001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.catalog.SYSTABLESRowFactory
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.DataValueDescriptor;
025:
026: import org.apache.derby.iapi.sql.dictionary.SystemColumn;
027:
028: import org.apache.derby.iapi.types.DataValueFactory;
029: import org.apache.derby.iapi.types.RowLocation;
030:
031: import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
032: import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
033: import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
034: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
035:
036: import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
037: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
038:
039: import org.apache.derby.iapi.services.sanity.SanityManager;
040:
041: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
042: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
043: import org.apache.derby.iapi.sql.execute.ExecRow;
044:
045: import org.apache.derby.iapi.error.StandardException;
046:
047: import org.apache.derby.catalog.UUID;
048: import org.apache.derby.iapi.services.uuid.UUIDFactory;
049:
050: /**
051: * Factory for creating a SYSTABLES row.
052: *
053: *
054: * @version 0.1
055: * @author Rick Hillegas (extracted from DataDictionaryImpl).
056: */
057:
058: class SYSTABLESRowFactory extends CatalogRowFactory {
059: private static final String TABLENAME_STRING = "SYSTABLES";
060:
061: protected static final int SYSTABLES_COLUMN_COUNT = 5;
062: /* Column #s for systables (1 based) */
063: protected static final int SYSTABLES_TABLEID = 1;
064: protected static final int SYSTABLES_TABLENAME = 2;
065: protected static final int SYSTABLES_TABLETYPE = 3;
066: protected static final int SYSTABLES_SCHEMAID = 4;
067: protected static final int SYSTABLES_LOCKGRANULARITY = 5;
068:
069: protected static final int SYSTABLES_INDEX1_ID = 0;
070: protected static final int SYSTABLES_INDEX1_TABLENAME = 1;
071: protected static final int SYSTABLES_INDEX1_SCHEMAID = 2;
072:
073: protected static final int SYSTABLES_INDEX2_ID = 1;
074: protected static final int SYSTABLES_INDEX2_TABLEID = 1;
075:
076: // all indexes are unique.
077:
078: private static final String[] uuids = {
079: "80000018-00d0-fd77-3ed8-000a0a0b1900" // catalog UUID
080: , "80000028-00d0-fd77-3ed8-000a0a0b1900" // heap UUID
081: , "8000001a-00d0-fd77-3ed8-000a0a0b1900" // SYSTABLES_INDEX1
082: , "8000001c-00d0-fd77-3ed8-000a0a0b1900" // SYSTABLES_INDEX2
083: };
084:
085: private static final int[][] indexColumnPositions = {
086: { SYSTABLES_TABLENAME, SYSTABLES_SCHEMAID },
087: { SYSTABLES_TABLEID } };
088:
089: /////////////////////////////////////////////////////////////////////////////
090: //
091: // CONSTRUCTORS
092: //
093: /////////////////////////////////////////////////////////////////////////////
094:
095: SYSTABLESRowFactory(UUIDFactory uuidf, ExecutionFactory ef,
096: DataValueFactory dvf, boolean convertIdToLower) {
097: super (uuidf, ef, dvf, convertIdToLower);
098: initInfo(SYSTABLES_COLUMN_COUNT, TABLENAME_STRING,
099: indexColumnPositions, (boolean[]) null, uuids);
100: }
101:
102: /////////////////////////////////////////////////////////////////////////////
103: //
104: // METHODS
105: //
106: /////////////////////////////////////////////////////////////////////////////
107:
108: /**
109: * Make a SYSTABLES row
110: *
111: * @return Row suitable for inserting into SYSTABLES.
112: *
113: * @exception StandardException thrown on failure
114: */
115:
116: public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
117: throws StandardException {
118: UUID oid;
119: String tabSType = null;
120: int tabIType;
121: ExecRow row;
122: String lockGranularity = null;
123: String tableID = null;
124: String schemaID = null;
125: String tableName = null;
126:
127: if (td != null) {
128: /*
129: ** We only allocate a new UUID if the descriptor doesn't already have one.
130: ** For descriptors replicated from a Source system, we already have an UUID.
131: */
132: TableDescriptor descriptor = (TableDescriptor) td;
133: SchemaDescriptor schema = (SchemaDescriptor) parent;
134:
135: oid = descriptor.getUUID();
136: if (oid == null) {
137: oid = getUUIDFactory().createUUID();
138: descriptor.setUUID(oid);
139: }
140: tableID = oid.toString();
141:
142: if (SanityManager.DEBUG) {
143: SanityManager
144: .ASSERT(schema != null,
145: "Schema should not be null unless empty row is true");
146: if (schema.getUUID() == null) {
147: SanityManager.THROWASSERT("schema " + schema
148: + " has a null OID");
149: }
150: }
151:
152: schemaID = schema.getUUID().toString();
153:
154: tableName = descriptor.getName();
155:
156: /* RESOLVE - Table Type should really be a char in the descriptor
157: * T, S, V, S instead of 0, 1, 2, 3
158: */
159: tabIType = descriptor.getTableType();
160: switch (tabIType) {
161: case TableDescriptor.BASE_TABLE_TYPE:
162: tabSType = "T";
163: break;
164: case TableDescriptor.SYSTEM_TABLE_TYPE:
165: tabSType = "S";
166: break;
167: case TableDescriptor.VIEW_TYPE:
168: tabSType = "V";
169: break;
170:
171: case TableDescriptor.SYNONYM_TYPE:
172: tabSType = "A";
173: break;
174:
175: default:
176: if (SanityManager.DEBUG)
177: SanityManager.THROWASSERT("invalid table type");
178: }
179: char[] lockGChar = new char[1];
180: lockGChar[0] = descriptor.getLockGranularity();
181: lockGranularity = new String(lockGChar);
182: }
183:
184: /* Insert info into systables */
185:
186: /* RESOLVE - It would be nice to require less knowledge about systables
187: * and have this be more table driven.
188: */
189:
190: /* Build the row to insert */
191: row = getExecutionFactory().getValueRow(SYSTABLES_COLUMN_COUNT);
192:
193: /* 1st column is TABLEID (UUID - char(36)) */
194: row.setColumn(SYSTABLES_TABLEID, dvf.getCharDataValue(tableID));
195:
196: /* 2nd column is NAME (varchar(30)) */
197: row.setColumn(SYSTABLES_TABLENAME, dvf
198: .getVarcharDataValue(tableName));
199:
200: /* 3rd column is TABLETYPE (char(1)) */
201: row.setColumn(SYSTABLES_TABLETYPE, dvf
202: .getCharDataValue(tabSType));
203:
204: /* 4th column is SCHEMAID (UUID - char(36)) */
205: row.setColumn(SYSTABLES_SCHEMAID, dvf
206: .getCharDataValue(schemaID));
207:
208: /* 5th column is LOCKGRANULARITY (char(1)) */
209: row.setColumn(SYSTABLES_LOCKGRANULARITY, dvf
210: .getCharDataValue(lockGranularity));
211:
212: return row;
213: }
214:
215: /**
216: * Builds an empty index row.
217: *
218: * @param indexNumber Index to build empty row for.
219: * @param rowLocation Row location for last column of index row
220: *
221: * @return corresponding empty index row
222: * @exception StandardException thrown on failure
223: */
224: ExecIndexRow buildEmptyIndexRow(int indexNumber,
225: RowLocation rowLocation) throws StandardException {
226: int ncols = getIndexColumnCount(indexNumber);
227: ExecIndexRow row = getExecutionFactory().getIndexableRow(
228: ncols + 1);
229:
230: row.setColumn(ncols + 1, rowLocation);
231:
232: switch (indexNumber) {
233: case SYSTABLES_INDEX1_ID:
234: /* 1st column is TABLENAME (varchar(128)) */
235: row.setColumn(1, getDataValueFactory().getVarcharDataValue(
236: (String) null));
237:
238: /* 2nd column is SCHEMAID (UUID - char(36)) */
239: row.setColumn(2, getDataValueFactory().getCharDataValue(
240: (String) null));
241:
242: break;
243:
244: case SYSTABLES_INDEX2_ID:
245: /* 1st column is TABLEID (UUID - char(36)) */
246: row.setColumn(1, getDataValueFactory().getCharDataValue(
247: (String) null));
248: break;
249: } // end switch
250:
251: return row;
252: }
253:
254: ///////////////////////////////////////////////////////////////////////////
255: //
256: // ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN OF CatalogRowFactory
257: //
258: ///////////////////////////////////////////////////////////////////////////
259:
260: /**
261: * Make a TableDescriptor out of a SYSTABLES row
262: *
263: * @param row a SYSTABLES row
264: * @param parentTupleDescriptor Null for this kind of descriptor.
265: * @param dd dataDictionary
266: *
267: * @return a table descriptor equivalent to a SYSTABLES row
268: *
269: * @exception StandardException thrown on failure
270: */
271:
272: public TupleDescriptor buildDescriptor(ExecRow row,
273: TupleDescriptor parentTupleDescriptor, DataDictionary dd)
274: throws StandardException {
275: if (SanityManager.DEBUG)
276: SanityManager.ASSERT(
277: row.nColumns() == SYSTABLES_COLUMN_COUNT,
278: "Wrong number of columns for a SYSTABLES row");
279:
280: DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
281:
282: String tableUUIDString;
283: String schemaUUIDString;
284: int tableTypeEnum;
285: String lockGranularity;
286: String tableName, tableType;
287: DataValueDescriptor col;
288: UUID tableUUID;
289: UUID schemaUUID;
290: SchemaDescriptor schema;
291: TableDescriptor tabDesc;
292:
293: /* 1st column is TABLEID (UUID - char(36)) */
294: col = row.getColumn(SYSTABLES_TABLEID);
295: tableUUIDString = col.getString();
296: tableUUID = getUUIDFactory().recreateUUID(tableUUIDString);
297:
298: /* 2nd column is TABLENAME (varchar(128)) */
299: col = row.getColumn(SYSTABLES_TABLENAME);
300: tableName = col.getString();
301:
302: /* 3rd column is TABLETYPE (char(1)) */
303: col = row.getColumn(SYSTABLES_TABLETYPE);
304: tableType = col.getString();
305: if (SanityManager.DEBUG) {
306: SanityManager.ASSERT(tableType.length() == 1,
307: "Fourth column type incorrect");
308: }
309: switch (tableType.charAt(0)) {
310: case 'T':
311: tableTypeEnum = TableDescriptor.BASE_TABLE_TYPE;
312: break;
313: case 'S':
314: tableTypeEnum = TableDescriptor.SYSTEM_TABLE_TYPE;
315: break;
316: case 'V':
317: tableTypeEnum = TableDescriptor.VIEW_TYPE;
318: break;
319: case 'A':
320: tableTypeEnum = TableDescriptor.SYNONYM_TYPE;
321: break;
322: default:
323: if (SanityManager.DEBUG)
324: SanityManager
325: .THROWASSERT("Fourth column value invalid");
326: tableTypeEnum = -1;
327: }
328:
329: /* 4th column is SCHEMAID (UUID - char(36)) */
330: col = row.getColumn(SYSTABLES_SCHEMAID);
331: schemaUUIDString = col.getString();
332: schemaUUID = getUUIDFactory().recreateUUID(schemaUUIDString);
333:
334: schema = dd.getSchemaDescriptor(schemaUUID, null);
335:
336: /* 5th column is LOCKGRANULARITY (char(1)) */
337: col = row.getColumn(SYSTABLES_LOCKGRANULARITY);
338: lockGranularity = col.getString();
339: if (SanityManager.DEBUG) {
340: SanityManager.ASSERT(lockGranularity.length() == 1,
341: "Fifth column type incorrect");
342: }
343:
344: // RESOLVE - Deal with lock granularity
345: tabDesc = ddg.newTableDescriptor(tableName, schema,
346: tableTypeEnum, lockGranularity.charAt(0));
347: tabDesc.setUUID(tableUUID);
348: return tabDesc;
349: }
350:
351: /**
352: * Get the table name out of this SYSTABLES row
353: *
354: * @param row a SYSTABLES row
355: *
356: * @return string, the table name
357: *
358: * @exception StandardException thrown on failure
359: */
360: protected String getTableName(ExecRow row) throws StandardException {
361: DataValueDescriptor col;
362:
363: col = row.getColumn(SYSTABLES_TABLENAME);
364: return col.getString();
365: }
366:
367: /**
368: * Builds a list of columns suitable for creating this Catalog.
369: *
370: *
371: * @return array of SystemColumn suitable for making this catalog.
372: */
373: public SystemColumn[] buildColumnList() {
374: SystemColumn[] columnList = new SystemColumn[SYSTABLES_COLUMN_COUNT];
375:
376: // describe columns
377:
378: columnList[0] = new SystemColumnImpl(convertIdCase("TABLEID"), // column name
379: SYSTABLES_TABLEID, // column number
380: 0, // precision
381: 0, // scale
382: false, // nullability
383: "CHAR", // dataType
384: true, // built-in type
385: 36 // maxLength
386: );
387:
388: columnList[1] = new SystemColumnImpl( // SQLIDENTIFIER
389: convertIdCase("TABLENAME"), // column name
390: SYSTABLES_TABLENAME, // column number
391: false // nullability
392: );
393:
394: columnList[2] = new SystemColumnImpl(
395: convertIdCase("TABLETYPE"), // column name
396: SYSTABLES_TABLETYPE,// column number
397: 0, // precision
398: 0, // scale
399: false, // nullability
400: "CHAR", // dataType
401: true, // built-in type
402: 1 // maxLength
403: );
404:
405: columnList[3] = new SystemColumnImpl(convertIdCase("SCHEMAID"), // column name
406: SYSTABLES_SCHEMAID, // schema number
407: 0, // precision
408: 0, // scale
409: false, // nullability
410: "CHAR", // dataType
411: true, // built-in type
412: 36 // maxLength
413: );
414:
415: columnList[4] = new SystemColumnImpl(
416: convertIdCase("LOCKGRANULARITY"), // column name
417: SYSTABLES_LOCKGRANULARITY,// column number
418: 0, // precision
419: 0, // scale
420: false, // nullability
421: "CHAR", // dataType
422: true, // built-in type
423: 1 // maxLength
424: );
425:
426: return columnList;
427: }
428:
429: }
|