001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.RowTriggerExecutor
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.execute;
023:
024: import org.apache.derby.iapi.sql.execute.CursorResultSet;
025: import org.apache.derby.iapi.error.StandardException;
026: import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
027: import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
028: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
029: import org.apache.derby.iapi.sql.Activation;
030:
031: /**
032: * A row trigger executor is an object that executes
033: * a row trigger. It is instantiated at execution time.
034: * There is one per row trigger.
035: */
036: public class RowTriggerExecutor extends GenericTriggerExecutor {
037: /**
038: * Constructor
039: *
040: * @param tec the execution context
041: * @param triggerd the trigger descriptor
042: * @param activation the activation
043: * @param lcc the lcc
044: */
045: RowTriggerExecutor(InternalTriggerExecutionContext tec,
046: TriggerDescriptor triggerd, Activation activation,
047: LanguageConnectionContext lcc) {
048: super (tec, triggerd, activation, lcc);
049: }
050:
051: /**
052: * Fire the trigger based on the event.
053: *
054: * @param event the trigger event
055: * @param brs the before result set
056: * @param ars the after result set
057: *
058: * @exception StandardExcetion on error or general trigger
059: * exception
060: */
061: void fireTrigger(TriggerEvent event, CursorResultSet brs,
062: CursorResultSet ars) throws StandardException {
063: tec.setTrigger(triggerd);
064:
065: try {
066: while (true) {
067: if (brs != null) {
068: if (brs.getNextRow() == null)
069: break;
070: }
071:
072: if (ars != null) {
073: if (ars.getNextRow() == null)
074: break;
075: }
076:
077: tec.setBeforeResultSet(brs == null ? null
078: : TemporaryRowHolderResultSet
079: .getNewRSOnCurrentRow(activation, brs));
080:
081: tec.setAfterResultSet(ars == null ? null
082: : TemporaryRowHolderResultSet
083: .getNewRSOnCurrentRow(activation, ars));
084:
085: /*
086: This is the key to handling autoincrement values that might
087: be seen by insert triggers. For an AFTER ROW trigger, update
088: the autoincrement counters before executing the SPS for the
089: trigger.
090: */
091: if (event.isAfter())
092: tec.updateAICounters();
093:
094: executeSPS(getAction());
095:
096: /*
097: For BEFORE ROW triggers, update the ai values after the SPS
098: has been executed. This way the SPS will see ai values from
099: the previous row.
100: */
101: if (event.isBefore())
102: tec.updateAICounters();
103: }
104: } finally {
105: clearSPS();
106: tec.clearTrigger();
107: }
108: }
109: }
|