KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.FKInfo
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.catalog.UUID;
25
26 import org.apache.derby.iapi.error.StandardException;
27
28 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
29
30 import org.apache.derby.iapi.types.RowLocation;
31
32 import org.apache.derby.iapi.services.monitor.Monitor;
33
34 import org.apache.derby.iapi.services.sanity.SanityManager;
35 import org.apache.derby.iapi.services.io.StoredFormatIds;
36 import org.apache.derby.iapi.services.io.FormatIdUtil;
37 import org.apache.derby.iapi.services.io.ArrayUtil;
38 import org.apache.derby.iapi.services.io.Formatable;
39
40 import java.io.StreamCorruptedException JavaDoc;
41 import java.io.ObjectOutput JavaDoc;
42 import java.io.ObjectInput JavaDoc;
43 import java.io.IOException JavaDoc;
44
45 import java.util.Vector JavaDoc;
46
47 /**
48  * This is a simple class used to store the run time information
49  * about a foreign key. Used by DML to figure out what to
50  * check.
51  *
52  * @author jamie
53  */

54 public class FKInfo implements Formatable
55 {
56     /********************************************************
57     **
58     ** This class implements Formatable. That means that it
59     ** can write itself to and from a formatted stream. If
60     ** you add more fields to this class, make sure that you
61     ** also write/read them with the writeExternal()/readExternal()
62     ** methods.
63     **
64     ** If, inbetween releases, you add more fields to this class,
65     ** then you should bump the version number emitted by the getTypeFormatId()
66     ** method. OR, since this is something that is used
67     ** in stored prepared statements, it is ok to change it
68     ** if you make sure that stored prepared statements are
69     ** invalidated across releases.
70     **
71     ********************************************************/

72
73     public static final int FOREIGN_KEY = 1;
74     public static final int REFERENCED_KEY = 2;
75
76     /*
77     ** See the constructor for the meaning of these fields
78     */

79     public String JavaDoc fkConstraintNames[];
80     public String JavaDoc tableName;
81     public int type;
82     public UUID refUUID;
83     public long refConglomNumber;
84     public UUID[] fkUUIDs;
85     public long[] fkConglomNumbers;
86     public boolean[] fkIsSelfReferencing;
87     public int[] colArray;
88     public int stmtType;
89     public RowLocation rowLocation;
90     public int[] raRules;
91
92     /**
93      * Niladic constructor for Formattable
94      */

95     public FKInfo() {}
96
97     /**
98      * Consructor for FKInfo
99      *
100      * @param fkConstraintNames the foreign key constraint names
101      * @param tableName the name of the table being modified
102      * @param stmtType the type of the statement: e.g. StatementType.INSERT
103      * @param type either FKInfo.REFERENCED_KEY or FKInfo.FOREIGN_KEY
104      * @param refUUID UUID of the referenced constraint
105      * @param refConglomNumber congomerate number of the referenced key
106      * @param fkUUIDs an array of fkUUIDs of backing indexes. if
107      * FOREIGN_KEY, then just one element, the backing
108      * index of the referrenced keys. if REFERENCED_KEY,
109      * then all the foreign keys
110      * @param fkConglomNumbers array of conglomerate numbers, corresponds
111      * to fkUUIDs
112      * @param fkIsSelfReferencing array of conglomerate booleans indicating
113      * whether the fk references a key in the same table
114      * @param colArray map of columns to the base row that DML
115      * is changing. 1 based. Note that this maps the
116      * constraint index to a row in the target table of
117      * the current dml operation.
118      * @param rowLocation a row location template for the target table
119      * used to pass in a template row to tc.openScan()
120      */

121     public FKInfo(
122                     String JavaDoc[] fkConstraintNames,
123                     String JavaDoc tableName,
124                     int stmtType,
125                     int type,
126                     UUID refUUID,
127                     long refConglomNumber,
128                     UUID[] fkUUIDs,
129                     long[] fkConglomNumbers,
130                     boolean[] fkIsSelfReferencing,
131                     int[] colArray,
132                     RowLocation rowLocation,
133                     int[] raRules
134                     )
135     {
136         this.fkConstraintNames = fkConstraintNames;
137         this.tableName = tableName;
138         this.stmtType = stmtType;
139         this.type = type;
140         this.refUUID = refUUID;
141         this.refConglomNumber = refConglomNumber;
142         this.fkUUIDs = fkUUIDs;
143         this.fkConglomNumbers = fkConglomNumbers;
144         this.fkIsSelfReferencing = fkIsSelfReferencing;
145         this.colArray = colArray;
146         this.rowLocation = rowLocation;
147         this.raRules = raRules;
148
149         if (SanityManager.DEBUG)
150         {
151             if (fkUUIDs.length != fkConglomNumbers.length)
152             {
153                 SanityManager.THROWASSERT("number of ForeignKey UUIDS ("+fkUUIDs.length+
154                                         ") doesn't match the number of conglomerate numbers"+
155                                         " ("+fkConglomNumbers.length+")");
156             }
157             if (type == FOREIGN_KEY)
158             {
159                 SanityManager.ASSERT(fkUUIDs.length == 1, "unexpected number of fkUUIDs for a foreign key, should only have the uuid of the key it references");
160             }
161             else if (type == REFERENCED_KEY)
162             {
163                 SanityManager.ASSERT(fkUUIDs.length >= 1, "too few fkUUIDs for a referenced key, expect at least one foreign key");
164             }
165             else
166             {
167                 SanityManager.THROWASSERT("bad type: "+type);
168             }
169         }
170     }
171
172     /**
173      * Comb through the FKInfo structures and pick out the
174      * ones that have columns that intersect with the input
175      * columns.
176      *
177      * @param fkInfo array of fkinfos
178      * @param cols array of columns
179      * @param addAllTypeIsFK take all with type == FORIEGN_KEY
180      *
181      * @return array of relevant fkinfos
182      */

183     public static FKInfo[] chooseRelevantFKInfos
184     (
185         FKInfo[] fkInfo,
186         int[] cols,
187         boolean addAllTypeIsFK)
188     {
189         if (fkInfo == null)
190         {
191             return (FKInfo[])null;
192         }
193
194         Vector JavaDoc newfksVector = new Vector JavaDoc();
195         FKInfo[] newfks = null;
196
197         /*
198         ** For each FKInfo
199         */

200         for (int i = 0; i < fkInfo.length; i++)
201         {
202             if (addAllTypeIsFK &&
203                 (fkInfo[i].type == FOREIGN_KEY))
204             {
205                 newfksVector.addElement(fkInfo[i]);
206                 continue;
207             }
208                 
209             int fkcollen = fkInfo[i].colArray.length;
210             for (int fkCols = 0; fkCols < fkcollen; fkCols++)
211             {
212                 for (int chcol = 0; chcol < cols.length; chcol++)
213                 {
214                     /*
215                     ** If any column intersects, the FKInfo is
216                     ** relevant.
217                     */

218                     if (fkInfo[i].colArray[fkCols] == cols[chcol])
219                     {
220                         newfksVector.addElement(fkInfo[i]);
221                         
222                         // go to the next fk
223
fkCols = fkcollen;
224                         break;
225                     }
226                 }
227             }
228         }
229
230         
231         /*
232         ** Now convert the vector into an array.
233         */

234         int size = newfksVector.size();
235         if (size > 0)
236         {
237             newfks = new FKInfo[size];
238             for (int i = 0; i < size; i++)
239             {
240                 newfks[i] = (FKInfo)newfksVector.elementAt(i);
241             }
242         }
243         return newfks;
244     }
245         
246     //////////////////////////////////////////////
247
//
248
// FORMATABLE
249
//
250
//////////////////////////////////////////////
251
/**
252      * Write this object out
253      *
254      * @param out write bytes here
255      *
256      * @exception IOException thrown on error
257      */

258     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
259     {
260         /*
261         ** Row locations cannot be written unless they
262         ** have a valid value. So we'll just write out
263         ** the format id, and create a new RowLocation
264         ** when we read it back in.
265         */

266         FormatIdUtil.writeFormatIdInteger(out, rowLocation.getTypeFormatId());
267
268         out.writeObject(tableName);
269         out.writeInt(type);
270         out.writeInt(stmtType);
271         out.writeObject(refUUID);
272         out.writeLong(refConglomNumber);
273
274         ArrayUtil.writeArray(out, fkConstraintNames);
275         ArrayUtil.writeArray(out, fkUUIDs);
276         ArrayUtil.writeLongArray(out, fkConglomNumbers);
277         ArrayUtil.writeBooleanArray(out, fkIsSelfReferencing);
278         ArrayUtil.writeIntArray(out, colArray);
279         ArrayUtil.writeIntArray(out, raRules);
280         
281     }
282
283     /**
284      * Read this object from a stream of stored objects.
285      *
286      * @param in read this.
287      *
288      * @exception IOException thrown on error
289      * @exception ClassNotFoundException thrown on error
290      */

291     public void readExternal(ObjectInput JavaDoc in)
292         throws IOException JavaDoc, ClassNotFoundException JavaDoc
293     {
294         try
295         {
296             /*
297             ** Create a new RowLocation from the format id.
298             */

299             int formatid = FormatIdUtil.readFormatIdInteger(in);
300             rowLocation = (RowLocation)Monitor.newInstanceFromIdentifier(formatid);
301             if (SanityManager.DEBUG)
302             {
303                 SanityManager.ASSERT(rowLocation != null, "row location is null in readExternal");
304             }
305
306             tableName = (String JavaDoc)in.readObject();
307             type = in.readInt();
308             stmtType = in.readInt();
309             refUUID = (UUID)in.readObject();
310             refConglomNumber = in.readLong();
311
312             fkConstraintNames = new String JavaDoc[ArrayUtil.readArrayLength(in)];
313             ArrayUtil.readArrayItems(in, fkConstraintNames);
314
315             fkUUIDs = new UUID[ArrayUtil.readArrayLength(in)];
316             ArrayUtil.readArrayItems(in, fkUUIDs);
317
318             fkConglomNumbers = ArrayUtil.readLongArray(in);
319             fkIsSelfReferencing = ArrayUtil.readBooleanArray(in);
320             colArray = ArrayUtil.readIntArray(in);
321             raRules = ArrayUtil.readIntArray(in);
322         }
323         catch (StandardException exception)
324         {
325             throw new StreamCorruptedException JavaDoc(exception.toString());
326         }
327     }
328     
329     /**
330      * Get the formatID which corresponds to this class.
331      *
332      * @return the formatID of this class
333      */

334     public int getTypeFormatId() { return StoredFormatIds.FK_INFO_V01_ID; }
335
336     //////////////////////////////////////////////////////////////
337
//
338
// Misc
339
//
340
//////////////////////////////////////////////////////////////
341
public String JavaDoc toString()
342     {
343         if (SanityManager.DEBUG)
344         {
345             StringBuffer JavaDoc str = new StringBuffer JavaDoc();
346             str.append("\nTableName:\t\t\t");
347             str.append(tableName);
348
349             str.append("\ntype:\t\t\t\t");
350             str.append((type == FOREIGN_KEY) ? "FOREIGN_KEY" : "REFERENCED_KEY");
351
352             str.append("\nReferenced Key UUID:\t\t"+refUUID);
353             str.append("\nReferenced Key ConglomNum:\t"+refConglomNumber);
354
355             str.append("\nForeign Key Names:\t\t(");
356             for (int i = 0; i < fkUUIDs.length; i++)
357             {
358                 if (i > 0)
359                     str.append(",");
360             
361                 str.append(fkConstraintNames[i]);
362             }
363             str.append(")");
364
365             str.append("\nForeign Key UUIDS:\t\t(");
366             for (int i = 0; i < fkUUIDs.length; i++)
367             {
368                 if (i > 0)
369                     str.append(",");
370             
371                 str.append(fkUUIDs[i]);
372             }
373             str.append(")");
374
375             str.append("\nForeign Key Conglom Nums:\t(");
376             for (int i = 0; i < fkConglomNumbers.length; i++)
377             {
378                 if (i > 0)
379                     str.append(",");
380             
381                 str.append(fkConglomNumbers[i]);
382             }
383             str.append(")");
384         
385             str.append("\nForeign Key isSelfRef:\t\t(");
386             for (int i = 0; i < fkIsSelfReferencing.length; i++)
387             {
388                 if (i > 0)
389                     str.append(",");
390             
391                 str.append(fkIsSelfReferencing[i]);
392             }
393             str.append(")");
394         
395             str.append("\ncolumn Array:\t\t\t(");
396             for (int i = 0; i < colArray.length; i++)
397             {
398                 if (i > 0)
399                     str.append(",");
400             
401                 str.append(colArray[i]);
402             }
403             str.append(")\n");
404
405             return str.toString();
406         }
407         else
408         {
409             return "";
410         }
411     }
412 }
413
Popular Tags