Rush Flat Consulting

Notes on UniVerse Triggers

      SUBROUTINE QUV.TRIGGER(triggername, schema, filename, event, timing, newid, newrec, oldid, oldrec, assoc, assoc.event, trigcnt, chain.cascade, cascade)
      ************************************************************************
      * Bp.Q Quv.Trigger - Master subroutine for UV Triggers.
      *
      * Author : BSS
      * Created: 17 Jun 2014
      * Updated: 24 Jun 2014
      * Version: 0.0.1
      *
      $INCLUDE Q.INCLUDES QB.COMMON.H
      
      *
      * Triggers apply to individual files, so we can't specify a trigger
      * to cover all files in a multi-file structure. We have to create a
      * file pointer to each of the individual files and then apply the
      * trigger to that file pointer. What we want to here is catch those
      * instances and apply a global trigger for all the multi-files.
      *
      CONVERT '/\' TO DS:DS IN filename     ;* DS = path delimiter
      IF INDEX(filename, DS, 1) THEN
        dictname = FIELD(filename, DS, DCOUNT(filename, DS) - 1)
        triggersub = dictname:'.TRIGGER'
      END ELSE
        triggersub = filename:'.TRIGGER'
      END
      
      CALL Q.CATALOGUED(triggersub, iscatalogued)
      IF NOT(iscatalogued) THEN RETURN
      
      mode = timing:' ':event
      CALL @triggersub(filename, mode, newid, newrec, oldid, oldrec)
      
      RETURN
      *
      * ---------------------------------------------------------------------- *
      *
      END
      
	  
    Program "TEST": Line 9, File is locked. Update not allowed
    Program "TEST": Line 9, Error performing trigger for "BSTEST\BSTEST2".
    Write failed: Status: -4
	

The code used in this write was:

    WRITE rec ON bs2, id ON ERROR
      CRT 'Error'
    END ELSE
      CRT 'Write failed: Status: ':STATUS()
    END
	

This indicates that the WRITE took the ELSE clause after the trigger failure rather than the ON ERROR clause.

There doesn't appear to be a good way of suppressing the error lines that appear on the screen. You can wrap the WRITE block in HUSH statements, but you would want to check the STATUS variable to determine if any errors occurred.

I was expecting another error here because the above code did not obtain an exclusive lock before writing the item. However, it turns out that the triggers only enforce locking within TRANSACTIONS. This behaviour is controlled by the ISOMODE configuration parameter (can be modified within the UniVerse Extensible Admin tool). If ISOMODE were set to 2, then all writes and deletes would require exclusive locking of the records.

Rushes.gif