====== Index Transaction Code=====
^Published By^Date^Version^Knowledge Level^Keywords^
|Revelation Technologies|30 OCT 1988|1.1X|EXPERT|!, INDEXING|
Advanced Revelation 1.1 provides a unique and powerful hook into index
processing. A developer can modify or replace the routines that process
transactions created during modifications to an indexed file.
==== Index Transactions ====
In Advanced Revelation 1.1, most index updating activity is handled by the
processing of transaction information. When a record is modified or added,
information regarding changes to indexed fileds in that record is written to
the !INDEXING file. These transactions are later moved into the index files
(the !data files), which are created during the index creation process.
The process of moving the transactions into the !INDEXING file is now
handled by a specialized routine generated during the index creation
process. Since a custom transaction program is created for each indexed
file, the index transactions are handled more efficiently than by the
general processing routines used in version 1.0.
The transaction routine is a symbolic field, generated when the index is
created. The dictionary record for this symbolic is stored in the "!" record
of the index file of the data file. For example, the index transaction
routine that updates the indexes for the CUSTOMER file is stored in the '!'
record of the !CUSTOMER file.
==== Capturing Index Transaction Code ====
When the system generates the transaction routine, it will look for a "!!"
record in the index file. If this record is present, it will store the
R/BASIC source code used by the symbolic field into this record. The source
code can then be edited and used to modify the index transaction process.
To capture the source code, simply create an empty "!!" record in the index
file. The next time an index for this file is created, the system will store
the source code in the "!!" record.
==== Modifications ====
Since the "!" record is called as a symbolic field, implementing a modified
transaction program requires a few more steps than simply compiling the
modified source code and copying the object code to the '!' record. The '!'
record format must be that of a symbolic dictionary item. There are a couple
of methods for implementing changes to the transaction process.
The first method involves an R/BASIC program that converts the source code
in the '!!' record into a symbolic dictionary format, and moveds it into the
"!" record. See figure 1.
Another method is to create an entry in the VOC file for the compiled
source. For example, if the "!!" record of the !DATA.FILE was compiled,
simply use the editor to create a new record in the VOC. The VOC record key
can be any permissible key. The record layout should be:
field 1: RBASIC
field 2:
field 3: !DATA.FILE
field 4: !!
Next, create a symbolic field in the dictionary of the data file. The
formula of this symbolic simply calls the VOC item created above. For
example, if the VOC item key is INDEX.TRANSACTION.CODE, the formula would
be:
CALL INDEX.TRANSACTION.CODE
The last step is to RECORDCOPY this dictionary item from the DICT.DATA.FILE
into the '!' record of the !DATA.FILE. Use the (O) option to overwrite the
existing '!' record.
Since each indexed file has its own transaction routine, it is possible to
tailor the index transactions for specific files. Note: Use the unmodified
transaction code to gain a full understanding of how index transactions are
handled before making any modifications! Examining unmodified code will aid
in understanding the following example.
==== Example ====
Figure 2 demonstrates how index transaction can be modified "on-the-fly"
based on external criteria. This listing outlines changes made to the
generated index transaction code for a sample file.
In this example, a labeled common variable is used as a flag to determine
whether or not this index should be updated immediately after posting the
transaction. The flag variable is set by an external routine.
The labeled common variable UPDATE.INDEX.NOW determines the update process.
If it is true, then a local subroutine invokes a call to the system
subroutine INDEX.FLUSH. The flag is tested only when a transaction has been
written to the !INDEXING file to avoid unnecessary updates to the index.
=== Figure 1 ===
* create new ! record in !file
FILE = ''
CALL MSG("Which File?","R",FILE,'')
OPEN "!":FILE TO INDEX.FILE.VAR ELSE
CALL MSG('!':FILE:"can't be opened!",'','','')
STOP
END
READ SOURCE FROM INDEX.FILE.VAR, '!!' THEN
NEW.UPDATE.PGM = 'S'
CONVERT @FM TO @VM IN SOURCE
NEW.UPDATE.PGM<8> = SOURCE
WRITE NEW.UPDATE.PGM ON INDEX.FILE.VAR, '$!!'
PERFORM 'DICTCOMPILE !':FILE:' $!!'
READ OBJECT FROM INDEX.FILE.VAR, '$!!' THEN
WRITE OBJECT ON INDEX.FILE.VAR,'!'
END
END ELSE
CALL MSG('No !! source code available','','','')
END
=== Figure 2 ===
* program INDEX.TEST secondary index transaction builder
*-------------------
* invoked like a dictionary CALCULATE
* input: @MV = 0 for WRITE, 1 for DELETE, 2 for CLEARFILE
* @ID = record key for WRITE and DELETE
* @RECORD = record for WRITE
* @ANS = datafile file variable
* returns: nothing
*--------------------
* this routine forces a flush of the index transaction for the
* FIELDNAME field of the INDEX.TEST file if the flag UPDATE.INDEX.NOW
* has been set by an external routine.
*
* the first parameter required by INDEX.FLUSH is:
*
* FILENAME*ACCOUNT.NAME*MEDIA.NAME
*
* this string is hardcoded to speed processing. The second parameter
* is the indexed file name.
* (for additional information on using the system subroutine
* INDEX.FLUSH, refer to the "Appendix to Using Advanced Revelation")
*--------------------
* common block used by indexing system (NOTE: this should be ONE line)
COMMON /%%SI%%/MAX.UPDATE.SIZE,INDEXES,INDEXES.FILEVAR,NO.PROTECT,OLD.REC
OLD.FLAG,OLD.FV,OLD.ID,DICT.FVS%,BATCH.MODE%,UPDATE.ITEM%
* labeled common area to use as flag value for forced index flush
COMMON /%BANG.BANG.FLAGS%/ UPDATE.INDEX.NOW
*---------------------
* (body of index transaction code generated by system goes here
*---------------------
IF WRITE.UPDATES THEN
WRITE UPDATE.ITEM% ON INDEXES.FILEVAR,'0'
IF @STATION NE '' THEN
UNLOCK INDEXES.FILEVAR,'0'
END
* (customization here)
* test if index flush should be forced after the write.
* this test is only made after a write to !INDEXING
IF UPDATE.INDEX.NOW THEN
* the parameters should match the appropriate media name
* and fieldname for the application
PARM1 = "INDEX.TEST*SYSPROG*AREV.06:52:53 21 JUN 1988 (S)"
PARM2 = 'FIELDNAME"
CALL INDEX.FLUSH(PARM1,PARM2)
UPDATE.ITEM% = ''
END ;* if update.index.now
* (end of customization)
END ;* if write.updates
* skip final processing if CLEARFILE
IF @MV EQ 2 ELSE
* unlock all indexes that were logically locked before getting
* the old values
IF @STATION NE '' THEN
IF ITEM.LOCKED THEN
UNLOCKED LOCK.FILEVAR,@ID
END
END ; * if @station
END ; * if @mv