22
Sun, Dec
3 New Articles

Practical RPG: QUSLOBJ, the Next Level of Object Information Retrieval

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

QUSLOBJ can be used as both an enhancement to and even a replacement for QUSROBJD, and this article shows you how.

As I detailed in a previous article, QUSROBJD allows you to see all the details of an object. However, it is specifically designed to return the data for a single object. For example, if you want to get the information for all the programs in a library (is this foreshadowing?), you'd need to have a way to list all those objects. QUSLOBJ is one way to do that, and it provides two basic approaches.

The Basics of the List APIs

The list APIs all work the same way. Please note that the term "list APIs" is a specific term not to be confused with the (newer) "open list APIs." Processing open list APIs is a separate topic that we will address another day. While the open list APIs were introduced in V3R6, the simpler list APIs have been around pretty much since the beginning. As such, they've received extensive coverage over the years, but today's article will, as I always try to do, enhance that coverage into the modern world of free-format RPG.

All list APIs work like this:

  1. Create a user space.
  2. Call the API to load entries into the user space.
  3. Process those entries.

Using a User Space

Creating and accessing a user space has been thoroughly documented, but let me give you the free-format prototypes that I've been using. I use two: one to create the user space (QUSCRTUS) and one to pull some of the data out of the user space (QUSRTVUS). I find it interesting that even with something this simple, there are two ways to do it. The approach in this article is to create a standard data structure and copy the data from the user space into the data structure. The alternative is to create a based data structure and change the basing pointer to walk through the user space directly. Either way is acceptable, and the based approach uses less memory and is probably even a bit faster since you don't have to copy the memory. At the same time, I find that basing pointers can sometimes obscure things a little bit, so I don't always use them. Perhaps I'll write a subsequent article in which I compare the two approaches.

In any case, here are the prototypes I use:

      // QUSCRTUS - Create User Space

     dcl-pr QUSCRTUS extpgm;

      iUserSpace char(20) Const;

      iSpaceAttr char(10) Const;

      iSpaceLen int(10) Const;

      iSpaceVal char(1) Const;

      iSpaceAuth char(10) Const;

      iSpaceText char(50) Const;

      iSpaceRepl char(10) Const;

      ErrorDs char(32767) Options( *VarSize );

     end-pr;

     // QUSRTVUS - Retrieve User Space Data

     dcl-pr QUSRTVUS extpgm;

      iUserSpace char(20) Const;

      iStart     int(10) Const;

      iLength   int(10) Const;

      oData     char(32767) Options( *VarSize );

     end-pr;

Listing 1: These are the two prototypes I use to create a user space and retrieve data from it.

The first API creates the user space, and the second retrieves some data from it. You may have noticed that when I create a prototype for an API, I leave the name of the prototype the same as the external program or procedure. This is my own convention; I like to always know the IBM name of the API. Other people provide meaningful names for the APIs, such as CreateUserSpace, which in turn might make the code a little more readable. It's up to you which approach works better, but in either case, I highly recommend that you use free-format RPG to define your prototypes; it's a great way to learn how to use the language.

Navigating the List

All of the list APIs use the same basic structure. IBM has provided a wonderful overview of this process complete with diagrams, details, and examples. You can start with the overview here. The concept is simple: the list APIs fill the specified user space with data that includes a header in the first positions. This header in turn has pointers (offsets, actually) to the rest of the data, including the actual list of entries. By using that generic header, you can future-proof your program so that even if the API changes in future releases, your code will still work.

IBM provides a great semi-graphical diagram of the user space layout used by all the list APIs:

Practical RPG: QUSLOBJ, the Next Level of Object Information Retrieval - Figure 1

Figure 1: This is IBM's simple graphical layout of the data; note the offsets to other parts of the data.

As you can see, the user space starts with a 64-byte user area, which in my experience doesn't seem to ever have much in it. Then comes the generic header area, which is very important, especially the offset to the list data. Here is the definition I use in my free-format RPG programs.

      dcl-ds QUSL_ListHeader template qualified;

      UserArea char(64);

      GenHdrSize int(10);

      Release char(4);

      Format char(8);

      API char(10);

      CreatedTS13 char(13);

      InfoStatus char(1);

      SpaceSize int(10);

      InputParmOffset int(10);

      InputParmSize int(10);

      HeaderOffset int(10);

      HeaderSize int(10);

      ListDataOffset int(10);

      ListDataSize int(10);

      ListEntryCount int(10);

      ListEntrySize int(10);

     end-ds;

