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 | Monday, 7 October 2019 15:22 | 0 Comments
One of our favourite pastimes is spending time on client site being challenged to do stuff we've never even considered doing before. This post documents the result of one such challenge.

For the longest time, Revelation products have not allowed two volumes with the same name to be attached at the same time. To ensure that index transactions are applied to the correct bang file, the system enforces this artificial limit. Note though, that it IS an artificial limit, implemented at the table attaching level, not at the table opening level.

Many VARs working with multiple clients frequently just copy a base subdirectory of application tables to a new folder for a new client and in so doing, duplicate the name in the REVMEDIA map. This, naturally, means that if we have say an INVOICES table in that subdirectory, that we would not be able to consolidate across multiple INVOICES tables without first detaching the old table and attaching the new one.

This introduces significant overhead.

We needed to find a way of opening the same table multiple times for reporting purposes. Note that caveat - we didn't want to write to the file, we merely wanted to be able to read from it. As that is the case, we just needed a simple raw file handle - with no mention of SI.MFS or any other MFSs - just an RTP57 file handle.

For our first proof of concept, we manually created a file handle and were able to show that we could read from multiple tables having the same table name and the same volume name. After all, a pure file handle doesn't include the name of the table in question, it just contains information about the DOS file name of the underlying file. We did, however, notice that, whereas in the dim shrouded mists of antiquity the file handle used to contain the modulo of the file, it now contains a sequential number representing the order in which the file was opened. So our concern was that if we built the handle ourselves, the system might not know that we'd used a sequential number ourselves and that it might subsequently introduce unexpected consequences.

So, we cast around for a better way of creating a file handle, and unsurprisingly settled on making direct calls to RTP57A to do the heavy lifting for us.

The actual task is relatively simple; given the name of the table that we want a handle for, and the location, return a working file handle. So in RTP57 terms, open the media map, read the row corresponding to the table we want the handle for, grab the DOS file name and request a file handle.

With the process defined, it was not rocket science to create a function that returned a file handle given a location and a table name. The results are presented below.

0001  Function zz_getFileHandle( location, fileName )
0003     $Insert Logical
0005     fileHandle = ""
0007     Gosub validateLocation
0008     If OK Then
0009        Gosub getMediaHandle
0010        If Ok Then
0011           Gosub getFileHandle
0012        End
0013     End
0015  Return fileHandle
0017  validateLocation:
0019     OK = FALSE$
0020     OSOpen location To vLocation Then
0021        // can be opened so is Not a directory it's a file
0022        osclose vLocation
0023     End Else
0024        // was access denied because it didn't exist or because it's a subdir?
0026        If status() = 2 Then
0027           OK = TRUE$
0028           location := "\"
0029        End
0030     End
0031     If OK Else call Set_Status( 1, status(),"")
0033  Return
0035  getMediaHandle:
0037     status = TRUE$
0038     mediaName = "REVMEDIA"
0039     Call RTP57A("OP", mediaName, mediaHandle, "", location , "", status)
0040     If status then
0041        mediaHandle = "RTP57" : @vm : mediaHandle
0042     End else
0043        OK = FALSE$
0044     End
0045  return
0047  getFileHandle:
0049     If Index( fileName, "*", 1 ) else
0050        fileName := "*" : @DbID<1>
0051     End
0053     Read fileRow from mediaHandle, fileName then
0055        Call RTP57A("OP", fileRow<1>, record, "", location, errMsg, status)
0056        If Status then
0057           fileHandle = "RTP57" : @Vm : record
0058        End else
0059           // Set arbitrary error code
0060           Call Set_Status( 1, 400)
0061        End
0062     End else
0063        // Set arbitrary error code
0064        Call Set_Status( 1, 401)
0065     End
0067  Return
Pixel Footer R1 C1 Pixel