6. 3GL Trigger
When data is being written to or read from Thoroughbred files, the 3GL Trigger allows you to modify that data transparent to the running application. Data can be normalized and file integrity can be maintained, without changing your current 3GL code.
When an I/O operation is performed and the data file is contained in a trigger list, that I/O is intercepted and passed to the trigger code before being returned to the application or being written to the disk.
The LOAD directive activates the given Trigger Method. The DROP directive can then deactivate the given Trigger Method.
Syntax
Section titled “Syntax”LOAD trigger-definition-list, OPT="IOT"DROP trigger-definition-list, OPT="IOT"Where:
trigger-definition-list is the trigger file list to activate or deactivate.
OPT=“IOT” is the keyword that indicates to Basic that this is a Trigger Definition List.
This causes a lookup in OOLIOT0 to match the trigger-definition-list. On each entry in the data-file-list for that trigger-definition-list is a Data-File/Trigger-Method pair.
Besides LOAD, you can also activate a trigger using the IPLINPUT file.
PRM LOADTRIGGER=trigger-definition-listSetting Up the Trigger
Section titled “Setting Up the Trigger”To set up the trigger, you must first create a trigger definition list, and then create a data file list for that definition.
Trigger Definition
Section titled “Trigger Definition”Below is the Format of the Trigger Definition List Files.
Name: OOFIOT1 , Trigger Definition List Files Fld Key --- Position ---- Data Element Length Sep HELP Ind1 TRIGGER-DEF-NAME.... 8 - TNAME YThe name of this trigger definition list. This is the name which ties back to the trigger definition list header and is used in the LOAD “trigger-definition-list”, OPT=“IOT” and DROP “ trigger-definition-list“, OPT=“IOT”.
2 TRIGGER-DESC........ 40 - TDESCProvides a descriptive definition for this trigger definition list.
3 CREATED-DATE........ 11.4 - TCDATEThe date on which this trigger definition list was created is automatically created.
Perform screen maintenance on OOLIOT1 and define the trigger-definition-list using normal Thoroughbred procedure (2-character library name and up to 6 characters for the file name).
You then can use up to 40 characters to describe your trigger definition.
Example
07/03/03 Trigger Definition List Files 1
TriggerDef Name Description Created Date/TimeHRTALL All Files 05/12/03 13:19:29HRTUSERS Users Triggers 06/20/03 13:24:58Trigger Method
Section titled “Trigger Method”Once you have created your Trigger Definition List you then must set up the data file list to be accessed by the Trigger Method during I/O to the data file.
Below is the format of the data file list.
Name: OOFIOT0 , I/O Trigger CONNECT spec Fld Key Data Element Length Sep HELP Ind========================================================= 1 TRIGGER-DEF-NAME.... 8 - TNAME YThe name of this trigger definition list. This is the name which ties back to the trigger definition list header and is used in the LOAD “ trigger-definition-list “, OPT=“IOT” and DROP “ trigger-definition-list“, OPT=“IOT”.
2 DATA-FILE-NAME...... 14 - TFILE YThe name of each Data file to be included in this trigger definition list.
3 LINK-NAME........... 8 - TLINK -Dictionary-IV Link Name that defines the FORMAT and any SORTS, which may exist for this file.
4 FORMAT-NAME......... 8 - TFMT -The Dictionary-IV Format Name that defines the data for the records in this file.
5 APPLICATION-TRIGGER. 8 - TTRIG -The Basic method that will be invoked by OOIO on any I/O to the data file.
6 IO-OPTION........... 1 - TIOOPT -Reserved for future use.
Example:
07/03/03 Data File List 1Trigger Data Link Format Applic I/ODef Name File Name Name Name Trigger OptionHRTALL ACCCHG HRL0123 HRF0123 HRTFTRIG NHRTALL ACCDEL HRL0124 HRF0124 HRTFTRIG NHRTALL ACCTA HRL0122 HRF0122 HRTFTRIG NHRTALL ACFILE HRL0313 HRF0313 HRTFTRIG NWhen an I/O directive to a file is executed and that file is contained in a trigger, Basic activates the “OOIO” method. Basic provides all information necessary for “OOIO” to determine which trigger method should be executed for the I/O action. This information is passed from Basic to OOIO in OOIO$[0] through OOIO$[7]. The record data passed into the trigger in entry OOIO$[5] is raw data. OOIO$[5] will have field separators and lengths just as if the record had been read into a string with the READ RECORD() directive. The data passed back to Basic in OOIO$[7] must have the delimiters in place so that the variable list for the READ directive can be filled. Please refer to the DTR() and RTD() functions in the Basic Language Reference for information on processing data in this format.
If an error condition occurs in OOIO, error processing can be controlled by setting the following variables prior to exiting:
- OOIO$[0]:
- "X" or "ERROR nnn".
When OOIO$[0] is set to “X” Basic assumes the trigger has done whatever is needed to complete the I/O directive. The interrupted program will continue at the next statement.
When OOIO$[0] is set to “ERROR nnn” the interrupted program will receive an ERR=nnn.
- CGV(“OOIO_ERROR”):
- The Common Global Variable "OOIO_ERROR" can be used to pass back additional message text or a CONNECT METHOD or RETURN directive including parameter values.
If OOIO is invoked from UPDATE, CONNECT SCREEN or CONNECT VIEW and OOIO$[0] is set to “ERROR 99”, the CONNECT METHOD or RETURN directive defined in “OOIO_ERROR” will be processed prior to returning control back to your application. If “OOIO_ERROR” is not set, normal error processing will be executed based on the value of ERR. In the case of the UPDATE directive, standard UPDATE ERROR PROCESSING IS procedure_name is always executed based on the value of ERR when control is returned to the Script.
The following example assumes an OPENworkshop environment. When OOIO exits, ERR will be set to 99 and the Method named TRIGERROR will be executed. The parameter “OutOfStock” is passed to the Method TRIGERROR.
LET O$=CGV("OOIO_ERROR","CONNECT METHOD TRIGERROR, OutOfStock");LET OOIO$[0]="ERROR 99";EXITThe following example assumes an OPENworkshop environment. When OOIO exits, ERR will be set to 99 and the Dictionary-IV Help definition named HELP01 will be displayed.
LET O$=CGV("OOIO_ERROR","ERROR HELP01; EXIT");LET OOIO$[0]="ERROR 99";EXITThe following example assumes a 3GL environment. When OOIO exits, ERR will be set to 90 and “OOIO_ERROR” will contain the message text “OutOfStock”. The application code can then test for the case where ERR=90 and process the appropriate error logic.
LET O$=CGV("OOIO_ERROR","OutOfStock");LET OOIO$[0]="ERROR 9O";EXITImportant: An example OOIO trigger is supplied in the Thoroughbred OO0 source library. The OO0 Source-IV library is a Thoroughbred library, it will be replaced if an upgrade is done. Never maintain your triggers in the OO0 library. To use OO0.OOIO as a template for your triggers you must first copy it to one of your application Source-IV libraries.
OOIO Example
Section titled “OOIO Example”METHOD OOIO$[ALL], OOIO[ALL]
OOIO$
[0] - Return values for basic. [1](1,1) - Basic directive code. (2,2) - Channel number for I/O operation. (4,14)- Basic file name associated with the channel. (18,1)- $02$ = IND= was specified $01$ = KEY= was specified $00$ = neither IND= or KEY= were specified. (19,1)- $01$ = DOM= was specified on a WRITE. (20,1)- $01$ = a record was not found for a READ. [2] - Basic file name table created by Load(s). Comes from file OOIOT0 and is defined by the link OOLIOT0 and the format OOFIOT0. This table is created and maintained by basic as LOAD trigger-class,OPT="IOT" and DROP trigger-class,OPT="IOT" directives are done. 1,14 - Basic File name. 15,8 - Dict Link name. 23,8 - Dict Format name. 31,8 - Basic File Trigger name. 39,1 - I/O Type: R-Read W-Write B-Both 40,x - etc. [3] - Channel number + Basic file name table entry address table. This table is maintained as basic files are opened closed. 1,2 - Channel number. 3,2 - Entry address within Basic File name table. [4] - Old record key when write. Current record key when read. [5] - Old record data when write is being done. Current record data when read. [6] - New record key when write. [7] - New record data when write. [8-N] These can be used by the trigger developer to maintain information needed by subsequent invocations, or to retain information to optimize access.
OOIO[ALL] Currently not used.PROCEDURE FUNC$= OOIO$[1], ! Set: basic function. DIRF$= FUNC$(1,1), ! dir/func code. CHN$ = FUNC$(2,2), ! channel number (str) . CHN = DEC(CHN$), ! channel number (num) . FILE$= FUNC$(4,14), ! dir/func file name. W$ = OOIO$[3], ! channel/file table. W = POS(CHN$=W$,4); ! Find channel in file table. IF W=0 ! If channel not opened EXIT ! Get out. FI; ! endif I = DEC($00$+W$(W+2,2)), ! Set: trigger table entry adr TE$ = OOIO$[2](I,39); ! trigger info entry. DF$ = TE$(1,14), ! data file name. LNK$ = TE$(15,8), ! link name. FMT$ = TE$(23,8), ! format name. FMI$ = "#"+FMT$, ! (usable form) TRG$ = TE$(31,8), ! trigger name. IOT$ = TE$(39,1), ! I/O type. OOIO$[0]=""; ! Clear return value. CALL TRG$,OOIO$[ALL],OOIO[ALL],DIRF$, ! Go process FILE$,DF$,LNK$,FMT$,IOT$,CHN$,CHN;! I/O IF OOIO$[0]="" ! If no return code OOIO$[0]="." ! Set ok return. FI; ! endif EXIT ! Get outExample Trigger Method
Section titled “Example Trigger Method”METHOD IOT$[ALL],IOT[ALL],DIRF$,FILE$,DF$,LNK$,FMT$,IOT$,CHN$,CHN
IOT$ [0] - Return values for basic. [1](1,1) - Basic directive code. (2,2) - Channel number for I/O operation. (4,14)- Basic file name associated with the channel. (18,1)- $02$ = IND= was specified $01$ = KEY= was specified $00$ = neither IND= or KEY= were specified. (19,1)- $01$ = DOM= was specified on a WRITE. (20,1)- $01$ = a record was not found for a READ. [2] - Basic file name table created by Load(s). Comes from file OOIOT0 and is defined by the link OOLIOT0 and the format OOFIOT0. This table is created and maintained by basic as LOAD trigger-class,OPT="IOT" and DROP trigger-class,OPT="IOT" directives are done. 1,14 - Basic File name. 15,8 - Dict Link name. 23,8 - Dict Format name. 31,8 - Basic File Trigger name. 39,1 - I/O Type: R-Read W-Write B-Both 40,x - etc. [3] - Channel number + Basic file name table entry address table. This table is maintained as basic files are opened closed. 1,2 - Channel number. 3,2 - Entry address within Basic File name table. [4] - Old record key when write. Current record key when read. [5] - Old record data when write is being done. Current record data when read. [6] - New record key when write. [7] - New record data when write. [8-N] These can be used by the trigger developer to maintain information needed by subsequent invocations, or to retain information to optimize access.
IOT[ALL] Currently not used. DIRF$ = One byte directive/function code. (Corresponds to the Basic Atom for that Directive) FILE$ = File name. LNK$ = Link name. FMT$ = Format name. IOT$ = IO Trigger type. CHN$ = Two byte binary channel number. CHN = Numeric channel number.PROCEDURE IOTT$= $20$+ ! OPEN. $21$+ ! CLOSE. $25$+ ! PRINT. $26$+ ! WRITE. $27$+ ! REMOVE $29$+ ! INPUT. $2A$+ ! READ. $2B$+ ! EXTRACT. $2C$+ ! FIND. $4A$+ ! INPUT RECORD. $4B$+ ! READ RECORD. $4C$+ ! EXTRACT RECORD. $4D$+ ! FIND RECORD. $4E$+ ! PRINT RECORD. $4F$+ ! WRITE RECORD. $54$+ ! READ PREVIOUS. $55$+ ! READ PREVIOUS RECORD. $56$+ ! EXTRACT PREVIOUS. $57$; ! EXTRACT PREVIOUS RECORD.
ON POS(DIRF$=IOTT$) GOSUB ! Go process I/O directive. BADDIR, ! Bad directive/function. XOPEN, ! OPEN. XCLOSE, ! CLOSE. XPRINT, ! PRINT. XWRITE, ! WRITE. XREMOVE, ! REMOVE XINPUT, ! INPUT. XREAD, ! READ. XEXTRACT, ! EXTRACT. XFIND, ! FIND. XINPUTRECORD, ! INPUTRECORD. XREADRECORD, ! READRECORD. XEXTRACTRECORD, ! EXTRACTRECORD. XFINDRECORD, ! FINDRECORD. XPRINTRECORD, ! PRINTRECORD. XWRITERECORD, ! WRITERECORD. XREADPREV, ! READPREV. XREADPREVRECORD, ! READPREVRECORD. XEXTRACTPREV, ! EXTRACTPREV. XEXTRACTPREVRECORD, ! EXTRACTPREVRECORD. BADDIR; ! Bad directive/function. EXIT
BADDIR ! PROCESS BAD DIRECTIVE. PRINT "Bad Directive: $"+HTA(DIRF$),"$",; ! Show status. INPUT *; ! Wait for input. RETURN ! Return.
XOPEN! Processing RETURNXCLOSE! Processing RETURN
XPRINT! Processing RETURN
XWRITE! Processing RETURN
XREMOVE! Processing RETURN
XINPUT! Processing RETURN
XREAD! Processing RETURN
XEXTRACT GOSUB XREAD; RETURN
XFIND GOSUB XREAD; RETURN
XINPUTRECORD! Processing RETURN
XREADRECORD GOSUB XREAD; RETURN
XEXTRACTRECORD GOSUB XREAD; RETURN
XFINDRECORD GOSUB XREAD; RETURN
XPRINTRECORD! Processing RETURN
XWRITERECORD GOSUB XWRITE; RETURNXREADPREV GOSUB XREAD; RETURN
XREADPREVRECORD GOSUB XREAD; RETURN
XEXTRACTPREV GOSUB XREAD; RETURN
XEXTRACTPREVRECORD GOSUB XREAD; RETURNFrom the Thoroughbred Basic Developer Guide, version 8.9.1. Open this page in the PDF