KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > sql > dictionary > ReferencedKeyConstraintDescriptor


1 /*
2
3    Derby - Class org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor
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.iapi.sql.dictionary;
23
24 import org.apache.derby.iapi.error.StandardException;
25
26 import org.apache.derby.iapi.reference.SQLState;
27 import org.apache.derby.iapi.services.sanity.SanityManager;
28 import org.apache.derby.iapi.sql.StatementType;
29 import org.apache.derby.iapi.services.io.StoredFormatIds;
30 import org.apache.derby.catalog.UUID;
31 /**
32  * A ReferencedConstraintDeescriptor is a primary key or a unique
33  * key that is referenced by a foreign key.
34  *
35  * @author Jamie
36  */

37 public class ReferencedKeyConstraintDescriptor extends KeyConstraintDescriptor
38 {
39     /**
40        public interface to this descriptor:
41        <ol>
42        <li>public boolean hasSelfReferencingFK(ConstraintDescriptorList cdl, int type)
43         throws StandardException;</li>
44         <li>public ConstraintDescriptorList getForeignKeyConstraints(int type) throws StandardException;</li>
45         <li>public boolean isReferenced();</li>
46         <li>public int getReferenceCount();</li>
47         <li>public int incrementReferenceCount();</li>
48         <li>public int decrementReferenceCount();</li>
49         </ol>
50     */

51
52     //Implementation
53
private final int constraintType;
54
55     int referenceCount;
56
57     // enabled foreign keys
58
private ConstraintDescriptorList fkEnabledConstraintList;
59     // all foreign keys
60
private ConstraintDescriptorList fkConstraintList;
61
62     private boolean checkedSelfReferencing;
63     private boolean hasSelfReferencing;
64
65     /**
66      * Constructor for a KeyConstraintDescriptorImpl
67      *
68      * @param constraintType The type of the constraint
69      * @param dataDictionary The data dictionary that this descriptor lives in
70      * @param table The descriptor of the table the constraint is on
71      * @param constraintName The name of the constraint.
72      * @param deferrable If the constraint can be deferred.
73      * @param initiallyDeferred If the constraint starts life deferred.
74      * @param columns columns involved in the constraint
75      * @param constraintId UUID of constraint
76      * @param indexId The UUID for the backing index
77      * @param schemaDesc The SchemaDescriptor for the constraint
78      * @param isEnabled is the constraint enabled?
79      * @param referenceCount number of FKs (enabled only)
80      */

81     protected ReferencedKeyConstraintDescriptor(int constraintType,
82             DataDictionary dataDictionary,
83             TableDescriptor table,
84             String JavaDoc constraintName,
85             boolean deferrable,
86             boolean initiallyDeferred,
87             int[] columns,
88             UUID constraintId,
89             UUID indexId,
90             SchemaDescriptor schemaDesc,
91             boolean isEnabled,
92             int referenceCount
93             )
94     {
95         super(dataDictionary, table, constraintName, deferrable,
96               initiallyDeferred, columns,
97               constraintId, indexId, schemaDesc, isEnabled);
98         this.referenceCount = referenceCount;
99         this.constraintType = constraintType;
100     }
101
102     public final int getConstraintType() {
103         return constraintType;
104     }
105
106     /**
107      * Am I referenced by a FK on the same table?
108      *
109      * @param cdl ConstraintDescriptorList for the table
110      * @param type ConstraintDescriptor.(ENABLED|DISABLED|ALL)
111      *
112      * @return true/false
113      *
114      * @exception StandardException on error
115      */

116     public boolean hasSelfReferencingFK(ConstraintDescriptorList cdl, int type)
117         throws StandardException
118     {
119         if (SanityManager.DEBUG)
120         {
121             checkType(type);
122         }
123     
124         if (checkedSelfReferencing)
125         {
126             return hasSelfReferencing;
127         }
128     
129         ConstraintDescriptor cd;
130         ForeignKeyConstraintDescriptor fkcd;
131         /* Get a full list of referencing keys, if caller
132          * passed in null CDL.
133          */

134         if (cdl == null)
135         {
136             cdl = getForeignKeyConstraints(type);
137         }
138         int cdlSize = cdl.size();
139
140         for (int index = 0; index < cdlSize; index++)
141         {
142             cd = (ConstraintDescriptor) cdl.elementAt(index);
143             if (! (cd instanceof ForeignKeyConstraintDescriptor))
144             {
145                 continue;
146             }
147
148             fkcd = (ForeignKeyConstraintDescriptor) cd;
149             if (fkcd.getReferencedConstraintId().equals(getUUID()))
150             {
151                 hasSelfReferencing = true;
152                 break;
153             }
154         }
155         return hasSelfReferencing;
156     }
157
158
159     /**
160      * Am I referenced by a FK on another table?
161      * @param type ConstraintDescriptor.(ENABLED|DISABLED|ALL)
162      * @return true/false
163      * @exception StandardException on error
164      */

165     public boolean hasNonSelfReferencingFK(int type)
166         throws StandardException
167     {
168
169         boolean hasNonSelfReferenceFk = false;
170
171         if (SanityManager.DEBUG)
172         {
173             checkType(type);
174         }
175     
176         ConstraintDescriptor cd;
177         ForeignKeyConstraintDescriptor fkcd;
178         // Get a full list of referencing keys,
179
ConstraintDescriptorList cdl = getForeignKeyConstraints(type);
180         int cdlSize = cdl.size();
181
182         for (int index = 0; index < cdlSize; index++)
183         {
184             cd = (ConstraintDescriptor) cdl.elementAt(index);
185             if (! (cd instanceof ForeignKeyConstraintDescriptor))
186             {
187                 continue;
188             }
189
190             fkcd = (ForeignKeyConstraintDescriptor) cd;
191             if(!(fkcd.getTableId().equals(getTableId())))
192             {
193                 hasNonSelfReferenceFk = true;
194                 break;
195             }
196         }
197         return hasNonSelfReferenceFk;
198     }
199
200
201
202     /**
203      * Get the referencing foreign key constraints
204      *
205      * @param type ConstraintDescriptor.(ENABLED|DISABLED|ALL)
206      *
207      * @return the list of constraints (ConstraintDescriptorListImpl)
208      *
209      * @exception StandardException on error
210      */

211     public ConstraintDescriptorList getForeignKeyConstraints(int type)
212         throws StandardException
213     {
214         if (SanityManager.DEBUG)
215         {
216             checkType(type);
217         }
218
219         // optimized for this case
220
if (type == ENABLED)
221         {
222             // optimization to avoid any lookups if we know we
223
// aren't referenced.
224
if (!isReferenced())
225             {
226                 return new ConstraintDescriptorList();
227             }
228             else if (fkEnabledConstraintList != null)
229             {
230                 return fkEnabledConstraintList;
231             }
232             else if (fkConstraintList == null)
233             {
234                 fkConstraintList = getDataDictionary().getForeignKeys(constraintId);
235             }
236             fkEnabledConstraintList = fkConstraintList.getConstraintDescriptorList(true);
237             return fkEnabledConstraintList;
238         }
239
240         // not optimized for this case
241
else if (type == DISABLED)
242         {
243             if (fkConstraintList == null)
244             {
245                 fkConstraintList = getDataDictionary().getForeignKeys(constraintId);
246             }
247             return fkConstraintList.getConstraintDescriptorList(false);
248         }
249         else
250         {
251             if (fkConstraintList == null)
252             {
253                 fkConstraintList = getDataDictionary().getForeignKeys(constraintId);
254             }
255             return fkConstraintList;
256         }
257     }
258         
259     /**
260      * Is this constraint referenced? Returns
261      * true if there are enabled fks that
262      * reference this constraint.
263      *
264      * @return false
265      */

266     public boolean isReferenced()
267     {
268         return referenceCount != 0;
269     }
270
271     /**
272      * Get the number of enabled fks that
273      * reference this key.
274      *
275      * @return the number of fks
276      */

277     public int getReferenceCount()
278     {
279         return referenceCount;
280     }
281
282     /**
283      * Bump the reference count by one.
284      *
285      * @return the number of fks
286      */

287     public int incrementReferenceCount()
288     {
289         return referenceCount++;
290     }
291
292     /**
293      * Decrement the reference count by one.
294      *
295      * @return the number of fks
296      */

297     public int decrementReferenceCount()
298     {
299         return referenceCount--;
300     }
301
302     /**
303      * Does this constraint need to fire on this type of
304      * DML? For referenced keys, fire if referenced by
305      * a fk, and stmt is delete or bulk insert replace,
306      * or stmt is update and columns intersect.
307      *
308      * @param stmtType the type of DML
309      * (StatementType.INSERT|StatementType.UPDATE|StatementType.DELETE)
310      * @param modifiedCols the columns modified, or null for all
311      *
312      * @return true/false
313      */

314     public boolean needsToFire(int stmtType, int[] modifiedCols)
315     {
316         /*
317         ** If we are disabled, we never fire
318         */

319         if (!isEnabled)
320         {
321             return false;
322         }
323
324         if (!isReferenced() ||
325             (stmtType == StatementType.INSERT))
326         {
327             return false;
328         }
329
330         if (stmtType == StatementType.DELETE ||
331             stmtType == StatementType.BULK_INSERT_REPLACE)
332         {
333             return true;
334         }
335
336         // if update, only relevant if columns intersect
337
return doColumnsIntersect(modifiedCols, getReferencedColumns());
338     }
339
340     private void checkType(int type) throws StandardException
341     {
342         if (SanityManager.DEBUG)
343         {
344             switch (type)
345             {
346               case ENABLED:
347               case DISABLED:
348               case ALL:
349                 break;
350               default:
351                 SanityManager.THROWASSERT("constraint type "+type+" is invalid");
352             }
353         }
354     }
355         
356 }
357
Popular Tags