Embedded Basic Examples

Triggers

The first example is a subroutine that is intended to be used as a PRE-WRITE and PRE-DELETE trigger. It performs some validation and also records information about the operation for later use by the second example.

SUBROUTINE PRE.TRIG(ITEM)
 *
 * This routine can be used as Pre-Write and Pre-Delete trigger.
 *
 * It performs some validation and also records information
 * about the operation for later use by the Post Trigger.
 *
 *-----------------------------------------------------------------
 *
 * Named Common - used to share info between Pre and Post Triggers
 *
 COMMON /TRIGSTUFF/ T.LOGFILE,T.TYPE,T.SEQ
 *
 * Set a debugger entry point in case we need to debug this routine
 * using the EB.DEBUG environment option
 *
 DEBUG
 *
 * Open Logfile for use by Post Trigger
 *
 IF UNASSIGNED(T.LOGFILE) THEN
   *
   * We open the logfile here so that we can abort the operation
   * if there is any problem. By the time the Post trigger is called
   * the operation has completed and cannot easily be cancelled.
   *
   OPEN "LOGFILE" TO T.LOGFILE ELSE
     INPUTERR "Cannot open logfile - operation aborted"
     RETURN
   END
 END
 *
 * Only users with SYS2 privilege are allowed to update this file
 *
 PRIV = SYSTEM(28)  ;* current system privilege level (0,1,2)
 IF (PRIV<2) THEN
   INPUTERR "You do not have permission to update this file"
   RETURN
 END
 *
 * Determine type of operation
 *
 DELETING = ACCESS(12)  ;* True if item being deleted
 NEW.ITEM = ACCESS(16)  ;* True if new item being written
 BEGIN CASE
   CASE DELETING; T.TYPE="DEL";    * delete item
   CASE NEW.ITEM; T.TYPE="NEW";    * write new item
   CASE 1;        T.TYPE="UPD";    * update existing item
 END CASE
 *
 * Check the value of attribute 2 is valid
 *
 IF NOT(DELETING) THEN
   A2 = ITEM<2>
   IF (A2<0) OR (A2>100) THEN
     INPUTERR "Value out of range"
     RETURN
   END
 END
 *
 * If we got here there were no problems, so we return without
 * using INPUTERR to allow the operation to complete.
 *
RETURN

The second example is a POST-WRITE and POST-DELETE trigger subroutine. It logs the operation using information saved by the previous example.

SUBROUTINE POST.TRIG(ITEM)
 *
 * This routine is a Post-Write and Post-Delete trigger.
 *
 * It logs the operation using information saved by the Pre Trigger.
 *
 *-----------------------------------------------------------------
 *
 * Named Common - used to share info between Pre and Post Triggers
 *                and to save a logging sequence number
 *
 COMMON /TRIGSTUFF/ T.LOGFILE,T.TYPE,T.SEQ
 IF UNASSIGNED(T.SEQ) THEN T.SEQ=0
 *
 * Set a debugger entry point in case we need to debug this routine
 * using the EB.DEBUG environment option
 *
 DEBUG
 *
 * Construct a unique Log item-id
 *
 PORT = SYSTEM(18)  ;* current port number
 T.SEQ += 1         ;* logging sequence number
 *
 LOGID = DATE():'~':TIME():'~':PORT:'~':T.SEQ
 *
 * Construct Log record
 *
 LOGITEM = ''
 LOGITEM<1> = ACCESS(10)  ;* Item-id of item written or deleted
 LOGITEM<2> = T.TYPE      ;* Operation type (NEW, UPD or DEL)
 *
 * Record operation to logfile
 *
 WRITE LOGITEM ON T.LOGFILE,LOGID ON ERROR
   *
   * Write to logfile failed, but operation on datafile completed.
   * Not much we can do here except shout loudly.
   * If using Transaction Boundaries we could use TRANSABORT.
   *
   CRT
   CRT "*** ERROR - Cannot write to logfile"
   CRT
 END
 *
RETURN

Dictionary Subroutines

The dictionary subroutine which follows returns the highest numeric value in the values and subvalues of the first attribute of the item. It would be called using the CALL conversion code in attribute 7 of a File Definition item or in attribute 7 or 8 of a Data Definition item.

SUBROUTINE MAX1(VALUE)
*
* ACCESS(3) = FILE ITEM
*
* Get the item and extract the first attribute.
VALUE = MAXIMUM(ACCESS(3)<1>)
RETURN

This would be called using the following conversion code:

CALL MAX1

The next example demonstrates how to pass parameters to dictionary subroutines:

SUBROUTINE DICT1(P)
    P = P:",":ACCESS(31):",Done"
RETURN

When called from within a CALL conversion code, the P parameter will contain the data passed to it by the conversion processor, while the call to the ACCESS(31) function obtains any parameters that follow the subroutine name. The subroutine modifies the value of P and, on exit, this modified value is used as the output of the conversion code.

This subroutine could be called using the following conversion code:

A;0vmCALL DICT1svmFred

where vm is a value mark and svm a subvalue mark. Typical output would be as follows:

DISTANCE,Fred,Done

Where DISTANCE is the id of an item in the listed file (generated by the A conversion code).

See Also

Embedded Basic Subroutines
How to Write an Embedded Basic Subroutine
Debugging Embedded Basic Subroutines
How to Associate a Trigger with a File
Triggers Dos and Don'ts