public class DatabaseTriggerManager extends java.lang.Object implements Scopeable
Scopeable
it is initialized in StandardServer.invoke()
, before the
topmost "startup" scope is pushed.
The DatabaseTriggerManager
is notified when the execution enters and leaves
subroutine blocks so it can do the management of trigger layers.Modifier and Type | Field and Description |
---|---|
private static ContextLocal<DatabaseTriggerManager> |
context
Context local map of instances of this class, mapped by theirs database name .
|
private java.util.Map<java.lang.Class<? extends Buffer>,java.util.HashMap<java.lang.Long,java.util.Deque<DatabaseEventType>>> |
executing
The stack of currently executing triggers in this context for each record id.
|
private static java.util.logging.Logger |
LOG
Logger
|
private ProcedureManager.ProcedureHelper |
pm
Helper to use the ProcedureManager without any context local lookups.
|
private java.util.Deque<TriggerBlockLayer> |
stack
The stack of all layer of triggers handled by this manager.
|
private TransactionManager.TransactionHelper |
tm
Helper to use the TM without any context local lookups.
|
Modifier | Constructor and Description |
---|---|
private |
DatabaseTriggerManager()
Private constructor.
|
Modifier and Type | Method and Description |
---|---|
(package private) boolean |
areAssignTriggersEnabled(java.lang.Class<? extends Buffer> bufferCls)
Indicate whether assign triggers are enabled for the given buffer class at this block
level.
|
private static Buffer |
createWriteOldBuffer(java.lang.Class<?> def,
java.lang.Class<? extends Buffer> bufferCls,
Record oldDmoValue)
Extract only the DMO schema-specific interface (i.e., exclude the Buffer interface)
|
static void |
deregisterDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls)
Unregister a session database trigger for the given event type and buffer class.
|
static void |
deregisterDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property)
Unregister a session database trigger for the given event type and buffer class.
|
static boolean |
disableDumpTriggers(java.lang.Class<? extends Buffer> bufferCls)
Disables dump triggers (
FIND events) for the current block and any block of a
callee from this block (function, internal/external procedure). |
static boolean |
disableLoadTriggers(java.lang.Class<? extends Buffer> bufferCls)
Disables load triggers (
CREATE , ASSIGN , WRITE events)
for the current block. |
static boolean |
disableLoadTriggers(java.lang.Class<? extends Buffer> bufferCls,
boolean allowReplication)
Disables load triggers (
CREATE , ASSIGN , WRITE events)
for the current block. |
private static boolean |
fireAssignTrigger(TriggerData triggerData,
Buffer newVal,
java.lang.String property,
BaseDataType oldValue)
Instantiates an object of the ASSIGN trigger and fires it.
|
private static void |
fireTrigger(DatabaseEventType det,
TriggerData triggerData,
Buffer buffer,
Buffer oldValue)
Instantiates a trigger object associated with the specified database event type and
fires it.
|
static DatabaseTriggerManager |
get()
Obtain the context-local DatabaseTriggerManager object.
|
(package private) java.util.Deque<DatabaseEventType> |
getExecutingTriggerStack(java.lang.Class<? extends Buffer> bufferClass,
java.lang.Long rowId,
boolean create)
Get the set of triggers that are currently executed for a specified record.
|
static DatabaseEventType |
getReplicationEvent(DatabaseEventType det)
Convert a base database event into the replication event.
|
static TriggerData |
getReplicationSchemaTrigger(DatabaseEventType det,
java.lang.Class<? extends Buffer> bufferCls)
Obtain the container that hold information for instantiating a schema trigger object for
the replication version of the
det event. |
static TriggerData |
getSchemaTrigger(DatabaseEventType det,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property)
Obtain the container that holds information for instantiating a schema trigger object
responsible for a
det event. |
private TriggerBlockLayer.EnableStatus |
getTriggerStatus(DatabaseEventType det,
java.lang.Class<? extends Buffer> bufferCls)
Looks into the stack of layers and check if a trigger is enabled for a database event.
|
private static boolean |
guardedExec(java.lang.Runnable code)
Execute a piece of code, checking whether it raised an ERROR.
|
static void |
handleError(int errId,
DatabaseEventType det,
java.lang.String tableOrBufferName,
java.lang.String fieldName)
Handle trigger- related errors.
|
private static DatabaseTrigger<Buffer> |
instantiateTrigger(TriggerData triggerData)
Create a trigger object instance based on information from a
TriggerData
container. |
(package private) boolean |
isAssignTrigger(java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property)
Indicate whether an assign trigger (session or schema) is registered for the given buffer
class and DMO property at the current block level.
|
private static boolean |
isSchemaTriggerOverrideable(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls)
Tests if a schema trigger is overrideable.
|
(package private) boolean |
isTriggerEnabled(DatabaseEventType det,
java.lang.Class<? extends Buffer> bufferCls)
Indicate whether any trigger (session or schema) of the specified type is registered for the
given buffer class at the current block level.
|
private TriggerData |
peekTrigger(DatabaseEventType det,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property)
Implementation of the trigger search algorithm in the stack of triggers.
|
static void |
registerDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.Class<? extends DatabaseTrigger> triggerCls,
java.lang.Object container)
Register a session database trigger within the current scope.
|
static void |
registerDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.Class<? extends DatabaseTrigger> triggerCls,
java.lang.Object container,
boolean override)
Register a session database trigger within the current scope.
|
static void |
registerDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.Class<? extends DatabaseTrigger> triggerCls,
java.lang.Object container,
boolean override,
boolean hasOldBuffer)
Register a session database trigger within the current scope.
|
static void |
registerDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property,
java.lang.Class<? extends DatabaseTrigger> triggerCls,
java.lang.Object container)
Register an
ASSIGN session database trigger within the current scope. |
static void |
registerDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property,
java.lang.Class<? extends DatabaseTrigger> triggerCls,
java.lang.Object container,
boolean override)
Register an
ASSIGN session database trigger within the current scope. |
static void |
registerDatabaseTrigger(DatabaseEventType event,
java.lang.Class<? extends Buffer> bufferCls,
java.lang.String property,
java.lang.Class<? extends DatabaseTrigger> triggerCls,
java.lang.Object container,
boolean override,
boolean hasOldValue)
Register an
ASSIGN session database trigger within the current scope. |
(package private) void |
removeExecutingTriggerStack(java.lang.Class<? extends Buffer> bufferClass,
java.lang.Long rowId)
Cleanup.
|
void |
scopeDeleted()
Provides a notification that an external scope is about to be deleted.
|
void |
scopeFinished()
Provides a notification that a scope is about to be exited.
|
void |
scopeStart()
Provides a notification that a new scope is about to be entered.
|
static boolean |
trigger(DatabaseEventType det,
java.lang.Class<? extends Buffer> bufferCls,
Buffer newVal,
Record oldDmoValue)
Executes trigger suite for a base event (except for
ASSIGN triggers). |
static boolean |
triggerAssign(java.lang.Class<? extends Buffer> bufferCls,
Buffer newVal,
java.lang.String property,
BaseDataType oldValue)
Executes an ASSIGN trigger.
|
private static final java.util.logging.Logger LOG
private static final ContextLocal<DatabaseTriggerManager> context
private final ProcedureManager.ProcedureHelper pm
private final TransactionManager.TransactionHelper tm
private final java.util.Deque<TriggerBlockLayer> stack
private final java.util.Map<java.lang.Class<? extends Buffer>,java.util.HashMap<java.lang.Long,java.util.Deque<DatabaseEventType>>> executing
private DatabaseTriggerManager()
public static TriggerData getSchemaTrigger(DatabaseEventType det, java.lang.Class<? extends Buffer> bufferCls, java.lang.String property)
det
event. If such trigger does not exist, or the procedure
defined is invalid, a null object is returned.det
- The database event to which the trigger responds to.bufferCls
- The class that defines the table for which the trigger applies to.property
- Optionally, for ASSIGN triggers the name of the property (field) for which the
trigger was declared. Otherwise it is ignored.public static TriggerData getReplicationSchemaTrigger(DatabaseEventType det, java.lang.Class<? extends Buffer> bufferCls)
det
event. This call is only valid for events
that have replication equivalent. If these conditions are not met or no such replication
trigger was defined, then a null object is returned.det
- The database event whose replication equivalent trigger responds to.bufferCls
- The buffer class for the dmo that fired the trigger.public static DatabaseTriggerManager get()
public static void registerDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.Class<? extends DatabaseTrigger> triggerCls, java.lang.Object container)
OLD [BUFFER]
.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.triggerCls
- The class of the trigger.container
- The containing object (all triggers are implemented as non-static inner classes,
so they must have a reference to the containing class).public static void registerDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.Class<? extends DatabaseTrigger> triggerCls, java.lang.Object container, boolean override)
OLD [BUFFER]
.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.triggerCls
- The class of the trigger.container
- The containing object (all triggers are implemented as non-static inner classes,
so they must have a reference to the containing class).override
- true
if OVERRIDE keyword is specified.public static void registerDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.Class<? extends DatabaseTrigger> triggerCls, java.lang.Object container, boolean override, boolean hasOldBuffer)
event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.triggerCls
- The class of the trigger.container
- The containing object (all triggers are implemented as non-static inner classes,
so they must have a reference to the containing class).override
- true
if OVERRIDE keyword is specified.hasOldBuffer
- true
if an OLD [BUFFER] keyword is specified.public static void registerDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.String property, java.lang.Class<? extends DatabaseTrigger> triggerCls, java.lang.Object container)
ASSIGN
session database trigger within the current scope. Any
previously registered session trigger on current block is silently removed. This overloaded
method is always not overriding the schema trigger and is not declaring an
OLD [VALUE]
.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.triggerCls
- The class of the trigger.container
- The containing object (all triggers are implemented as non-static inner classes,
so they must have a reference to the containing class).public static void registerDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.String property, java.lang.Class<? extends DatabaseTrigger> triggerCls, java.lang.Object container, boolean override)
ASSIGN
session database trigger within the current scope. Any
previously registered session trigger on current block is silently removed. This overloaded
method is not declaring an OLD [VALUE]
.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.triggerCls
- The class of the trigger.container
- The containing object (all triggers are implemented as non-static inner classes,
so they must have a reference to the containing class).override
- true
if OVERRIDE
keyword is specified.public static void registerDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.String property, java.lang.Class<? extends DatabaseTrigger> triggerCls, java.lang.Object container, boolean override, boolean hasOldValue)
ASSIGN
session database trigger within the current scope. Any previously
registered session trigger on current block is silently removed.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.triggerCls
- The class of the trigger.container
- The containing object (all triggers are implemented as non-static inner classes,
so they must have a reference to the containing class).override
- true
if OVERRIDE
keyword is specified.public static void deregisterDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls, java.lang.String property)
ON Assign OF <table.field> REVERT
.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.property
- The property that is deregistered from ASSIGN
trigger.public static void deregisterDatabaseTrigger(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls)
ON <event> OF <table> REVERT
.event
- Database event type.bufferCls
- The class of the buffer to which the event is applied.public static boolean disableDumpTriggers(java.lang.Class<? extends Buffer> bufferCls)
FIND
events) for the current block and any block of a
callee from this block (function, internal/external procedure).bufferCls
- The buffer for which to disable dump triggers.true
if the filter was successfully applied. If false
is returned then the internal stack is broken because of bad block management.public static boolean disableLoadTriggers(java.lang.Class<? extends Buffer> bufferCls)
CREATE
, ASSIGN
, WRITE
events)
for the current block. The replication triggers are also disabled.bufferCls
- The buffer for which to disable load triggers.true
if the filter was successfully applied. If false
is returned then the internal stack is broken because of bad block management.public static boolean disableLoadTriggers(java.lang.Class<? extends Buffer> bufferCls, boolean allowReplication)
CREATE
, ASSIGN
, WRITE
events)
for the current block.bufferCls
- The buffer for which to disable load triggers.allowReplication
- If true
the replication triggers will not be disabled for this block.true
if the filter was successfully applied. If false
is returned then the internal stack is broken because of bad block management.public static boolean trigger(DatabaseEventType det, java.lang.Class<? extends Buffer> bufferCls, Buffer newVal, Record oldDmoValue)
ASSIGN
triggers). The suite includes the
session, simple schema and replication triggers that have been defined/assigned for the det
base
event. The order in which they execute depends on det
: session triggers are always executed
first and replication triggers last, except for the FIND
triggers, where schema triggers execute
execute before session triggers and there is no replication trigger to execute.det
- The trigger type to be executed.bufferCls
- The buffer class for the dmo that fired the trigger.newVal
- The buffer that fired the trigger.oldDmoValue
- When the (WRITE) trigger declares an 'old' buffer value, this is passed to trigger procedure as
r/o buffer.true
if no trigger was executed or they executed with success. The method will return
false
if the trigger vetoed the operation (by returning error).public static DatabaseEventType getReplicationEvent(DatabaseEventType det)
null
is returned.det
- The base trigger event.det
. For FIND and ASSIGN null
is returned.public static boolean triggerAssign(java.lang.Class<? extends Buffer> bufferCls, Buffer newVal, java.lang.String property, BaseDataType oldValue)
bufferCls
- The buffer class for the dmo that fired the trigger.newVal
- The buffer that contains the field that fired the trigger.oldValue
- When the ASSIGN trigger declares an 'old' value, this is passed to trigger
procedure. The procedure code is allowed to modify this value without generating
any error, however, they are lost as only a duplicate is passed on.true
if no trigger was executed or they executed with success. The method will return
false
if the trigger vetoed the operation (by returning error).public void scopeStart()
scopeStart
in interface Scopeable
public void scopeDeleted()
scopeDeleted
in interface Scopeable
public void scopeFinished()
scopeFinished
in interface Scopeable
private static boolean isSchemaTriggerOverrideable(DatabaseEventType event, java.lang.Class<? extends Buffer> bufferCls)
true
is returned. Otherwise, 3223 code is recordOrThrowError
.
If no error is acting false
will be returned.event
- The database event of the trigger to be tested.bufferCls
- The class buf for the table the trigger is defined.true
if respective trigger can be overridden by a session trigger.private static DatabaseTrigger<Buffer> instantiateTrigger(TriggerData triggerData)
TriggerData
container.triggerData
- The container that holds information about the trigger to be built.triggerData
.private static Buffer createWriteOldBuffer(java.lang.Class<?> def, java.lang.Class<? extends Buffer> bufferCls, Record oldDmoValue)
def
- The source-definition class for the trigger.bufferCls
- Interface which defines DMO's public API plus all Buffer
methods.oldDmoValue
- The read-only value.private static boolean fireAssignTrigger(TriggerData triggerData, Buffer newVal, java.lang.String property, BaseDataType oldValue)
triggerData
- Information about how the trigger will be built.newVal
- The buffer that contains the field that fired the trigger.property
- Optionally, for ASSIGN triggers the name of the property (field) for which the
trigger was declared. Otherwise it is ignored.oldValue
- The old value of the field. May be null if the trigger did not declared it.true
if no trigger was executed or they executed with success. The method will return
false
if the trigger vetoed the operation (by returning error).private static void fireTrigger(DatabaseEventType det, TriggerData triggerData, Buffer buffer, Buffer oldValue)
det
- The database event type to be fired.triggerData
- Information about how the trigger will be built.buffer
- The buffer that fired the trigger.oldValue
- The old value of the buffer. May be null if the trigger did not declared it.public static void handleError(int errId, DatabaseEventType det, java.lang.String tableOrBufferName, java.lang.String fieldName)
errId
- The id of the error.det
- The database event that caused the error.tableOrBufferName
- The name of the table (or buffer in some cases) that caused the errorfieldName
- In the case of ASSIGN
trigger the field that caused the error.boolean isTriggerEnabled(DatabaseEventType det, java.lang.Class<? extends Buffer> bufferCls)
det
- Trigger type.bufferCls
- Buffer class.true
if a registered trigger is found, else false
.boolean areAssignTriggersEnabled(java.lang.Class<? extends Buffer> bufferCls)
bufferCls
- Buffer class.true
boolean isAssignTrigger(java.lang.Class<? extends Buffer> bufferCls, java.lang.String property)
bufferCls
- Buffer class.property
- DMO property name.true
if a registered trigger is found, else false
.java.util.Deque<DatabaseEventType> getExecutingTriggerStack(java.lang.Class<? extends Buffer> bufferClass, java.lang.Long rowId, boolean create)
bufferClass
- The dmo buffer interface.rowId
- The id of the record.create
- If the specified stack does not exist, make sure it is created.null
if stack does not exist and
creation of a new one was not requested.void removeExecutingTriggerStack(java.lang.Class<? extends Buffer> bufferClass, java.lang.Long rowId)
bufferClass
- The dmo buffer interface.rowId
- The id of the record.private TriggerBlockLayer.EnableStatus getTriggerStatus(DatabaseEventType det, java.lang.Class<? extends Buffer> bufferCls)
EnableStatus.ENABLED
is returned. If
the trigger was disabled, the EnableStatus.DISABLED
is returned unless the
events has a replication pair and it was not disable using ALLOW-REPLICATION
,
when EnableStatus.REPLICATION_ONLY
is returned.
FIND/ASSIGN/CREATE/WRITE events won't return ENABLED here, they will either return DISABLED or UNKNOWN. Thus we check the entire stack until DISABLED is found and if DISABLED is never returned, then we are implicitly ENABLED.
det
- The database (base) event.bufferCls
- The buffer.private TriggerData peekTrigger(DatabaseEventType det, java.lang.Class<? extends Buffer> bufferCls, java.lang.String property)
det
type of trigger associated with buff
.
If found it is returned, otherwise the search continue with the next level from the stack.
If no such trigger can be found, null
is returned.
This method takes into account if respective trigger event was disabled and, in this case,
a special singleton object is returned.det
- The database trigger type.bufferCls
- The buffer that raised the trigger event.property
- In the case of ASSIGN trigger, the name of the property that fired the triggerdet
type associated
with buff
.private static boolean guardedExec(java.lang.Runnable code)
false
is returned if already in silent mode, otherwise the exception will propagate to the caller.code
- The code to be executed.true
if the code executed normally, and false
if it raised an error while in
silent mode.ErrorConditionException
- if an error condition was raised while not in silent mode