Listing 2: This is the free-format RPG definition of the generic header in Figure 1.

This includes both the 64-byte user area and the generic header, so you can retrieve it from the start of the user space. Once retrieved, the generic header then provides an offset to the list data, as well as a count of entries and the size of each entry. Armed with just that information, you can now process the entire list!

QUSLOBJ, the List API Version of QUSROBJD

Let's take a look at how we can use QUSLOBJ in place of QUSROBJD. Please note that although QUSLOBJ retrieves the information for many objects at once, each entry is the same with the contents defined by the format parameter. Let's start by inspecting the API parameters.

      // QUSLOBJ - List objects

     dcl-pr QUSLOBJ extpgm;

      iUserSpace char(20) Const;

      iFormat   char(8) Const;

      iObjQName   char(20) Const;

      iType     char(10) Const;

     end-pr;

Listing 3: Here’s the prototype for the QUSLOBJ API.

If you refer to the previous article on QUSROBJD, you'll see that the parameters are similar. Instead of a data structure and length, you specify the user space that you created using QUSCRTUS. Next is the format of the data, which we'll go over in more detail in a moment. Then you have the qualified name and the type of the objects whose data you want to retrieve. The primary difference in this case is that you can specify generic values for these parameters, which is what allows you to retrieve a list of objects.

The second parameter, the format parameter, determines the layout of the entries. QUSLOBJ is similar to QUSROBJD in that each format builds on the others: OBJL0200 contains all the fields from OBJL0100 along with some additional fields, OBJL0300 starts with the same fields as OBJL0200, and so on. There are currently seven formats, each one with more information (and requiring correspondingly more time for each entry).

Here are the first couple of layouts:

      dcl-ds T_OBJL_0100 template qualified;

      Object char(10);

      Library char(10);

      ObjectType char(10);

     end-ds;

     dcl-ds T_OBJL_0200 template qualified;

      InfoStatus char(1);

      ExtObjAttrib char(10);

      Description char(50);

      UserAttr char(10);

      reserved char(7);

     end-ds;

Listing 4: These are the first two substructures in the QUSLOBJ API.

      dcl-ds T_OBJL0100 qualified template;

        A0100 likeds(T_OBJL_0100);

     end-ds;

     dcl-ds T_OBJL0200 qualified template;

        A0100 likeds(T_OBJL_0100);

        A0200 likeds(T_OBJL_0200);

     end-ds;

Listing 5: The actual list entries are defined by concatenating the substructures.

You select the amount of data you want through the format variable and then pull each entry into the matching structure.

Using the API

I recently wrote a tool that needed access to the last-used date of all the objects in a library. To do that, I had to use the sixth data structure. The code looked like this:

      // Header and detail list structures

     dcl-ds ListObj likeds(QUSL_ListHeader);

     dcl-ds dsOBJL likeds(T_OBJL0600);

     // Create user space

     CreateUserSpace(USObj);

     QUSLOBJ( USObj: 'OBJL0600': '*ALL     ' + iLib : '*ALL');

     // Retrieve list header from user space

     QUSRTVUS( USObj: 1: %size(ListObj): ListObj);

     // Do for number of objects in the userspace

     wPos = ListObj.ListDataOffset + 1;

      for count = 1 to ListObj.ListEntryCount;

      QUSRTVUS( USObj : wPos: %size(dsOBJL): dsOBJL);

      processEntry(dsOBJL);

      wPos += ListObj.ListEntrySize;

      endfor;

Listing 6: This is the code to process all the objects in a library.

This simple code processed the entire list of objects in the library. You might worry about one thing, though. The size of the entry gets larger and larger with each level, to the point where the OBJL0600 entry I am using is 576 entries long. Given the limitation for a user space of 16MB, that means that I'm limited to a little less than 28,000 objects. One way to get around that limitation is to use a combination of QUSLOBJ and QUSROBJD. Use the OBJL0100 format, which returns just the object name, library, and type, and then use that to call QUSROBJD to get the information. That then allows you to retrieve a half million objects, which ought to be enough for nearly any purpose.

The other option is to use the open list API QYGOLOBJ. The open list APIs allow you to process a list with an effectively unlimited number of objects. There are other benefits to these APIs as well, but we'll address those in a subsequent installment. If you want to jump ahead in your studies, though, you can start with Bruce Vining's excellent article on QYGOLOBJ. And until next time, enjoy your APIs!

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: