04
Mon, Nov
6 New Articles

TechTip: Accessing Database Files in C and C++

General
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Will there always be RPG and COBOL programmers? Learn how to access files natively using C and C++. Your application’s future may depend on it.

 

Google "Most popular programming languages in the world," peruse the top results, and you'll find that C and C++ programming languages are consistently among the top five languages listed. For COBOL and RPG, you have to dig a little deeper. On one site, programming language popularity based upon search engine hits is reported monthly. As of August 2014, COBOL had slipped to 29th, (down from 27th in July) and RPG was lumped in with an alphabetized list of those that ranked from 51 through 100, down from 47th in July. By the time you read this, who knows where they will be.

 

While languages such as Java and PHP are becoming popular on the IBM i platform, the majority of the mission-critical back-end applications are written in COBOL or RPG. But you don't hear of many recent computer science graduates who are excited about these languages. Are C and C++ a good alternative for IBM i programming? Because they're ILE languages, C and C++ play well with COBOL and RPG, allowing for applications to start making use of these technologies directly.

 

One of the first things you'll want to know with C/C++ programming on IBM i is how to access database files. There are several SQL-based approaches, but if you're not ready to fully embrace SQL, you can still use the C "native" I/O interfaces, which are more closely aligned with the native file access provided in RPG and COBOL.

 

The C/C++ native I/O interfaces are documented in the ILE C/C++ Runtime Library Functions document, which can be found here for OS 7.1. The native file I/O functions all begin with _R, such as _Ropen, _Rclose, _Rreadf, and so on. However, what's hardly mentioned in this documentation is how to best provide your C program with the structural layout of database records and keys for processing within the program. You can do this manually, declaring a C structure (struct), but this is tedious and at risk of becoming out of date if the file format is changed. Historically, this was done with the #pragma mapinc facility, but more recently, IBM also provides the GENCSRC command. The pragma causes a C/C++ header source file member to be dynamically generated in QTEMP/QACYXTRA during the compile when the pragma is encountered, which can then be immediately included into your program with the #include directive. The GENCSRC CL command is more flexible. It is run separately from the compile step and generates the C/C++ header source file in any location you choose, which can be either a traditional source physical file or an IFS stream file. The generated header file can then be included in your program normally using the #include directive. Other than this, both methods provide the same capabilities for mapping files, so the following descriptions are provided in terms of the GENCSRC command.

 

Let's consider a simple employee file, defined using the following DDS:

                                           UNIQUE
     A        R MYFORMAT                  TEXT('MY FILE OF FIELDS')
     A           EMPNBR       10S 0       TEXT('EMPLOYEE NUMBER')
     A           EMPNAME       50         TEXT('EMPLOYEE NAME')
     A           SEX           1         TEXT('SEX')
     A           SALARY       10P 2       TEXT('SALARY (DOLLARS)')
     A           POSITION       9B         TEXT('POSITION CODE')
     A           HIREDATE       Z         TEXT('HIRE DATE')
     A           COMMENTS   2000         COLHDG('EMPLOYEE COMMENTS')       -
                                           TEXT('EMPL COMMENTS') VARLEN       -
                                           ALWNULL
               K EMPNBR

 

After creating the file with CRTPF, we use the following GENCSRC command to generate a C/C++ header file:

 

GENCSRC
OBJ('/QSYS.LIB/MYLIB.LIB/MYFILE.FILE')
SRCFILE(MYSRCLIB/GENCSRC)
SLTFLD(*BOTH *KEY *NULLFLDS *LVLCHK)
ONEBYTE(*CHAR)                  

#ifdef __cplusplus
#include <bcd.h>
#else
#include <decimal.h>
#endif
/* ------------------------------------------------------- *
// PHYSICAL FILE : MYLIB/MYFILE
// FILE LAST CHANGE DATE : 2014/08/05
// RECORD FORMAT : MYFORMAT
// FORMAT LEVEL IDENTIFIER : 4FA3F5B1EE90B
* ------------------------------------------------------- */
typedef _Packed struct {
   char EMPNBR[10];                     /* EMPLOYEE NUMBER */
                                         /* ZONE SPECIFIED IN DDS */
                                         /* REPLACED BY CHARACTER TYPE */
   char EMPNAME[50];                     /* EMPLOYEE NAME */
   char SEX;

#ifndef __cplusplus
   decimal(10, 2) SALARY;
#else
   _DecimalT<10, 2> SALARY;             /* SALARY (DOLLARS) */
                                         /* BCD class SPECIFIED IN DDS */
#endif
   int POSITION;                         /* POSITION CODE */
   char HIREDATE[26];                   /* HIRE DATE */
                                         /* TIMESTAMP FIELD */
_Packed struct { short len;             /* LENGTH OF DATA */
           char data[2000];           /* FIELD DATA     */
   } COMMENTS;                           /* EMPL COMMENTS */
} MYLIB_MYFILE_MYFORMAT_both_t;


typedef _Packed struct {
   char EMPNBR[10];
                                         /* DDS - ASCENDING */
                                        /* SIGNED NUMERIC KEY FIELD */
} MYLIB_MYFILE_MYFORMAT_key_t;


typedef   struct {
   unsigned char EMPNBR;
   unsigned char EMPNAME;
   unsigned char SEX;
   unsigned char SALARY;
   unsigned char POSITION;
   unsigned char HIREDATE;
   unsigned char COMMENTS;
} MYLIB_MYFILE_MYFORMAT_nmap_t;


#ifndef __LVLCHK__
#define __LVLCHK__
typedef struct _LVLCHK_ {
   unsigned char format_name[10];
   unsigned char sequence_no[13];

#ifdef __cplusplus
   _LVLCHK_(const char * pformat, const char * pseq) {
       short int i;
       for (i=0; i < 10; format_name[i]=pformat[i++]);
       for (i=0; i < 13; sequence_no[i]=pseq[i++]);};
#endif
} _LVLCHK_T[];
#endif



#ifdef __cplusplus
_LVLCHK_T MYLIB_MYFILE__QSYS_LIB_ MYSRCLIB__LIB_GENCSRC_FILE_MYFILE_MBR_lvlchk = {
_LVLCHK_("MYFORMAT ","4FA3F5B1EE90B"),
_LVLCHK_("","")
};
#else
_LVLCHK_T MYLIB_MYFILE__QSYS_LIB_MYSRCLIB__LIB_GENCSRC_FILE_MYFILE_MBR_lvlchk = {
"MYFORMAT ","4FA3F5B1EE90B",
"",""
};


#endif

 

Lines 1-5 include declarations needed for packed-decimal field declarations and are designed to work correctly whether this header file is used by the C compiler or the C++ compiler.

 

Lines 6-11 provide a comment block to describe the header file.

 

Lines 12-31 define the record format layout structure

 

Lines 13-15 define a zoned numeric field, which is mapped into a character array type.

 

Line 16 defines a simple character field.

 

Line 17 defines a character field whose length is one. Because the ONEBYTE(*CHAR) option was specified on the GENCSRC command, this character field is declared as a simple scalar character, rather than a character array of length one. Also note that this field does not have a descriptive comment. This is because the TEXT attribute in the DDS was simply the field name. GENCSRC is smart enough to know that a comment repeating the field name would look silly.

 

Lines 19-24 define a packed numeric field, again using syntax that allows use in either C or C++ programs.

 

Line 25 is a binary data type.

 

Line 26 is a timestamp data type.

 

Lines 28-30 define a variable-length character field by declaring an inner structure with a length element and the data for the value.

 

Lines 34-38 define a structure that maps out the key fields for the file. This allows you to construct a key value for use in key-based file reading.

 

Lines 41-49 define a structure containing appropriately named character values to provide the layout of the null map that is passed and returned by the native I/O read and write family of functions. This is present because the *NULLFLDS option was specified on the SLTFLD parameter of GENCSRC.

 

Lines 52-64 define some types and values that can be referenced when the file is opened at run time to cause a run-time check to occur that verifies the file that is actually opened has the same file format as was used to generate the include. This may very well catch a case where a program might otherwise corrupt a file by writing data using the wrong layout.

 

In a future TechTip, I'll cover how to use the C runtime library native I/O functions to open, read, update, and write to a database file using the declarations provided by the GENCSRC generated header file.

Downloadable Code

You can download the code files for this article here and here.

 

John Vriezen

John Vriezen is an Advisory Architect at Vision Solutions, Inc. for the MIMIX family of products. He has been working with IBM i systems and their predecessors for most of the last 30 years, including nine years at IBM Rochester, where he worked on database and journal enhancements. He spends free time volunteering in programs that introduce kids to science and technology through FIRST Robotics and CoderDojo.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: