001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.catalog.SYSFOREIGNKEYSRowFactory
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.catalog;
023:
024: import org.apache.derby.iapi.types.TypeId;
025: import org.apache.derby.iapi.sql.dictionary.SystemColumn;
026: import org.apache.derby.catalog.TypeDescriptor;
027:
028: import org.apache.derby.iapi.types.DataValueDescriptor;
029:
030: import org.apache.derby.iapi.types.DataValueFactory;
031: import org.apache.derby.iapi.types.RowLocation;
032:
033: import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
034: import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
035: import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
036: import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
037: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
038: import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
039: import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor;
040: import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor;
041: import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
042: import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
043: import org.apache.derby.iapi.sql.dictionary.SubKeyConstraintDescriptor;
044: import org.apache.derby.iapi.sql.StatementType;
045:
046: import org.apache.derby.iapi.sql.execute.ExecutionContext;
047: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
048: import org.apache.derby.iapi.sql.execute.ExecRow;
049: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
050:
051: import org.apache.derby.iapi.error.StandardException;
052:
053: import org.apache.derby.iapi.types.RowLocation;
054:
055: import org.apache.derby.iapi.services.sanity.SanityManager;
056:
057: import org.apache.derby.iapi.services.uuid.UUIDFactory;
058: import org.apache.derby.catalog.UUID;
059: import org.apache.derby.catalog.IndexDescriptor;
060:
061: /**
062: * Factory for creating a SYSFOREIGNKEYS row.
063: *
064: * @author jerry
065: */
066:
067: public class SYSFOREIGNKEYSRowFactory extends CatalogRowFactory {
068: private static final String TABLENAME_STRING = "SYSFOREIGNKEYS";
069:
070: protected static final int SYSFOREIGNKEYS_COLUMN_COUNT = 5;
071: protected static final int SYSFOREIGNKEYS_CONSTRAINTID = 1;
072: protected static final int SYSFOREIGNKEYS_CONGLOMERATEID = 2;
073: protected static final int SYSFOREIGNKEYS_KEYCONSTRAINTID = 3;
074: protected static final int SYSFOREIGNKEYS_DELETERULE = 4;
075: protected static final int SYSFOREIGNKEYS_UPDATERULE = 5;
076:
077: // Column widths
078: protected static final int SYSFOREIGNKEYS_CONSTRAINTID_WIDTH = 36;
079:
080: protected static final int SYSFOREIGNKEYS_INDEX1_ID = 0;
081: protected static final int SYSFOREIGNKEYS_INDEX2_ID = 1;
082:
083: private static final int[][] indexColumnPositions = {
084: { SYSFOREIGNKEYS_CONSTRAINTID },
085: { SYSFOREIGNKEYS_KEYCONSTRAINTID } };
086:
087: private static final boolean[] uniqueness = { true, false };
088:
089: private static final String[] uuids = {
090: "8000005b-00d0-fd77-3ed8-000a0a0b1900" // catalog UUID
091: , "80000060-00d0-fd77-3ed8-000a0a0b1900" // heap UUID
092: , "8000005d-00d0-fd77-3ed8-000a0a0b1900" // SYSFOREIGNKEYS_INDEX1
093: , "8000005f-00d0-fd77-3ed8-000a0a0b1900" // SYSFOREIGNKEYS_INDEX2
094: };
095:
096: /////////////////////////////////////////////////////////////////////////////
097: //
098: // CONSTRUCTORS
099: //
100: /////////////////////////////////////////////////////////////////////////////
101:
102: public SYSFOREIGNKEYSRowFactory(UUIDFactory uuidf,
103: ExecutionFactory ef, DataValueFactory dvf,
104: boolean convertIdToLower) {
105: super (uuidf, ef, dvf, convertIdToLower);
106: initInfo(SYSFOREIGNKEYS_COLUMN_COUNT, TABLENAME_STRING,
107: indexColumnPositions, uniqueness, uuids);
108: }
109:
110: /////////////////////////////////////////////////////////////////////////////
111: //
112: // METHODS
113: //
114: /////////////////////////////////////////////////////////////////////////////
115:
116: /**
117: * Make a SYSFOREIGNKEYS row
118: *
119: * @return Row suitable for inserting into SYSFOREIGNKEYS.
120: *
121: * @exception StandardException thrown on failure
122: */
123: public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
124: throws StandardException {
125: DataValueDescriptor col;
126: ExecIndexRow row;
127: String constraintId = null;
128: String keyConstraintId = null;
129: String conglomId = null;
130: String raDeleteRule = "N";
131: String raUpdateRule = "N";
132:
133: if (td != null) {
134: ForeignKeyConstraintDescriptor cd = (ForeignKeyConstraintDescriptor) td;
135: constraintId = cd.getUUID().toString();
136:
137: ReferencedKeyConstraintDescriptor refCd = cd
138: .getReferencedConstraint();
139: if (SanityManager.DEBUG) {
140: SanityManager.ASSERT(refCd != null,
141: "this fk returned a null referenced key");
142: }
143: keyConstraintId = refCd.getUUID().toString();
144: conglomId = cd.getIndexUUIDString();
145:
146: raDeleteRule = getRefActionAsString(cd.getRaDeleteRule());
147: raUpdateRule = getRefActionAsString(cd.getRaUpdateRule());
148: }
149:
150: /* Build the row */
151: row = getExecutionFactory().getIndexableRow(
152: SYSFOREIGNKEYS_COLUMN_COUNT);
153:
154: /* 1st column is CONSTRAINTID (UUID - char(36)) */
155: row.setColumn(SYSFOREIGNKEYS_CONSTRAINTID, dvf
156: .getCharDataValue(constraintId));
157:
158: /* 2nd column is CONGLOMERATEID (UUID - char(36)) */
159: row.setColumn(SYSFOREIGNKEYS_CONGLOMERATEID, dvf
160: .getCharDataValue(conglomId));
161:
162: /* 3rd column is KEYCONSTRAINTID (UUID - char(36)) */
163: row.setColumn(SYSFOREIGNKEYS_KEYCONSTRAINTID, dvf
164: .getCharDataValue(keyConstraintId));
165:
166: // currently, DELETERULE and UPDATERULE are always "R" for restrict
167: /* 4th column is DELETERULE char(1) */
168: row.setColumn(SYSFOREIGNKEYS_DELETERULE, dvf
169: .getCharDataValue(raDeleteRule));
170:
171: /* 5th column is UPDATERULE char(1) */
172: row.setColumn(SYSFOREIGNKEYS_UPDATERULE, dvf
173: .getCharDataValue(raUpdateRule));
174:
175: return row;
176: }
177:
178: ///////////////////////////////////////////////////////////////////////////
179: //
180: // ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
181: //
182: ///////////////////////////////////////////////////////////////////////////
183:
184: /**
185: * Make a ViewDescriptor out of a SYSFOREIGNKEYS row
186: *
187: * @param row a SYSFOREIGNKEYS row
188: * @param parentTupleDescriptor Null for this kind of descriptor.
189: * @param dd dataDictionary
190: *
191: * @exception StandardException thrown on failure
192: */
193: public TupleDescriptor buildDescriptor(ExecRow row,
194: TupleDescriptor parentTupleDescriptor, DataDictionary dd)
195: throws StandardException {
196:
197: if (SanityManager.DEBUG) {
198: SanityManager.ASSERT(
199: row.nColumns() == SYSFOREIGNKEYS_COLUMN_COUNT,
200: "Wrong number of columns for a SYSKEYS row");
201: }
202:
203: DataValueDescriptor col;
204: DataDescriptorGenerator ddg;
205: UUID constraintUUID;
206: UUID conglomerateUUID;
207: UUID keyConstraintUUID;
208: String constraintUUIDString;
209: String conglomerateUUIDString;
210: String raRuleString;
211: int raDeleteRule;
212: int raUpdateRule;
213:
214: ddg = dd.getDataDescriptorGenerator();
215:
216: /* 1st column is CONSTRAINTID (UUID - char(36)) */
217: col = row.getColumn(SYSFOREIGNKEYS_CONSTRAINTID);
218: constraintUUIDString = col.getString();
219: constraintUUID = getUUIDFactory().recreateUUID(
220: constraintUUIDString);
221:
222: /* 2nd column is CONGLOMERATEID (UUID - char(36)) */
223: col = row.getColumn(SYSFOREIGNKEYS_CONGLOMERATEID);
224: conglomerateUUIDString = col.getString();
225: conglomerateUUID = getUUIDFactory().recreateUUID(
226: conglomerateUUIDString);
227:
228: /* 3rd column is KEYCONSTRAINTID (UUID - char(36)) */
229: col = row.getColumn(SYSFOREIGNKEYS_KEYCONSTRAINTID);
230: constraintUUIDString = col.getString();
231: keyConstraintUUID = getUUIDFactory().recreateUUID(
232: constraintUUIDString);
233:
234: /* 4th column is DELETERULE char(1) */
235: col = row.getColumn(SYSFOREIGNKEYS_DELETERULE);
236: raRuleString = col.getString();
237: raDeleteRule = getRefActionAsInt(raRuleString);
238:
239: /* 5th column is UPDATERULE char(1) */
240: col = row.getColumn(SYSFOREIGNKEYS_UPDATERULE);
241: raRuleString = col.getString();
242: raUpdateRule = getRefActionAsInt(raRuleString);
243:
244: /* now build and return the descriptor */
245: return new SubKeyConstraintDescriptor(constraintUUID,
246: conglomerateUUID, keyConstraintUUID, raDeleteRule,
247: raUpdateRule);
248: }
249:
250: /**
251: * Builds a list of columns suitable for creating this Catalog.
252: *
253: *
254: * @return array of SystemColumn suitable for making this catalog.
255: */
256: public SystemColumn[] buildColumnList() {
257: int index = 0;
258: SystemColumn[] columnList = new SystemColumn[SYSFOREIGNKEYS_COLUMN_COUNT];
259:
260: // describe columns
261:
262: columnList[index++] = new SystemColumnImpl(
263: convertIdCase("CONSTRAINTID"), // name
264: SYSFOREIGNKEYS_CONSTRAINTID, // column number
265: 0, // precision
266: 0, // scale
267: false, // nullability
268: "CHAR", // dataType
269: true, // built-in type
270: 36 // maxLength
271: );
272: columnList[index++] = new SystemColumnImpl(
273: convertIdCase("CONGLOMERATEID"), // name
274: SYSFOREIGNKEYS_CONGLOMERATEID, // column number
275: 0, // precision
276: 0, // scale
277: false, // nullability
278: "CHAR", // dataType
279: true, // built-in type
280: 36 // maxLength
281: );
282: columnList[index++] = new SystemColumnImpl(
283: convertIdCase("KEYCONSTRAINTID"), // name
284: SYSFOREIGNKEYS_KEYCONSTRAINTID, // column number
285: 0, // precision
286: 0, // scale
287: false, // nullability
288: "CHAR", // dataType
289: true, // built-in type
290: 36 // maxLength
291: );
292:
293: columnList[index++] = new SystemColumnImpl(
294: convertIdCase("DELETERULE"), // name
295: SYSFOREIGNKEYS_DELETERULE, // column number
296: 0, // precision
297: 0, // scale
298: false, // nullability
299: "CHAR", // dataType
300: true, // built-in type
301: 1 // maxLength
302: );
303:
304: columnList[index++] = new SystemColumnImpl(
305: convertIdCase("UPDATERULE"), // name
306: SYSFOREIGNKEYS_UPDATERULE, // column number
307: 0, // precision
308: 0, // scale
309: false, // nullability
310: "CHAR", // dataType
311: true, // built-in type
312: 1 // maxLength
313: );
314: return columnList;
315: }
316:
317: int getRefActionAsInt(String raRuleString) {
318: int raRule;
319: switch (raRuleString.charAt(0)) {
320: case 'C':
321: raRule = StatementType.RA_CASCADE;
322: break;
323: case 'S':
324: raRule = StatementType.RA_RESTRICT;
325: break;
326: case 'R':
327: raRule = StatementType.RA_NOACTION;
328: break;
329: case 'U':
330: raRule = StatementType.RA_SETNULL;
331: break;
332: case 'D':
333: raRule = StatementType.RA_SETDEFAULT;
334: break;
335: default:
336: raRule = StatementType.RA_NOACTION;
337: ;
338: if (SanityManager.DEBUG) {
339: SanityManager.THROWASSERT("Invalid value '"
340: + raRuleString + "' for a referetial Action");
341: }
342: }
343: return raRule;
344: }
345:
346: String getRefActionAsString(int raRule) {
347: String raRuleString;
348: switch (raRule) {
349: case StatementType.RA_CASCADE:
350: raRuleString = "C";
351: break;
352: case StatementType.RA_RESTRICT:
353: raRuleString = "S";
354: break;
355: case StatementType.RA_NOACTION:
356: raRuleString = "R";
357: break;
358: case StatementType.RA_SETNULL:
359: raRuleString = "U";
360: break;
361: case StatementType.RA_SETDEFAULT:
362: raRuleString = "D";
363: raRule = StatementType.RA_SETDEFAULT;
364: break;
365: default:
366: raRuleString = "N"; // NO ACTION (default value)
367: if (SanityManager.DEBUG) {
368: SanityManager.THROWASSERT("Invalid value '" + raRule
369: + "' for a referetial Action");
370: }
371:
372: }
373: return raRuleString;
374: }
375:
376: }
|