Lightly Seared On The Reality Grill

Random expat geekery from The Low Countries

Browsing Posts in IBM i

RPG, the programming language that remains very popular on the IBM i platform is often criticised for being a bit… venerable. It is certainly true that the language goes all the way back to 1959 and is one of the very few languages developed for punched card processing that is still in common use today.

However, in its current incarnation the language is a very different beast to its precursors. ILE RPG is every bit as modern, functional and flexible as its more recent rivals and, when it comes to encapsulating business rules, ILE RPG on an IBM i remains an unbeatable combination.

This is only true, however, if programmers take advantage of the features provided and, in far too many cases, they don’t.

When people talk about modernising RPG or about modernising i applications it is worth keeping in mind that the perceived datedness does not stem from either the languages or the tools. The real problem lies in the army of semi-competent, under-resourced developers scattered across isolated offices and churning out code that would have been embarrassing twenty years ago.

The backward compatibility that the IBM i retains is a hugely important part of the box’s appeal. Knowing that you can simply apply any upgrade that comes along without any downtime or breakages is a significant part of the i’s stability and provides a great deal of peace of mind to those administering it. The downside of this, however, is that it also makes it very easy for developers to settle into their comfort zones and quietly watch the rest of the industry pass them by.

These are the people that IBM needs to reach out to. IBM needs to convince these people that it is in their interest to understand how to make the most of the available languages and tools. I suspect that IBM will also need to convince IT managers that the productivity gains to be made from moving forward far outweigh the cost of training, but this is what marketing folks are for.

The IBM i is a secure, stable, reliable and powerful platform and RPG is a powerful, functional and flexible language that enables very small teams to develop and maintain very large systems. I am increasingly of the view that what undermines the platform more than anything else is the large number of developers who are unwilling to keep up with the technology.

This rant was provoked by the goto statement I found in a three year old program.

flattr this!

Logo IBM unleashed the AS/400.

Over the last two decades, the platform has seen some incredible developments and is still streets ahead of the rest of the industry.

flattr this!

Another week, another utility. I’m supporting an application which, among other things, includes the concept of Conflicting Programs. This works by attaching an Activity Level to each program – essentially a count of how many instances of that program are active. When someone launches a program, its Activity Level is incremented and when they exit the program its activity level is decremented.

Each program within the application also has a list of Conflicting Programs attached to it. When you try to launch a program, the activity level of each of its conflicting programs is checked and if any of these activity levels is not zero, the program will not start. Instead, you will see a message telling you which Conflicting Program is active.

It’s a simple and (usually) effective method of ensuring that end users can’t cause data discrepancies by executing tasks when they shouldn’t – you can’t start entering transactions when a month end close is in progress, for example. The problem is that the application can only tell you that a program is active – not who is using it. When someone is preventing you from starting the month close and going home by leaving a transaction entry screen open, identifying who is holding things up is something you want to be able to do as quickly as possible. This is where the Display Program Locks utility comes in.

What this utility does is scans the active jobs on the system and, for each one found, checks its call stack. If the offending program is found, the job is added to a list which is displayed on the screen. The screen handling is pretty basic, but sufficient for the environment in which I am using this utility.

Three source files are attached, for the Display File (DSPPGMLCKD.DSPF), the RPG (DSPPGMLCKR.RPGLE) and the Command Source (DSPPGMLCK.CMD). Feel free to take a look and, if you decide to download and compile it, you will be able to use the DSPPGMLCK command to find exactly who is using any given program.

As ever, comments, observations and improvements are always welcome.

flattr this!

The IBM i includes several features which are – or can be – incredibly handy but which are not supported by industry standard tools. One example of this is physical files with multiple members. On the i, they provide a very effective mechanism for managing large amounts of similar data (transactions, for example). However, SQL doesn’t support multiple members and, therefore, can usually only access the first member in the table (which is usually the member with the same name as the file/table). This causes problems when people are trying to access i data from external applications and, as a consequence, far too many people end up not taking advantage of multiple members.

It’s a shame because there is a workaround and it’s painfully simple – all you need to do is create an alias.

In the, rather trivial, example below I want to delete transactions out of the INVALID member in file TRANSACTIONS based on various selection criteria provided by the business. So I create an alias, REJECTED. Now I can delete transactions out of the INVALID member by running the delete command over the alias REJECTED.

Set schema LIBRARY;

Create alias REJECTED for TRANSACTIONS(INVALID);

delete from REJECTED
where... ;

drop alias REJECTED;

Granted, this is a pretty basic example, but the general approach – Create Alias; Do Stuff; Drop Alias – will work in any case where you are accessing IBM i data from a non-i environment (such as PHP or Java JDBC).

One final note. It is, of course, possible to simply create a permanent alias and avoid the overhead of repeatedly creating and dropping the temporary one. You do have to be a little bit careful doing this, though, because if you rename a member in the file, the alias will no longer point to it and you would have to remember to either create a new alias or create a new member with the old member name.

My memory is terrible. This is why I prefer to create a temporary alias when I need it and then drop it when I’m done.

flattr this!

Why i?

No comments

Here’s Why. It’s a YouTube playlist in which Steve Will, IBM Chief Architect for IBM i describes the not inconsiderable value of the IBM i.

