| The API Corner: Still Using Compile-Time Arrays? |
|
|
|
| Programming - APIs | |||||
| Written by Bruce Vining | |||||
| Wednesday, 15 December 2010 00:00 | |||||
|
There are better ways for storing textual information.
As a contract programmer, I have the opportunity to review quite a bit of i-based code that is to be rewritten as part of various modernization efforts. One programming style that I encounter fairly often is the use of compile-time arrays to store textual information for use on displays and reports. These companies' databases may have, for instance, an order-status field (OrdSts) with values such as P, O, C, H, I, R, and S to represent order pending, order, order canceled, order held by accounting, order held due to inventory, order released for processing, and order shipped, respectively. When returning order status information to a user, the application programs may then utilize a compile-time array, as shown below, to provide a textual description of the order status through a display or printer file character variable (Status).
dTxt s 30 dim(8) ctdata
dOrdSts s 1 dStatus s 25
/free
// Read a record containing order status (OrdSts) select; // Provide text description of order status when OrdSts = 'P'; Status = Txt(1); when OrdSts = 'O'; Status = Txt(2); when OrdSts = 'C'; Status = Txt(3); when OrdSts = 'H'; Status = Txt(4); when OrdSts = 'I'; Status = Txt(8); when OrdSts = 'R'; Status = Txt(5); when OrdSts = 'S'; Status = Txt(6); other; Status = Txt(7); endsl;
// Do processing, including output of // order status in textual form
*inlr = *on; return;
/end-free **CTDATA TXT Order pending Order scheduled Order canceled Order held - Accounting Order being processed Order shipped Order status is unknown Order held - Inventory
While this approach to providing human-readable text descriptions of the order status is certainly time-proven (I've seen it in various forms of RPG for well over 30 years), it also irritates me (admittedly to a degree perhaps out of proportion, but an irritation all the same).
The major concern I have with this approach is that when a change is needed to the OrdSts textual description, then development must…
There are many ways to minimize this development effort, including approaches such as these:
Approaches 3 and 4 succeed in externalizing the descriptive text from the application program and eliminate the need to locate application source (whether it be an RPG application program or a DDS display/printer file), edit the source, and recompile the source—which in many cases also results in less need for a full regression test in order to change the text associated with OrdSts.
My preference is to use the fourth approach—message descriptions and message files. This article won't go into the implementation details behind this preference (though future articles will), but one example of why I prefer message descriptions over database fields is due to the ability for the i message-handler support to imbed replacement data within the returned text—without the application program having to explicitly control the concatenation of data and text, which would be more the case using database support.
To move the descriptive text to message descriptions, we can create a message file, named TextMsgs, and add the appropriate message descriptions as shown below.
CRTMSGF MSGF(TEXTMSGS) ADDMSGD MSGID(DSP0100) MSGF(TEXTMSGS) MSG('Order pending') ADDMSGD MSGID(DSP0101) MSGF(TEXTMSGS) MSG('Order scheduled') ADDMSGD MSGID(DSP0102) MSGF(TEXTMSGS) MSG('Order canceled') ADDMSGD MSGID(DSP0103) MSGF(TEXTMSGS) MSG('Order held - Accounting') ADDMSGD MSGID(DSP0104) MSGF(TEXTMSGS) MSG('Order held - Inventory') ADDMSGD MSGID(DSP0105) MSGF(TEXTMSGS) MSG('Order being processed') ADDMSGD MSGID(DSP0106) MSGF(TEXTMSGS) MSG('Order shipped') ADDMSGD MSGID(DSP0107) MSGF(TEXTMSGS) MSG('Order status is unknown')
Having added the message description to TEXTMSGS, we now need to access these descriptions from the application program. As you might expect, there's an API for that. The API is Retrieve Message (QMHRTVM) and is documented here. The QMHRTVM API has many capabilities we will not be taking advantage of today. The essential part that we will be using initially is that, given a message ID (and message file), the API can return the first-level text of the message description. In the next article, we'll look at one possible implementation of a *SRVPGM export RtvMsgTxt (Retrieve Message Text) which utilizes this API. In the meantime, feel free to review the API documentation and see if you can write your own implementation of RtvMsgTxt.
The RtvMsgTxt procedure we'll be developing returns first-level message text and will be utilized as shown in the following program.
h bnddir('MSGSPTBD')
dRtvMsgTxt pr dMsgRcv 65535a options(*varsize) dLenMsgRcv 10i 0 const dMsgID 7a const
dOrdSts s 1 dStatus s 25
/free
// Read a record containing order status (OrdSts) select; // Provide text description of order status when OrdSts = 'P'; RtvMsgTxt(Status :%size(Status) :'DSP0100'); when OrdSts = 'O'; RtvMsgTxt(Status :%size(Status) :'DSP0101'); when OrdSts = 'C'; RtvMsgTxt(Status :%size(Status) :'DSP0102'); when OrdSts = 'H'; RtvMsgTxt(Status :%size(Status) :'DSP0103'); when OrdSts = 'I'; RtvMsgTxt(Status :%size(Status) :'DSP0104'); when OrdSts = 'R'; RtvMsgTxt(Status :%size(Status) :'DSP0105'); when OrdSts = 'S'; RtvMsgTxt(Status :%size(Status) :'DSP0106'); other; RtvMsgTxt(Status :%size(Status) :'DSP0107'); endsl;
// Do processing, including output of // order status in textual form
*inlr = *on; return;
/end-free
These are the changes made to the original sample program:
With these changes to how the order status descriptive text is retrieved, we can now change the text with the Change Message Description (CHGMSGD) command and not have to locate, change, and recompile the source of any application program, display file, or printer file that is utilizing the text. We could, going admittedly to an extreme for some companies, even change the English description to Spanish and not have to recompile the application program (though in the case of a language change such as English to Spanish we would most likely want to also translate any *DSPF and *PRTF column headings, prompts, etc.—not related to Order Status though—to also be in Spanish).
Those of you familiar with the DDS keyword MSGID might be wondering why I'm using a RtvMsgTxt approach rather than simply using the variable support of the MSGID keyword to provide the message text. If I knew with certainty that the textual form of OrdSts would be needed only for display files, I might very well take that approach. I don't know with certainty though what the future might hold—and if that future includes printer files, I would then run into the problem that printer files do not support the MSGID DDS function, leaving me still with the need to provide order status descriptive text under application program control. Because I prefer one solution that can be applied across all scenarios, I would go with a RtvMsgTxt-based solution.
The benefit of storing the descriptive text external to the application program is not one that, in my opinion, warrants going out and changing existing applications solely for the purpose of eliminating compile-time arrays (or conditioned text in *DSPFs and *PRTFs). It is, however, a solution that can be easily implemented as you are updating existing applications and/or writing new application programs. And the ease of implementation is one where the additional cost of making such an enhancement is minimal.
Next month, we'll look at some of the specifics in using the QMHRTVM API. In the meantime, if you have any API questions send them to me at bvining@brucevining.com. I'll see what I can do about answering your burning questions in future columns.
as/400, os/400, iseries, system i, i5/os, ibm i, power systems, 6.1, 7.1, V7,
| |||||
|
|||||
| Last Updated on Wednesday, 15 December 2010 00:00 |








You must be logged in to view or make comments on this article