Sunday 12 November 2023

Version control for screen triggers

Two and a half years ago, I developed a system for version control of procedures. This system has proved invaluable at times when a change to a procedure did not not give the desired output; I could revert the code to the previous version thus restoring the status quo. At one time I extended the system to work with interface code - this was very simple. For some time now, I have been wanting to extend the system to provide version control for screen triggers, but this is not so simple.

In the same way that a procedure can have several SQLI stages, a screen/form can have several triggers. But as opposed to procedures where every SQLI stage has a different value in the PROGRAMS table, triggers are managed in a similar albeit different manner, by means of the FORMTRIG table that has both a pointer to the parent form (e.g. ORDERS) and a pointer to the given trigger. 

Originally I thought that I would have to develop a completely new system for form triggers, albeit influenced by the procedures code. But when I devoted some serious thought to the topic, I realised that all I need do was add a new field to the table that manages the versions; this field would be a pointer to the given trigger that along with the pointer to the parent form would completely identify the trigger. Obviously the code that saves a version would have to be written, but this would be very similar to the code that saves a version of a procedure or interface.

Once I had this insight, there wasn't very much that I could do to advance the subject, as the new field would have to be part of the primary key (U) of the manager table that would mean having to add the field to the appropriate form, which is something that I don't do during regular work hours. Fortunately Friday afternoon is a time when no one ever seems to be connected to Priority, so for me it's an ideal time to work on form code. 

First I added the new field, then I updated all the existing tuples in the table to have the value -10 in this field; every tuple has to have a value, but it is meaningless when the tuple is for a procedure. Then I had to add this field (and its value) to the existing screen, then prepared all the forms. Then I updated the code for saving procedure versions to include this new field and saved this new version: the form displayed it correctly. Why -10? 0 would appear to be a better value, but I am wary of saving 0 in a key field. There are five predefined triggers (four search triggers and CHOOSE-FIELD) that have values -5 to -1; as I didn't want a collision with these values, I chose a different number. It occurred to me later that a tuple for a procedure couldn't possibly have the same EXEC value as a tuple for a trigger, so I could have used -1 without problem.

Then I had to start work with the trigger code. First I defined a new form for displaying versions that is almost exactly the same as the existing form albeit with different values for the EXEC and TRIG fields. This form is a son of the FTRIG form. Once I had the form defined, I could define the interface for saving a new version, and once I had the interface I could define the required procedure. This is almost a chicken and egg problem, but there is a way through the convoluted path.

Debugging the procedure was a different story to the simple steps that I had taken so far. The first - and relatively minor - problem was that I had neglected to define correctly the TRIG field in the new form. Once this was fixed, I could save new versions of each trigger, but the text - the point of the entire exercise - was not being saved. In true debugging fashion, I took the dog for a walk and considered my options. It turned out that the procedure was saving the code text in GENERALLOAD.TEXT, but the interface was expecting the text in TEXT2. A hard to find but easy to correct bug. It then occurred to me that I could improve the system by saving the date of the trigger as the version date; this saves me some work when saving existing triggers, although of course it won't make any difference when saving a new version of a trigger.

An ounce of prevention is worth a pound of cure.

No comments:

Post a Comment