Via The Four Hundred.

flattr this!

I thought, until recently, that I was about to start missing out on my regular fix of System iNews magazine but a little poking around on their website reveals that most of the magazine is archived online. Which is why, at the end of May, I can start looking forward to IBM i 7.1, the next release of the IBM i.

There has been a lot of talk in the industry press over the past month about Rational Open Access which will enable RPG applications to easily reach new devices and new users with new interfaces, and this is certainly something that has been needed for a long time.

What really caught my attention, however, is the fact that DB2 for i now a whole lot more XML friendly. With this release, it will be possible to store data in its native XML format, easily split into relational database columns (the bit I really like the sound of) or created from existing database objects. On its own, this will really open up a whole slew of possibilities related to application integration and interface design, but there’s more.

The OmniFind Text Search Server now supports search in XML documents within DB2. There is a more detailed discussion of what this means, and how to get started, over here, but my immediate thought is: Oh my, this will make things even faster!

flattr this!

When you compile a SQLRPGLE program, the default Commitment Control option is *CHG. This indicates that tables you update will be locked until the changes are committed or rolled back. This is all well and good, but you do need to have journaling switched on for the tables for it to work.

The compiler doesn’t check this so, by default, a program to update an unjournaled table will compile and can be executed. It just won’t make any updates and you will need to dig through the job log to track this down.

The Right Way

What you should do is journal everything and take full advantage of commitment control.

In order to do this, you would need to create a journal receiver and a journal…

CRTJRNRCV JRNRCV(MYLIB/MYRECV) TEXT('My Journal Receiver')
CRTJRN JRN(MYLIB/MYJRN) JRNRCV(MYLIB/MYRECV) TEXT('My Journal')

And start journaling your files…

STRJRNPF FILE(FILEA, FILEB, FILEC, …) JRN(MYLIB/MYJRN) IMAGES(*BOTH) OMTJRNE(*OPNCLO)

When you want to stop journaling a file, you can do this:

ENDJRNPF FILE(*ALL | FILEA, FILEB, FILEC, …) JRN(MYJRN)

Bear in mind that the journal receivers can get pretty big pretty quickly so you will need to talk to your operations folks about disconnecting and purging these on a regular basis.

The Other Way

Of course, you may well be working with a third party application which is not taking advantage of commitment control and, for which, you can’t justify implementing a whole set of journals. This leaves you needing to turn off commitment control for your SQLRPGLE program. There are two ways of doing this:

What you can do, every time you come to compile this program, is ensure that you compile it with COMMIT(*NONE).

This approach works but it does rely on you, and every developer that follows you, remembering to change the COMMIT parameter. To me, this is a guarantee that sooner or later someone will forget and a trivial change will suddenly break a previously reliable program.

It is much better to explicitly turn off commitment control in the program itself, ideally in the header spec. Unfortunately, I’m on release 6.1 and this doesn’t include a compiler option for commitment control in the h-spec, so I am left with the following workaround.

Put this line of code at the start of you program:

exec sql Set Option Commit = *NONE;

Commitment control is now switched off and your SQLRPGLE program will happily update your horrible, unjournaled, third-party table.

flattr this!

So the application I mentioned on Monday was finally approved late yesterday and, today, it’s written and working. There were, inevitably enough, some changes to the spec. The application that has been approved can be executed once an outage has been started and will send a break message to any session still signed on that shouldn’t be, and generate a simple report so the operations folks can visit the offending users with a baseball bat.

This, in itself, wouldn’t be enough for me to bother reposting the code but since I also took the opportunity to develop the application in RPG (or Free Format ILE RPG if you want to be search engine friendly). Doing this gave me a great deal more flexibility over the earlier CL code and also allowed me to prototype the API names into something a lot more readable. You’ll see what I mean if you take a look at the code.

Again, I have filed off the serial numbers and you can take a look at the code here: Lockout.RPGLE

Feel free to copy it, compile it and modify it if it is of any use to you. And if you have any comments or observations, I’d love to hear them.

I do mean it about the baseball bat, though.

flattr this!

There are times (month end, for example) when you need to know which users of an application are signed on so you can respond accordingly. Reliably enough, the iSeries provides all the APIs you need to achieve this.

There are two APIs you need to know about:
QUSLJOB – List Job, generates a list of some or all jobs on the system. This information can be pushed into a user space.
QUSRTVUS – Retrieve User Space, pulls the information out of the user space.

The CL program, below the fold, shows these APIs in action. It does work, although it won’t make any changes – I’m still waiting for final approval to go ahead and write this – and I have filed off a few serial numbers to avoid copyright problems. Feel free to copy it, compile it and modify it according to your own needs. If you have any comments, feedback is always appreciated.

What the program does is read through a table of application users (USERTABLE) and, for each USERID, lists all active jobs for that user in a user space. A nested loop (at Label STEP01A) loops through each job found to retrieve the essential data.

What you do with this retrieved job information is up to you, but I’m thinking in terms of disabling the profile and ending the job.

Update: I’ve just noticed that copying and pasting the code into WordPress causes more than a few oddities in the rendering. So I’ve moved the code into a text file which you can download here: RtvActJob.CLLE

flattr this!