Wednesday, July 15, 2015

A partially documented trick in Priority

I wrote a few days ago about writing a program which takes date from an external program and imports it into Priority. There are actually two external programs: Imos creates a spreadsheet file and I wrote a program in Delphi which takes that file as input and creates several new text files which serve as input to Priority. The Imos developers added a new definition which I had to handle, both in the Delphi program and in Priority; whilst it was fairly difficult to handle this in the Delphi program, it was easy - on first sight - to handle it in Priority. The whole point of the Delphi program is to make things easy for Priority.

But as I looked deeper at the new definition, I saw a new problem: sometimes Delphi would output a file containing data regarding this new definition and sometimes Delphi would not output such a file, because it was not required. The program in Priority would look for this file, not find it and create an error, thus halting the program. Putting it simply, I needed a way in Priority of checking whether this external file exists.

I opened the documentation for Priority development and looked for such a function. Whilst it is documented how to copy a file, rename a file and delete a file, there was no function for checking whether it exists. There is, however, a function for getting a file's length; I cannot think of any use for this function, apart from the use which I found, of course. My way of thinking was that a file which does not exist does not have a length.

The documentation shows the following:

LINK STACK TO :$.STK;
ERRMSG 500 WHERE :RETVAL <= 0;
EXECUTE GETSIZE 'path/file name', :$.STK;
:FILESIZE = 0;
SELECT ELEMENT INTO :FILESIZE FROM DUMMY
WHERE ELEMENT > 0;
UNLINK STACK;

'Stack' is the name of a table in Priority which contains one field of type integer. The program 'Getsize' presumably adds a tuple to this table, containing the file size. The 'element > 0' bit is required as almost every table has a tuple with the primary key having the value 0; this simplifies matters when joining tables.

The sharp of eye can see that there is an error in the above code: it should be 'select element from stack'.

I thought that there would be a problem if the filesize is zero, because how would my program distinguish between the pre-existing tuple where element is zero and the inserted tuple where element is zero? So I elected to sum the values of the field 'element' and assume that the file exists where the sum is greater than zero. When I ran the program, I discovered that a non-existing file will cause -1 to be the value of the inserted tuple.

All of the above is moot for someone who is not interested in the gory details. Here is a snippet of code which will check in Priority whether a file exists:

SELECT SQL.TMPFILE INTO :TMP FROM DUMMY;
LINK STACK TO :TMP;
:FS = 0;
EXECUTE GETSIZE 'path/file name',, :TMP;
SELECT SUM (ELEMENT) INTO :FS FROM STACK;
UNLINK AND REMOVE STACK;
GOTO 1 WHERE :FS = -1; /* jump if no file */

The above would cost you money if you asked any Priority developing company; here you get it for free.

No comments: