001: /*
002:
003: Derby - Class org.apache.derby.iapi.sql.dictionary.CatalogRowFactory
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.iapi.sql.dictionary;
023:
024: import org.apache.derby.iapi.reference.Property;
025: import org.apache.derby.iapi.util.StringUtil;
026:
027: import org.apache.derby.iapi.services.context.ContextService;
028: import org.apache.derby.iapi.services.monitor.Monitor;
029: import org.apache.derby.iapi.services.sanity.SanityManager;
030: import org.apache.derby.iapi.error.StandardException;
031: import org.apache.derby.iapi.types.DataValueFactory;
032: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
033: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
034: import org.apache.derby.iapi.sql.execute.ExecRow;
035: import org.apache.derby.iapi.sql.execute.ExecutionContext;
036: import org.apache.derby.iapi.types.DataTypeDescriptor;
037: import org.apache.derby.iapi.types.DataValueFactory;
038: import org.apache.derby.iapi.types.RowLocation;
039: import org.apache.derby.iapi.store.raw.RawStoreFactory;
040: import org.apache.derby.iapi.services.uuid.UUIDFactory;
041: import org.apache.derby.catalog.UUID;
042: import java.util.Properties;
043:
044: /**
045: * Superclass of all row factories.
046: *
047: *
048: * @version 0.2
049: * @author Rick Hillegas
050: * @author Manish Khettry
051: */
052:
053: public abstract class CatalogRowFactory {
054: ///////////////////////////////////////////////////////////////////////////
055: //
056: // STATE
057: //
058: ///////////////////////////////////////////////////////////////////////////
059:
060: protected String[] indexNames;
061: protected int[][] indexColumnPositions;
062: protected boolean[] indexUniqueness;
063:
064: protected UUID tableUUID;
065: protected UUID heapUUID;
066: protected UUID[] indexUUID;
067:
068: protected DataValueFactory dvf;
069: private final ExecutionFactory ef;
070: private UUIDFactory uuidf;
071:
072: private boolean convertIdToLower;
073: private int indexCount;
074: private int columnCount;
075: private String catalogName;
076:
077: ///////////////////////////////////////////////////////////////////////////
078: //
079: // CONSTRUCTORS
080: //
081: ///////////////////////////////////////////////////////////////////////////
082:
083: public CatalogRowFactory(UUIDFactory uuidf, ExecutionFactory ef,
084: DataValueFactory dvf, boolean convertIdToLower)
085:
086: {
087: this .uuidf = uuidf;
088: this .dvf = dvf;
089: this .ef = ef;
090: this .convertIdToLower = convertIdToLower;
091: }
092:
093: /**
094: * Gets a ExecutionFactory
095: *
096: * @return an execution factory
097: */
098: public ExecutionFactory getExecutionFactory() {
099: return ef;
100: }
101:
102: /**
103: * Get the UUID factory
104: *
105: * @return the UUID factory
106: */
107: public UUIDFactory getUUIDFactory() {
108: return uuidf;
109: }
110:
111: /* Override the following methods in sub-classes if they have any
112: * indexes.
113: */
114:
115: /**
116: * Get the UUID of this catalog. This is the hard-coded uuid for
117: * this catalog that is generated for releases starting with Plato (1.3).
118: * Earlier releases generated their own UUIDs for system objectss on
119: * the fly.
120: *
121: * @return the name of this catalog
122: */
123: public UUID getCanonicalTableUUID() {
124: return tableUUID;
125: }
126:
127: /**
128: * Get the UUID of the heap underlying this catalog. See getCanonicalTableUUID()
129: * for a description of canonical uuids.
130: *
131: * @return the uuid of the heap
132: */
133: public UUID getCanonicalHeapUUID() {
134: return heapUUID;
135: }
136:
137: /**
138: * Get the UUID of the numbered index. See getCanonicalTableUUID()
139: * for a description of canonical uuids.
140: *
141: * @param indexNumber The (0-based) index number.
142: *
143: * @return the uuid of the heap
144: */
145: public UUID getCanonicalIndexUUID(int indexNumber) {
146: return indexUUID[indexNumber];
147: }
148:
149: /**
150: * Get the number of columns in the index for the specified index number.
151: *
152: * @param indexNum The (0-based) index number.
153: *
154: * @return int The number of columns in the index for the specifed index number.
155: */
156: public int getIndexColumnCount(int indexNum) {
157: return indexColumnPositions[indexNum].length;
158: }
159:
160: /**
161: * Get the name for the heap conglomerate underlying this catalog.
162: * See getCanonicalTableUUID() for a description of canonical uuids.
163: *
164: * @return String The name for the heap conglomerate.
165: */
166: public String getCanonicalHeapName() {
167: return catalogName + convertIdCase("_HEAP");
168: }
169:
170: /**
171: * Get the name for the specified index number.
172: *
173: * @param indexNum The (0-based) index number.
174: *
175: * @return String The name for the specified index number.
176: */
177: public String getIndexName(int indexNum) {
178: return indexNames[indexNum];
179: }
180:
181: /**
182: * Return whether or not the specified index is unique.
183: *
184: * @param indexNumber The (0-based) index number.
185: *
186: * @return boolean Whether or not the specified index is unique.
187: */
188: public boolean isIndexUnique(int indexNumber) {
189: return (indexUniqueness != null ? indexUniqueness[indexNumber]
190: : true);
191: }
192:
193: /**
194: * Gets the DataValueFactory for this connection.
195: *
196: * @return the data value factory for this connection
197: */
198: public DataValueFactory getDataValueFactory() {
199: return dvf;
200: }
201:
202: /**
203: * Generate an index name based on the index number.
204: *
205: * @param indexNumber Number of index
206: *
207: * @return the following index name: CatalogName + "_INDEX" + (indexNumber+1)
208: */
209: public String generateIndexName(int indexNumber) {
210: indexNumber++;
211: return catalogName + convertIdCase("_INDEX") + indexNumber;
212: }
213:
214: /** get the number of indexes on this catalog */
215: public int getNumIndexes() {
216: return indexCount;
217: }
218:
219: /** get the name of the catalog */
220: public String getCatalogName() {
221: return catalogName;
222: };
223:
224: /**
225: * Initialize info, including array of index names and array of
226: * index column counts. Called at constructor time.
227: *
228: * @param columnCount number of columns in the base table.
229: * @param catalogName name of the catalog (the case might have to be converted).
230: * @param indexColumnPositions 2 dim array of ints specifying the base
231: * column positions for each index.
232: * @param indexUniqueness Uniqueness of the indices
233: * @param uuidStrings Array of stringified UUIDs for table and its conglomerates
234: *
235: */
236: public void initInfo(int columnCount, String catalogName,
237: int[][] indexColumnPositions, boolean[] indexUniqueness,
238: String[] uuidStrings)
239:
240: {
241: indexCount = (indexColumnPositions != null) ? indexColumnPositions.length
242: : 0;
243:
244: this .catalogName = convertIdCase(catalogName);
245: this .columnCount = columnCount;
246:
247: UUIDFactory uf = getUUIDFactory();
248: this .tableUUID = uf.recreateUUID(uuidStrings[0]);
249: this .heapUUID = uf.recreateUUID(uuidStrings[1]);
250:
251: if (indexCount > 0) {
252: indexNames = new String[indexCount];
253: indexUUID = new UUID[indexCount];
254: for (int ictr = 0; ictr < indexCount; ictr++) {
255: indexNames[ictr] = generateIndexName(ictr);
256: indexUUID[ictr] = uf
257: .recreateUUID(uuidStrings[ictr + 2]);
258: }
259: this .indexColumnPositions = indexColumnPositions;
260: this .indexUniqueness = indexUniqueness;
261:
262: }
263: }
264:
265: /**
266: * Get the Properties associated with creating the heap.
267: *
268: * @return The Properties associated with creating the heap.
269: */
270: public Properties getCreateHeapProperties() {
271: Properties properties = new Properties();
272: // default properties for system tables:
273: properties.put(Property.PAGE_SIZE_PARAMETER, "1024");
274: properties.put(RawStoreFactory.PAGE_RESERVED_SPACE_PARAMETER,
275: "0");
276: properties.put(RawStoreFactory.MINIMUM_RECORD_SIZE_PARAMETER,
277: "1");
278: return properties;
279: }
280:
281: /**
282: * Get the Properties associated with creating the specified index.
283: *
284: * @param indexNumber The specified index number.
285: *
286: * @return The Properties associated with creating the specified index.
287: */
288: public Properties getCreateIndexProperties(int indexNumber) {
289: Properties properties = new Properties();
290: // default properties for system indexes:
291: properties.put(Property.PAGE_SIZE_PARAMETER, "1024");
292: return properties;
293: }
294:
295: /**
296: * Get the index number for the primary key index on this catalog.
297: *
298: * @return a 0-based number
299: *
300: */
301: public int getPrimaryKeyIndexNumber() {
302: if (SanityManager.DEBUG)
303: SanityManager.NOTREACHED();
304: return 0;
305: }
306:
307: /**
308: * Get the number of columns in the heap.
309: *
310: * @return The number of columns in the heap.
311: */
312: public final int getHeapColumnCount() {
313: return columnCount;
314: }
315:
316: protected String convertIdCase(String id) {
317: if (convertIdToLower)
318: return StringUtil.SQLToLowerCase(id);
319: else
320: return id;
321: }
322:
323: /**
324: * Return an empty row for this conglomerate.
325: */
326: public ExecRow makeEmptyRow() throws StandardException {
327: return this .makeRow(null, null);
328: }
329:
330: /**
331: * most subclasses should provide this method. One or two oddball cases in
332: * Replication and SysSTATEMENTSRowFactory don't. For those we call makeRow
333: * with the additional arguments.
334: */
335: public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
336: throws StandardException {
337: if (SanityManager.DEBUG) {
338: SanityManager.THROWASSERT("Should not get here.");
339: }
340: return null;
341: }
342:
343: // abstract classes that should be implemented by subclasses.
344:
345: /** builds a tuple descriptor from a row */
346: public abstract TupleDescriptor buildDescriptor(ExecRow row,
347: TupleDescriptor parentTuple, DataDictionary dataDictionary)
348: throws StandardException;
349:
350: /** builds a column list for the catalog */
351: public abstract SystemColumn[] buildColumnList();
352:
353: /** Return the column positions for a given index number */
354: public int[] getIndexColumnPositions(int indexNumber) {
355: return indexColumnPositions[indexNumber];
356: }
357: }
|