001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.execute.TriggerInfo
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.error.StandardException;
025:
026: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
027: import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList;
028: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
029: import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
030:
031: import org.apache.derby.iapi.services.monitor.Monitor;
032:
033: import org.apache.derby.iapi.services.sanity.SanityManager;
034: import org.apache.derby.iapi.services.io.StoredFormatIds;
035: import org.apache.derby.iapi.services.io.FormatIdUtil;
036: import org.apache.derby.iapi.services.io.ArrayUtil;
037: import org.apache.derby.iapi.services.io.Formatable;
038: import org.apache.derby.catalog.UUID;
039:
040: import java.io.ObjectOutput;
041: import java.io.ObjectInput;
042: import java.io.IOException;
043: import java.util.Enumeration;
044:
045: import java.util.Vector;
046:
047: /**
048: * This is a simple class used to store the run time information
049: * about a foreign key. Used by DML to figure out what to
050: * check.
051: *
052: * @author jamie
053: */
054: public final class TriggerInfo implements Formatable {
055: /********************************************************
056: **
057: ** This class implements Formatable. That means that it
058: ** can write itself to and from a formatted stream. If
059: ** you add more fields to this class, make sure that you
060: ** also write/read them with the writeExternal()/readExternal()
061: ** methods.
062: **
063: ** If, inbetween releases, you add more fields to this class,
064: ** then you should bump the version number emitted by the getTypeFormatId()
065: ** method. OR, since this is something that is used
066: ** in stored prepared statements, it is ok to change it
067: ** if you make sure that stored prepared statements are
068: ** invalidated across releases.
069: **
070: ********************************************************/
071:
072: TriggerDescriptor[] triggerArray;
073: String[] columnNames;
074: int[] columnIds;
075:
076: /**
077: * Niladic constructor for Formattable
078: */
079: public TriggerInfo() {
080: }
081:
082: /**
083: * Constructor for TriggerInfo
084: *
085: * @param td the table upon which the trigger is declared
086: * @param changedCols the columns that are changed in the dml that is
087: * causing the trigger to fire
088: * @param triggers the list of trigger descriptors
089: *
090: */
091: public TriggerInfo(TableDescriptor td, int[] changedCols,
092: GenericDescriptorList triggers) {
093: this .columnIds = changedCols;
094:
095: if (columnIds != null) {
096: /*
097: ** Find the names of all the columns that are
098: ** being changd.
099: */
100: columnNames = new String[columnIds.length];
101: for (int i = 0; i < columnIds.length; i++) {
102: columnNames[i] = td.getColumnDescriptor(columnIds[i])
103: .getColumnName();
104: }
105: }
106:
107: if (SanityManager.DEBUG) {
108: SanityManager.ASSERT(triggers != null,
109: "null trigger descriptor list");
110: SanityManager.ASSERT(triggers.size() > 0,
111: "trigger descriptor list has no elements");
112: }
113:
114: /*
115: ** Copy the trigger descriptors into an array of the right type
116: */
117: Enumeration descs = triggers.elements();
118:
119: int size = triggers.size();
120: triggerArray = new TriggerDescriptor[size];
121:
122: for (int i = 0; i < size; i++) {
123: triggerArray[i] = (TriggerDescriptor) descs.nextElement();
124: }
125: }
126:
127: /*
128: * private constructor for TriggerInfo
129: */
130: private TriggerInfo(TriggerDescriptor[] triggers,
131: int[] changedColsIds, String[] changedColsNames) {
132: this .columnIds = changedColsIds;
133: this .columnNames = changedColsNames;
134: this .triggerArray = triggers;
135: }
136:
137: /**
138: * Do we have a trigger or triggers that meet
139: * the criteria
140: *
141: * @param isBefore true for a before trigger, false
142: * for after trigger, null for either
143: * @param isRow true for a row trigger, false
144: * for statement trigger, null for either
145: *
146: * @return true if we have a trigger that meets the
147: * criteria
148: */
149: boolean hasTrigger(boolean isBefore, boolean isRow) {
150: if (triggerArray == null) {
151: return false;
152: }
153:
154: return hasTrigger(new Boolean(isBefore), new Boolean(isRow));
155: }
156:
157: /**
158: * Do we have a trigger or triggers that meet
159: * the criteria
160: *
161: * @param isBefore true for a before trigger, false
162: * for after trigger, null for either
163: * @param isRow true for a row trigger, false
164: * for statement trigger, null for either
165: *
166: * @return true if we have a trigger that meets the
167: * criteria
168: */
169: private boolean hasTrigger(Boolean isBefore, Boolean isRow) {
170: if (triggerArray == null) {
171: return false;
172: }
173: for (int i = 0; i < triggerArray.length; i++) {
174: if (((isBefore == null) || (triggerArray[i]
175: .isBeforeTrigger() == isBefore.booleanValue()))
176: && ((isRow == null) || (triggerArray[i]
177: .isRowTrigger() == isRow.booleanValue()))) {
178: return true;
179: }
180: }
181: return false;
182: }
183:
184: TriggerDescriptor[] getTriggerArray() {
185: return triggerArray;
186: }
187:
188: //////////////////////////////////////////////
189: //
190: // FORMATABLE
191: //
192: //////////////////////////////////////////////
193: /**
194: * Write this object out
195: *
196: * @param out write bytes here
197: *
198: * @exception IOException thrown on error
199: */
200: public void writeExternal(ObjectOutput out) throws IOException {
201: ArrayUtil.writeArray(out, triggerArray);
202: ArrayUtil.writeIntArray(out, columnIds);
203: ArrayUtil.writeArray(out, columnNames);
204: }
205:
206: /**
207: * Read this object from a stream of stored objects.
208: *
209: * @param in read this.
210: *
211: * @exception IOException thrown on error
212: * @exception ClassNotFoundException thrown on error
213: */
214: public void readExternal(ObjectInput in) throws IOException,
215: ClassNotFoundException {
216: triggerArray = new TriggerDescriptor[ArrayUtil
217: .readArrayLength(in)];
218: ArrayUtil.readArrayItems(in, triggerArray);
219:
220: columnIds = ArrayUtil.readIntArray(in);
221:
222: int len = ArrayUtil.readArrayLength(in);
223: if (len > 0) {
224: columnNames = new String[len];
225: ArrayUtil.readArrayItems(in, columnNames);
226: }
227: }
228:
229: /**
230: * Get the formatID which corresponds to this class.
231: *
232: * @return the formatID of this class
233: */
234: public int getTypeFormatId() {
235: return StoredFormatIds.TRIGGER_INFO_V01_ID;
236: }
237:
238: //////////////////////////////////////////////////////////////
239: //
240: // Misc
241: //
242: //////////////////////////////////////////////////////////////
243: public String toString() {
244: if (SanityManager.DEBUG) {
245: StringBuffer str = new StringBuffer();
246: str.append("\nColumn names modified:\t\t(");
247: for (int i = 0; i < columnNames.length; i++) {
248: if (i > 0)
249: str.append(",");
250:
251: str.append(columnNames[i]);
252: }
253: str.append(")");
254:
255: str.append("\nColumn ids modified:\t\t(");
256: for (int i = 0; i < columnIds.length; i++) {
257: if (i > 0)
258: str.append(",");
259:
260: str.append(columnIds[i]);
261: }
262: str.append(")");
263:
264: str.append("\nTriggers:");
265: for (int i = 0; i < triggerArray.length; i++) {
266: str.append("\n" + triggerArray[i]);
267: }
268: return str.toString();
269: } else {
270: return "";
271: }
272: }
273: }
|