Home page Home page Home page Home page
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
By Sprezz | Thursday 31 January 2013 22:09 | 0 Comments
As is often the case, postings on the Rev forum pique our intellectual curiousity and sometimes when you're on the road in a hotel room there's nothing more fun than probing some obscure piece of arcane system information "because we can".

Welcome to the first blog of 2013 where we pretty much excel ourselves in the arcane department although we SUSPECT the results will have wider applicability - especially to those of you doing multiple attaches/detaches within your application.

A recent post on the Rev forum asked about the use of SET_ATTACH_IMAGE and USE_ATTACH_IMAGE. Those of you with long memories may recall that these routines were introduced in AREV to allow essentially "Quick Attaches". They swap out the contents of @FILES and @VOLUMES for a previously stored set of values. Those of you with even longer memories will remember that the precursors to these routines were created by Dunbar & Co - a prolific contributor to the Rev community - much missed.

With the advent of OI, attach images disappeared to be replaced by their more visible counterparts, DBTs. These Operating System files contain pretty much the same information as the attach images but externalise the process away from the SYSENV file where the attach images were stored.

To refresh your memory, the syntax of SET_ATTACH_IMAGE is as follows

Set_Attach_Image(imageName, optionalLabel, options, errors)


Use_Attach_Image(imageName, errors)

So the idea was that you'd attach the tables you wanted and use Set_Attach_Image to "snapshot" these tables. The snapshot would be stored as a row in SYSENV and the next time you wanted them you'd use Use_Attach_Image to make them available again. This would then replace the contents of @FILES and @VOLUMES with the stored versions.

Back at using these routines in OI.... whilst they still appear in OI, any attempt to utilise them, for example

Subroutine DeleteMe( Void )

    Call Set_attach_Image("ZZTEST", "ANDTHEN", "", Errors)


results in 

which isn't particularly useful - so back to square one...

OI still has the requirement (and patently the ability) to swap between file and volume definitions as shown when you log between applications - so we know it is still possible. The only question is "How?".

Well, an examination of the most basic logs provided by OI shows that it changes databases using the SWAP_DATABASE command so let's give that a go...

Using a client app as a starting point... we have the following tables available to us


But any attempt to do anything gets this error

The reason is simple. DBTs are "user aware" and the user I'm logged into my client app as does not exist in SYSPROG. The answer is simple. Log into SYSPROG and add my username as a database user for SYSPROG

Now repeat the SWAP_DATABASE and now when you try to open a record, the only tables available are those in the SYSPROG definition

Of course, there are always caveats when playing at the system level. In this case the act of swapping the database also changes @DBID, @APPID and @APPINFO (at the least). It also wipes any @User and @Recur variables basically setting your system back to a state as through you had just logged in. So treat this as though you'd logged to another application - including running any custom initialise routines for that application! 

Now the reason we single out @APPID is because this variable has an impact on the inheritance chain. To explain :-

Imagine you had an application FIELDGUARD that inherited from SFX which in turn inherited from SYSPROG. Imagine further that you wish to run a program called EOM. The program loader will firstly look for $EOM*FIELDGUARD and if it doesn't find it look for $EOM*SFX. If this isn't found it will finally look for $EOM*SYSPROG.

Now imagine that you swap database to ACCOUNTING which also inherits from SFX. If we try to run EOM we will now be looking for $EOM*ACCOUNTING and the load will likely fail - unless of course there IS an $EOM*ACCOUNTING in which case you'll be running something that you didn't expect.

The fix is, fortunately, simple. Ensure that all of the databases that you wish to switch to are inherited from your core application. This has the added benefit that they will automatically be created with the same users! So imagine you inherited application CUSTOM from FIELDGUARD. The program loader will now firstly look for $EOM*CUSTOM and if it doesn't find it then look for $EOM*FIELDGUARD as before.

Now it has to be said that we haven't used this technique in a production environment and we have only tested for our own satisfaction. One thing that did emerge in testing was that whilst this technique happily changed the tables available to us it created problems when saving forms. So to be extra careful we'd recommend that this technique only be used in a non development environment. We'd also strongly recommend that you test the technique thoroughly in your own system. That said it seems to work in a very easy and straightforward manner and would be especially useful in web based sessions where users attach different databases.
Pixel Footer R1 C1 Pixel