tips:revmedia:mfs3

MFS PROGRAMMING & USAGE

Published ByDateVersionKnowledge LevelKeywords
Revelation Technologies14 NOV 19892.XEXPERT%RECORDS%, @-variables, @LIST.ACTIVE, @NEXT.FS, sample, program, Next, Aborting, Disabling, Accessing, file+, also, Calling,, Direct, call, different, files, Accounts,, Non-SYSPROG, Arguments, modifying+, names, Assembly, language, Attaching, after, changing, file, handle, installation, using, volume, name, Audit, trail, calling, system, argument, during, FLUSH, INSTALL, BFS,, definition, BFS-bound, Branching+, Btree, index, Buffers, caching, Bypassing, with, direct, calls, Caching, Calling, directly, from, R/BASIC, next, list, CASE, statement, Cataloging, Changing, CLEARSELECT, CODE, Compatibility, Compiling, Compression, CREATE.FILE, CREATE.MEDIA, Current, accessing, Cursors, Data, passing, De-installing, object, code, Debugger, Debugging,during, development, Decryption, Encryption, DELETE.FILE, Detaching, DICT.MFS, Dictionary, problems, with+, current, Direction,READNEXT, function+, Dispatching+, Environmental, Bond, Example

Dynamically Installing or De-installing an MFS

It is possible to install or de-install an MFS dynamically by updating a file handle in an R/BASIC program. This technique is useful if programmers wish to add transaction processing, security, or other MFS functionality to a file based on factors that can only be determined at runtime. If used in reverse – if a program removes an MFS from a file handle – the technique can be used to temporarily bypass a specific MFS for performance or other reasons.

A dynamic, file-handle-based MFS installation differs in three major ways from a permanent MFS installation that updates the media map. The first difference is that the MFS is installed (or de-installed) only for those routines that use the dynamically- updated file handle. If a user (on a network, for instance) accesses the file using a different routine, changes to the MFS list for a file will not be reflected for that user.

A second difference is that installation of the MFS is temporary. Once the program or programs that use the updated file handle have stopped, the MFS is no longer installed or de-installed.

Finally, certain calls will not be available to the MFS installed dynamically. For example, the MFS will not be able to trap the OPEN.FILE call, since this must be executed before the file handle is available to be updated with the MFS name.

The following sample code illustrates a possible technique for installing an MFS dynamically:

MFS.NAME = "SAMPLE.MFS"  
OPEN 'FILE' TO FILE.HANDLE THEN  
   FILE.HANDLE = MFS.NAME : @SVM : FILE.HANDLE  
END  
SELECT FILE.HANDLE  
(etc.)  

Note: Because this technique assumes a particular format for the file handle, it may not work for all filing structures. In addition, the structure of file handles may change in future releases of Advanced Revelation.

Installing an MFS on a Volume

A final technique for installing an MFS allows a developer to install an MFS across the board for all files on a volume. This is a typical requirement for a security MFS, in which all files associated with a specific volume must be protected together.

To install an MFS for all files on a volume requires that the volume be identified by a logical volume pointer in the VOC file. The structure of a VOC volume pointer is:

FieldDescription
KeyVolume name
<1>VOLUME (literal word)
<2>BFS name
<3>Qualifier (example: DOS path name)

the volume pointer. The MFS name is separated from the BFS name by a value mark.

For example, the second field of a volume pointer using the MFS named SECURITY.MFS might look like this:

SECURITY.MFS2RTP57  

When the volume is attached using the logical volume name, the MFS will be added to all files.

The volume pointer installation does not offer the developer a choice in the position of the MFS. The attach process will always place the volume MFS first in the MFS list for a given file. If other MFSs are associated with a file – for example, if files are indexed using SI.MFS – these MFS names will follow the volume MFS. A volume- based MFS installation may thus not be suitable for installing a position-sensitive MFS.

A volume-based MFS is unique in offering the developer access to BFS functions that address media rather than just records. For example, a volume-based MFS will be called for such functions as CREATE.FILE, OPEN.MEDIA, and other functions that access or update a media map.

Note: Due to restrictions in the system, indexing cannot be added to a file that is being accessed through a volume MFS. However, files that are already indexed can be successfully accessed via a volume-based MFS.

MFS PROGRAMMING NOTES

Because an MFS effectively becomes a system program in Advanced Revelation, programmers need information about the interaction between the MFS and the rest of the Advanced Revelation environment. The MFS programmer must understand not only the specific protocol of calls to the filing system, but what the context is for the calls, and how Advanced Revelation uses filing system information.

This chapter provides details about the relationship between R/BASIC, MFSs, and underlying filing systems. In some cases, explanations are provided that describe how an MFS programmer can accomplish certain commonly required functions not otherwise available through the basic MFS protocol.

Accessing the MFS

Once an MFS has been properly installed and the file attached, access to an MFS is automatic. Anytime an R/BASIC READ, WRITE, DELETE or other record-oriented statement is made, or anytime a TCL command such as ATTACH or CLEAR-FILE is made, R/BASIC will automatically pass the appropriate arguments to the MFSs and the BFS for the file being accessed.

Direct Calls to the MFS

Certain MFS codes do not have corresponding R/BASIC or TCL commands to call them. Examples include RECORD.COUNT, INSTALL, and GROUP.NUMBER.

If a program requires access to these codes, it must execute a direct call to the first MFS for the file to be accessed. This is done as an external subroutine call to the first MFS for the file, passing the seven filing system arguments.

Under most circumstances, the program should not do a direct call to the BFS itself. There are two reasons for this. First, a direct call assumes that the programmer knows in advance what BFS will be used to access the file. This makes the program unusable for files accessed through any other BFS.

Second, a direct call to the BFS bypasses calls to any MFS that might be installed for the file. While this might be desirable under certain limited conditions, in general it is a much better practice to access a file via the full sequence of MFSs. This helps preserve the file integrity represented by those MFSs. For example, direct access to the file via the BFS will defeat indexing, security, or audit trail MFSs that may be essential to an application.

The MFS list for a file is available in two places. The first is in the FILES file. The MFS list for a file is stored as the fourth field in the FILES entry for a file. The list is kept as a list delimited with @VM. In order to make use of the list, the value marks must be converted to @SVMs.

The handle returned by the R/BASIC OPEN statement also contains the MFS list for a file. In this situation, the MFS list is the first value (delimited with @VM) in the handle, and the true file handle is the second value. The MFS list returned as part of the R/BASIC OPEN file handle is already @SVM-delimited, so no conversion is required.

The following sample program illustrates how to execute a direct call to the first MFS for a file. The example program calls the filing system with a code of 28 (RECORD.COUNT) to return the total number of records in the file.

DECLARE SUBROUTINE MSG  
EQU RECORD.COUNT$ TO 28  
RESP = ""  
CALL MSG("Enter file name","R",RESP,"")  
OPEN RESP TO FILE THEN  
   FS.LIST = FILE<1,1>  
   HANDLE  = FILE<1,2>  
   NEXT.FS = FS.LIST<1,1,1>  
   NAME = "" ; FMC = 0 ; RECORD = "" ; STATUS = 0  
   CALL @NEXT.FS(RECORD.COUNT$,FS.LIST,HANDLE,‹  
      NAME,FMC,RECORD,STATUS)  
   IF STATUS THEN  
      MSG(FMC:" record(s) counted.","","","")  
   END ELSE  
      MSG("Can't count records in ":RESP,"","","")  
   END  
END ELSE  
   CALL MSG("201","","",RESP) ; * file not attached  
END  
STOP  

Accessing a File from Within an MFS

An MFS may occasionally require access to a file while it is processing. For example, many applications require read-before-write verification. As another example, an audit trail MFS will need to write its audit information to an audit file.

There are two options for accessing files from within an MFS. The first is to access files directly, by using MFS calls. The second method is to execute R/BASIC file I/O commands such as READ and WRITE.

Different circumstances dictate the choice of one option or another. Briefly stated, direct calls are necessary when accessing the current file – the file for which the MFS has trapped a file operation. Access to files other than the current file is best handled using R/BASIC commands.

Accessing the Current File

If the MFS requires access to the current file, it should generally not generate an R/BASIC command to access the file. When an MFS uses R/BASIC commands to access a current file, those R/BASIC commands result in calls back to the same MFS.

In some instances, this can result in an infinite loop as the MFS processes these MFS-generated I/O calls. A good example is an MFS that spawns modified versions of the current call. For instance, a programmer might write an MFS that monitors record deletions in a programs file. When a delete is detected, the MFS spawns additional deletes to clean up the object code and symbol table records ($ and * records). If the MFS were to use R/BASIC commands, each subsequent DELETE would call the same MFS, which would spawn additional DELETE commands, etc.

Instead of using R/BASIC commands, the MFS can generate direct calls to the next MFS or the BFS. The following code fragment illustrates how an MFS might execute read-before-write logic using direct calls to the next filing system. Note that the MFS must preserve any values that might be changed by the direct call (such as the value of the RECORD argument).

WRITE.RECORD:  
  
* read-before-write logic here  
READ.RECORD = 1  
OLD.RECORD  = ''  
NEXTFS = BFS<1,1,2>  
CALL @NEXTFS(READ.RECORD, FS, HANDLE,NAME, FMC,‹  
   OLD.RECORD, STATUS)  
IF STATUS THEN  
   IF OLD.RECORD NE RECORD THEN  
      CALL MSG("Record ":NAME:" has changed.",‹  
         '','','')  
   END ELSE  
      CALL MSG("Record ":NAME:" has not changed.",‹  
         '','','')  
   END  
END ELSE  
   CALL MSG("Record ":NAME:" is a new ‹  
        record.",'','','')  
END  
  
* continue normal processing  
GOSUB NEXT.MFS  
RETURN  

Accessing Different Files

If the MFS needs to update a file other than the current file, it is best to use R/BASIC file I/O commands (OPEN, READ, WRITE, DELETE) rather than a direct call. If a direct call is used, the MFS will pass a call to the next filing system (MFS or BFS) for the current file. This may cause problems in two ways.

First, the MFS that follows the current MFS may be installed for only the current file, and not for other files. A direct call might thus inadvertently "install" the next MFS onto the second file being accessed.

Another problem is the converse of the first. By doing a direct call using the MFS list for the current file, an MFS may bypass the MFS list for the second file. For example, if an MFS uses a direct call to access a file that is indexed, SI.MFS will not be called unless by chance it appears in the BFS argument for the current file.

A corollary to this is that the second file may use an entirely different BFS. Obviously, a direct call from the MFS can only use the BFS for the current file.

Some applications might present a hybrid of these problems. An MFS might use R/BASIC commands to access a second file, only to discover that the second file also uses the current MFS – thereby resulting in a call to itself.

  • tips/revmedia/mfs3.txt
  • Last modified: 2024/06/19 20:20
  • by 127.0.0.1