KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > execute > TriggerEventActivator


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.TriggerEventActivator
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.execute;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25 import org.apache.derby.iapi.error.StandardException;
26
27 import org.apache.derby.iapi.sql.execute.CursorResultSet;
28 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
29 import org.apache.derby.iapi.sql.execute.ExecRow;
30 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
31 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
32
33 import org.apache.derby.iapi.sql.Activation;
34
35 import org.apache.derby.iapi.store.access.TransactionController;
36 import org.apache.derby.impl.sql.execute.AutoincrementCounter;
37 import org.apache.derby.iapi.reference.SQLState;
38 import org.apache.derby.iapi.jdbc.ConnectionContext;
39 import org.apache.derby.catalog.UUID;
40
41 import java.util.Vector JavaDoc;
42 import java.sql.SQLException JavaDoc;
43
44 /**
45  * Responsible for firing a trigger or set of triggers
46  * based on an event.
47  */

48 public class TriggerEventActivator
49 {
50     private LanguageConnectionContext lcc;
51     private TransactionController tc;
52     private TriggerInfo triggerInfo;
53     private InternalTriggerExecutionContext tec;
54     private GenericTriggerExecutor[][] executors;
55     private Activation activation;
56     private ConnectionContext cc;
57     private String JavaDoc statementText;
58     private int dmlType;
59     private UUID tableId;
60     private String JavaDoc tableName;
61     private Vector JavaDoc aiCounters;
62
63     /**
64      * Basic constructor
65      *
66      * @param lcc the lcc
67      * @param tc the xact controller
68      * @param triggerInfo the trigger information
69      * @param dmlType Type of DML for which this trigger is being fired.
70      * @param activation the activation.
71      * @param aiCounters vector of ai counters
72      *
73      * @exception StandardException on error
74      */

75     public TriggerEventActivator
76     (
77         LanguageConnectionContext lcc,
78         TransactionController tc,
79         UUID tableId,
80         TriggerInfo triggerInfo,
81         int dmlType,
82         Activation activation,
83         Vector JavaDoc aiCounters
84     ) throws StandardException
85     {
86         if (triggerInfo == null)
87         {
88             return;
89         }
90
91         // extrapolate the table name from the triggerdescriptors
92
tableName = triggerInfo.triggerArray[0].getTableDescriptor().getQualifiedName();
93     
94         this.lcc = lcc;
95         this.tc = tc;
96         this.activation = activation;
97         this.tableId = tableId;
98         this.dmlType = dmlType;
99         this.triggerInfo = triggerInfo;
100
101         cc = (ConnectionContext)lcc.getContextManager().
102                                     getContext(ConnectionContext.CONTEXT_ID);
103
104         this.statementText = lcc.getStatementContext().getStatementText();
105
106         this.tec = ((GenericExecutionFactory)lcc.getLanguageConnectionFactory().getExecutionFactory()).
107                         getTriggerExecutionContext(
108                                 lcc,
109                                 cc,
110                                 statementText,
111                                 dmlType,
112                                 triggerInfo.columnIds,
113                                 triggerInfo.columnNames,
114                                 tableId,
115                                 tableName, aiCounters
116                                 );
117
118         setupExecutors(triggerInfo);
119     }
120
121     /**
122      * Reopen the trigger activator. Just creates a new trigger execution
123      * context. Note that close() still must be called when you
124      * are done -- you cannot just do a reopen() w/o a first doing
125      * a close.
126      *
127      * @exception StandardException on error
128      */

129     void reopen() throws StandardException
130     {
131         this.tec = ((GenericExecutionFactory)lcc.getLanguageConnectionFactory().getExecutionFactory()).
132                         getTriggerExecutionContext(
133                                 lcc,
134                                 cc,
135                                 statementText,
136                                 dmlType,
137                                 triggerInfo.columnIds,
138                                 triggerInfo.columnNames,
139                                 tableId,
140                                 tableName, aiCounters
141                                 );
142         setupExecutors(triggerInfo);
143     }
144
145     private void setupExecutors(TriggerInfo triggerInfo) throws StandardException
146     {
147         executors = new GenericTriggerExecutor[TriggerEvent.MAX_EVENTS][];
148         Vector JavaDoc[] executorLists = new Vector JavaDoc[TriggerEvent.MAX_EVENTS];
149         for (int i = 0; i < TriggerEvent.MAX_EVENTS; i++)
150         {
151             executorLists[i] = new Vector JavaDoc();
152         }
153
154         for (int i = 0; i < triggerInfo.triggerArray.length; i++)
155         {
156             TriggerDescriptor td = triggerInfo.triggerArray[i];
157             switch (td.getTriggerEventMask())
158             {
159                 case TriggerDescriptor.TRIGGER_EVENT_INSERT:
160                     if (td.isBeforeTrigger())
161                     {
162                         executorLists[TriggerEvent.BEFORE_INSERT].addElement(td);
163                     }
164                     else
165                     {
166                         executorLists[TriggerEvent.AFTER_INSERT].addElement(td);
167                     }
168                     break;
169
170
171                 case TriggerDescriptor.TRIGGER_EVENT_DELETE:
172                     if (td.isBeforeTrigger())
173                     {
174                         executorLists[TriggerEvent.BEFORE_DELETE].addElement(td);
175                     }
176                     else
177                     {
178                         executorLists[TriggerEvent.AFTER_DELETE].addElement(td);
179                     }
180                     break;
181
182                 case TriggerDescriptor.TRIGGER_EVENT_UPDATE:
183                     if (td.isBeforeTrigger())
184                     {
185                         executorLists[TriggerEvent.BEFORE_UPDATE].addElement(td);
186                     }
187                     else
188                     {
189                         executorLists[TriggerEvent.AFTER_UPDATE].addElement(td);
190                     }
191                     break;
192                 default:
193                     if (SanityManager.DEBUG)
194                     {
195                         SanityManager.THROWASSERT("bad trigger event "+td.getTriggerEventMask());
196                     }
197             }
198         }
199
200         for (int i = 0; i < executorLists.length; i++)
201         {
202             int size = executorLists[i].size();
203             if (size > 0)
204             {
205                 executors[i] = new GenericTriggerExecutor[size];
206                 for (int j = 0; j < size; j++)
207                 {
208                     TriggerDescriptor td = (TriggerDescriptor)executorLists[i].elementAt(j);
209                     executors[i][j] = (td.isRowTrigger()) ?
210                                 (GenericTriggerExecutor)new RowTriggerExecutor(tec, td, activation, lcc) :
211                                 (GenericTriggerExecutor)new StatementTriggerExecutor(tec, td, activation, lcc);
212                 }
213             }
214         }
215     }
216
217     /**
218      * Handle the given event.
219      *
220      * @param event a trigger event
221      * @param brs the before result set. Typically
222      * a TemporaryRowHolderResultSet but sometimes a
223      * BulkTableScanResultSet
224      * @param ars the after result set. Typically
225      * a TemporaryRowHolderResultSet but sometimes a
226      * BulkTableScanResultSet
227      *
228      * @exception StandardException on error
229      */

230     public void notifyEvent
231     (
232         TriggerEvent event,
233         CursorResultSet brs,
234         CursorResultSet ars
235     ) throws StandardException
236     {
237         if (executors == null)
238         {
239             return;
240         }
241
242         int eventNumber = event.getNumber();
243         if (executors[eventNumber] == null)
244         {
245             return;
246         }
247
248         tec.setCurrentTriggerEvent(event);
249         try
250         {
251             if (brs != null)
252             {
253                 brs.open();
254             }
255             if (ars != null)
256             {
257                 ars.open();
258             }
259
260             lcc.pushExecutionStmtValidator(tec);
261             for (int i = 0; i < executors[eventNumber].length; i++)
262             {
263                 if (i > 0)
264                 {
265                     
266                     if (brs != null)
267                     {
268                         ((NoPutResultSet)brs).reopenCore();
269                     }
270                     if (ars != null)
271                     {
272                         ((NoPutResultSet)ars).reopenCore();
273                     }
274                 }
275                 // Reset the AI counters to the beginning before firing next
276
// trigger.
277
tec.resetAICounters(true);
278                 executors[eventNumber][i].fireTrigger(event, brs, ars);
279             }
280         }
281         finally
282         {
283             lcc.popExecutionStmtValidator(tec);
284             tec.clearCurrentTriggerEvent();
285         }
286     }
287     
288     /**
289      * Clean up and release resources.
290      *
291      * @exception StandardException on unexpected error
292      */

293     public void cleanup() throws StandardException
294     {
295         if (tec != null)
296         {
297             tec.cleanup();
298         }
299     }
300 }
301
Popular Tags