In the first installment of this two-part article, you were introduced to the Save Object List (QSRSAVO) API. We discussed how the API works and how, unlike most APIs, the information you would normally pass to an API in parameters is instead written to a user space, the name of which you pass to the API in a parameter. We also discussed the format of the aforementioned user space and the key values you use to communicate specific information to the QSRSAVO API. Now, let's look at an example of how to use this API.
Example program: How to use the QSRSAVO API
The program, SAVUSROB.RPG, shows you how you can use this API to facilitate allowing users to specify which objects they want saved each night. The program is written in ILE RPG.
The DDS for physical file SAVINFO used in the utility (keyed by library, object name, and object type) is shown here. Users maintain the information in file SAVINFO, and the program uses the information to perform the saves. Note: The program shown does only the saving part; writing a program to allow users to maintain the data in the SAVINFO file is left as an exercise for the reader.
The program groups the objects in the SAVINFO file by library so that all objects in the same library can be saved using one save operation. This speeds tape processing and saves tape space.
The QSRSAVO keys that are used in the program and their descriptions are listed below in the order used. Notice that the keys do not have to be specified in order.
- Key = 2. Library name. An array of library names. Each array element is made up of a 10-byte library name. The array should be preceded by a 4-byte binary field containing the number of elements (i.e., libraries) in the array.
- Key = 3. Device specification. An array of device names. Each array element is made up of a 10-byte device name. The array should be preceded by a 4-byte binary field containing the number of elements (i.e., devices) in the array. (Note: Only tape devices allow multiple devices, so for save files and diskette devices, this array may only contain one element).
- Key = 10. End of tape option. A 1-character field used to specify the tape action to take when the save operation is complete. '0' to rewind, '1' to leave, and '2' to unload.
- Key = 1. Object information. An array of object names and type. Each array element is made up of a 10-byte object name (generic names are supported) followed by a 10-byte object type (any object type that is valid for the Object type parameter on the SAVOBJ OS/400-i5/OS command). The array should be preceded by a 4-byte binary field containing the number of elements (i.e., objects) in the array.
The default for the rest of the keys are used. The defaults for the QSRSAVO API are the same as those for the SAVOBJ command.
The only complicated portion of the program is the data structure UsrSpc, which accounts for almost half the program code. The data structure is made up of a 4-byte binary field (#Keys) followed by four "variable"-length records (#Keys should contain the number of variable-length records that follow, in this case 4).
Each of the variable-length records is made up of an Lx field (the overall length of the record), a Kx field (the key for the record), an LPx field (the length of the parameter data), and one or more fields used for the key-dependent parameter data.
Since we can predetermine the length of three of the four variable-length records (library, tape device and end-of-tape option), we put these three first in the data-structure and initialize them using the Inz keyword. (The library and tape device records do contain arrays, but since we will be using only one element for each, we can code them as regular character fields.) The last variable-length record is for the object information, for which we cannot predetermine the length. The actual number of elements used in the object array depends on the information read from the SAVINFO file.
The bulk of the executable code is two do-loops, one nested inside the other. The outer do-loop iterates through each unique library in the SAVINFO file. The inner loop reads through all the SAVINFO records that have the same library, building the Object information array (key value 1). At the end of each iteration of the outer loop, the QSRSAVO API is called to save the objects in that library.
About the author: Ron Turull is editor of Inside Version 5. He has more than 20 years' experience programming for and managing AS/400-iSeries systems.