001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.catalog.SYSTABLEPERMSRowFactory
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.catalog.UUID;
025: import org.apache.derby.iapi.error.StandardException;
026: import org.apache.derby.iapi.services.sanity.SanityManager;
027: import org.apache.derby.iapi.services.uuid.UUIDFactory;
028: import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;
029: import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
030: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
031: import org.apache.derby.iapi.sql.dictionary.SystemColumn;
032: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
033: import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;
034: import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
035: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
036: import org.apache.derby.iapi.sql.execute.ExecRow;
037: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
038: import org.apache.derby.iapi.types.DataValueDescriptor;
039: import org.apache.derby.iapi.types.DataValueFactory;
040: import org.apache.derby.iapi.types.RowLocation;
041: import org.apache.derby.iapi.types.StringDataValue;
042:
043: /**
044: * Factory for creating a SYSTABLEPERMS row.
045: *
046: */
047:
048: public class SYSTABLEPERMSRowFactory extends
049: PermissionsCatalogRowFactory {
050: static final String TABLENAME_STRING = "SYSTABLEPERMS";
051:
052: // Column numbers for the SYSTABLEPERMS table. 1 based
053: private static final int TABLEPERMSID_COL_NUM = 1;
054: private static final int GRANTEE_COL_NUM = 2;
055: private static final int GRANTOR_COL_NUM = 3;
056: private static final int TABLEID_COL_NUM = 4;
057: private static final int SELECTPRIV_COL_NUM = 5;
058: private static final int DELETEPRIV_COL_NUM = 6;
059: private static final int INSERTPRIV_COL_NUM = 7;
060: private static final int UPDATEPRIV_COL_NUM = 8;
061: private static final int REFERENCESPRIV_COL_NUM = 9;
062: private static final int TRIGGERPRIV_COL_NUM = 10;
063: private static final int COLUMN_COUNT = 10;
064:
065: public static final int GRANTEE_TABLE_GRANTOR_INDEX_NUM = 0;
066: public static final int TABLEPERMSID_INDEX_NUM = 1;
067: public static final int TABLEID_INDEX_NUM = 2;
068: private static final int[][] indexColumnPositions = {
069: { GRANTEE_COL_NUM, TABLEID_COL_NUM, GRANTOR_COL_NUM },
070: { TABLEPERMSID_COL_NUM }, { TABLEID_COL_NUM } };
071:
072: private static final boolean[] indexUniqueness = { true, true,
073: false };
074:
075: private static final String[] uuids = {
076: "b8450018-0103-0e39-b8e7-00000010f010" // catalog UUID
077: , "004b0019-0103-0e39-b8e7-00000010f010" // heap UUID
078: , "c851401a-0103-0e39-b8e7-00000010f010" // index1
079: , "80220011-010c-426e-c599-0000000f1120" // index2
080: , "f81e0010-010c-bc85-060d-000000109ab8" // index3
081: };
082:
083: private SystemColumn[] columnList;
084:
085: public SYSTABLEPERMSRowFactory(UUIDFactory uuidf,
086: ExecutionFactory ef, DataValueFactory dvf,
087: boolean convertIdToLower) {
088: super (uuidf, ef, dvf, convertIdToLower);
089: initInfo(COLUMN_COUNT, TABLENAME_STRING, indexColumnPositions,
090: indexUniqueness, uuids);
091: }
092:
093: public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
094: throws StandardException {
095: UUID oid;
096: DataValueDescriptor grantee = null;
097: DataValueDescriptor grantor = null;
098: String tablePermID = null;
099: String tableID = null;
100: String selectPriv = null;
101: String deletePriv = null;
102: String insertPriv = null;
103: String updatePriv = null;
104: String referencesPriv = null;
105: String triggerPriv = null;
106:
107: if (td == null) {
108: grantee = getNullAuthorizationID();
109: grantor = getNullAuthorizationID();
110: } else {
111: TablePermsDescriptor tpd = (TablePermsDescriptor) td;
112: oid = tpd.getUUID();
113: if (oid == null) {
114: oid = getUUIDFactory().createUUID();
115: tpd.setUUID(oid);
116: }
117: tablePermID = oid.toString();
118:
119: grantee = getAuthorizationID(tpd.getGrantee());
120: grantor = getAuthorizationID(tpd.getGrantor());
121: tableID = tpd.getTableUUID().toString();
122: selectPriv = tpd.getSelectPriv();
123: deletePriv = tpd.getDeletePriv();
124: insertPriv = tpd.getInsertPriv();
125: updatePriv = tpd.getUpdatePriv();
126: referencesPriv = tpd.getReferencesPriv();
127: triggerPriv = tpd.getTriggerPriv();
128: }
129: ExecRow row = getExecutionFactory().getValueRow(COLUMN_COUNT);
130: row.setColumn(TABLEPERMSID_COL_NUM, dvf
131: .getCharDataValue(tablePermID));
132: row.setColumn(GRANTEE_COL_NUM, grantee);
133: row.setColumn(GRANTOR_COL_NUM, grantor);
134: row.setColumn(TABLEID_COL_NUM, dvf.getCharDataValue(tableID));
135: row.setColumn(SELECTPRIV_COL_NUM, dvf
136: .getCharDataValue(selectPriv));
137: row.setColumn(DELETEPRIV_COL_NUM, dvf
138: .getCharDataValue(deletePriv));
139: row.setColumn(INSERTPRIV_COL_NUM, dvf
140: .getCharDataValue(insertPriv));
141: row.setColumn(UPDATEPRIV_COL_NUM, dvf
142: .getCharDataValue(updatePriv));
143: row.setColumn(REFERENCESPRIV_COL_NUM, dvf
144: .getCharDataValue(referencesPriv));
145: row.setColumn(TRIGGERPRIV_COL_NUM, dvf
146: .getCharDataValue(triggerPriv));
147:
148: return row;
149: } // end of makeRow
150:
151: /** builds a tuple descriptor from a row */
152: public TupleDescriptor buildDescriptor(ExecRow row,
153: TupleDescriptor parentTuple, DataDictionary dataDictionary)
154: throws StandardException {
155: if (SanityManager.DEBUG)
156: SanityManager
157: .ASSERT(row.nColumns() == COLUMN_COUNT,
158: "Wrong size row passed to SYSTABLEPERMSRowFactory.buildDescriptor");
159:
160: String tablePermsUUIDString = row.getColumn(
161: TABLEPERMSID_COL_NUM).getString();
162: UUID tablePermsUUID = getUUIDFactory().recreateUUID(
163: tablePermsUUIDString);
164: String tableUUIDString = row.getColumn(TABLEID_COL_NUM)
165: .getString();
166: UUID tableUUID = getUUIDFactory().recreateUUID(tableUUIDString);
167: String selectPriv = row.getColumn(SELECTPRIV_COL_NUM)
168: .getString();
169: String deletePriv = row.getColumn(DELETEPRIV_COL_NUM)
170: .getString();
171: String insertPriv = row.getColumn(INSERTPRIV_COL_NUM)
172: .getString();
173: String updatePriv = row.getColumn(UPDATEPRIV_COL_NUM)
174: .getString();
175: String referencesPriv = row.getColumn(REFERENCESPRIV_COL_NUM)
176: .getString();
177: String triggerPriv = row.getColumn(TRIGGERPRIV_COL_NUM)
178: .getString();
179: if (SanityManager.DEBUG) {
180: SanityManager.ASSERT(
181: "y".equals(selectPriv) || "Y".equals(selectPriv)
182: || "N".equals(selectPriv),
183: "Invalid SYSTABLEPERMS.selectPriv column value: "
184: + selectPriv);
185: SanityManager.ASSERT(
186: "y".equals(deletePriv) || "Y".equals(deletePriv)
187: || "N".equals(deletePriv),
188: "Invalid SYSTABLEPERMS.deletePriv column value: "
189: + deletePriv);
190: SanityManager.ASSERT(
191: "y".equals(insertPriv) || "Y".equals(insertPriv)
192: || "N".equals(insertPriv),
193: "Invalid SYSTABLEPERMS.insertPriv column value: "
194: + insertPriv);
195: SanityManager.ASSERT(
196: "y".equals(updatePriv) || "Y".equals(updatePriv)
197: || "N".equals(updatePriv),
198: "Invalid SYSTABLEPERMS.updatePriv column value: "
199: + updatePriv);
200: SanityManager.ASSERT("y".equals(referencesPriv)
201: || "Y".equals(referencesPriv)
202: || "N".equals(referencesPriv),
203: "Invalid SYSTABLEPERMS.referencesPriv column value: "
204: + referencesPriv);
205: SanityManager.ASSERT("y".equals(triggerPriv)
206: || "Y".equals(triggerPriv)
207: || "N".equals(triggerPriv),
208: "Invalid SYSTABLEPERMS.triggerPriv column value: "
209: + triggerPriv);
210: }
211:
212: TablePermsDescriptor tabPermsDesc = new TablePermsDescriptor(
213: dataDictionary,
214: getAuthorizationID(row, GRANTEE_COL_NUM),
215: getAuthorizationID(row, GRANTOR_COL_NUM), tableUUID,
216: selectPriv, deletePriv, insertPriv, updatePriv,
217: referencesPriv, triggerPriv);
218: tabPermsDesc.setUUID(tablePermsUUID);
219: return tabPermsDesc;
220: } // end of buildDescriptor
221:
222: /** builds a column list for the catalog */
223: public SystemColumn[] buildColumnList() {
224: if (columnList == null) {
225: columnList = new SystemColumn[COLUMN_COUNT];
226:
227: columnList[TABLEPERMSID_COL_NUM - 1] = new SystemColumnImpl(
228: convertIdCase("TABLEPERMSID"),
229: TABLEPERMSID_COL_NUM, 0, // precision
230: 0, // scale
231: false, // nullability
232: "CHAR", true, 36);
233: columnList[GRANTEE_COL_NUM - 1] = new SystemColumnImpl(
234: convertIdCase("GRANTEE"),
235: GRANTEE_COL_NUM,
236: 0, // precision
237: 0, // scale
238: false, // nullability
239: AUTHORIZATION_ID_TYPE,
240: AUTHORIZATION_ID_IS_BUILTIN_TYPE,
241: AUTHORIZATION_ID_LENGTH);
242: columnList[GRANTOR_COL_NUM - 1] = new SystemColumnImpl(
243: convertIdCase("GRANTOR"),
244: GRANTOR_COL_NUM,
245: 0, // precision
246: 0, // scale
247: false, // nullability
248: AUTHORIZATION_ID_TYPE,
249: AUTHORIZATION_ID_IS_BUILTIN_TYPE,
250: AUTHORIZATION_ID_LENGTH);
251: columnList[TABLEID_COL_NUM - 1] = new SystemColumnImpl(
252: convertIdCase("TABLEID"), TABLEID_COL_NUM, 0, // precision
253: 0, // scale
254: false, // nullability
255: "CHAR", // dataType
256: true, // built-in type
257: 36);
258: columnList[SELECTPRIV_COL_NUM - 1] = new SystemColumnImpl(
259: convertIdCase("SELECTPRIV"), SELECTPRIV_COL_NUM, 0, // precision
260: 0, // scale
261: false, // nullability
262: "CHAR", // dataType
263: true, // built-in type
264: 1);
265: columnList[DELETEPRIV_COL_NUM - 1] = new SystemColumnImpl(
266: convertIdCase("DELETEPRIV"), DELETEPRIV_COL_NUM, 0, // precision
267: 0, // scale
268: false, // nullability
269: "CHAR", // dataType
270: true, // built-in type
271: 1);
272: columnList[INSERTPRIV_COL_NUM - 1] = new SystemColumnImpl(
273: convertIdCase("INSERTPRIV"), INSERTPRIV_COL_NUM, 0, // precision
274: 0, // scale
275: false, // nullability
276: "CHAR", // dataType
277: true, // built-in type
278: 1);
279: columnList[UPDATEPRIV_COL_NUM - 1] = new SystemColumnImpl(
280: convertIdCase("UPDATEPRIV"), UPDATEPRIV_COL_NUM, 0, // precision
281: 0, // scale
282: false, // nullability
283: "CHAR", // dataType
284: true, // built-in type
285: 1);
286: columnList[REFERENCESPRIV_COL_NUM - 1] = new SystemColumnImpl(
287: convertIdCase("REFERENCESPRIV"),
288: REFERENCESPRIV_COL_NUM, 0, // precision
289: 0, // scale
290: false, // nullability
291: "CHAR", // dataType
292: true, // built-in type
293: 1);
294: columnList[TRIGGERPRIV_COL_NUM - 1] = new SystemColumnImpl(
295: convertIdCase("TRIGGERPRIV"), TRIGGERPRIV_COL_NUM,
296: 0, // precision
297: 0, // scale
298: false, // nullability
299: "CHAR", // dataType
300: true, // built-in type
301: 1);
302: }
303: return columnList;
304: } // end of buildColumnList
305:
306: /**
307: * builds a key row given for a given index number.
308: */
309: public ExecIndexRow buildIndexKeyRow(int indexNumber,
310: PermissionsDescriptor perm) throws StandardException {
311: ExecIndexRow row = null;
312:
313: switch (indexNumber) {
314: case GRANTEE_TABLE_GRANTOR_INDEX_NUM:
315: // RESOLVE We do not support the FOR GRANT OPTION, so table permission rows are unique on the
316: // grantee and table UUID columns. The grantor column will always have the name of the owner of the
317: // table. So the index key, used for searching the index, only has grantee and table UUID columns.
318: // It does not have a grantor column.
319: //
320: // If we support FOR GRANT OPTION then there may be multiple table permissions rows for a
321: // (grantee, tableID) combination. We must either handle the multiple rows, which is necessary for
322: // checking permissions, or add a grantor column to the key, which is necessary for granting or revoking
323: // permissions.
324: row = getExecutionFactory().getIndexableRow(2);
325: row.setColumn(1, getAuthorizationID(perm.getGrantee()));
326: String tableUUIDStr = ((TablePermsDescriptor) perm)
327: .getTableUUID().toString();
328: row.setColumn(2, getDataValueFactory().getCharDataValue(
329: tableUUIDStr));
330: break;
331: case TABLEPERMSID_INDEX_NUM:
332: row = getExecutionFactory().getIndexableRow(1);
333: String tablePermsUUIDStr = perm.getObjectID().toString();
334: row.setColumn(1, getDataValueFactory().getCharDataValue(
335: tablePermsUUIDStr));
336: break;
337: case TABLEID_INDEX_NUM:
338: row = getExecutionFactory().getIndexableRow(1);
339: tableUUIDStr = ((TablePermsDescriptor) perm).getTableUUID()
340: .toString();
341: row.setColumn(1, getDataValueFactory().getCharDataValue(
342: tableUUIDStr));
343: break;
344: }
345: return row;
346: } // end of buildIndexRow
347:
348: public int getPrimaryKeyIndexNumber() {
349: return GRANTEE_TABLE_GRANTOR_INDEX_NUM;
350: }
351:
352: /**
353: * Or a set of permissions in with a row from this catalog table
354: *
355: * @param row an existing row
356: * @param perm a permission descriptor of the appropriate class for this PermissionsCatalogRowFactory class.
357: * @param colsChanged An array with one element for each column in row. It is updated to
358: * indicate which columns in row were changed
359: *
360: * @return The number of columns that were changed.
361: *
362: * @exception StandardException standard error policy
363: */
364: public int orPermissions(ExecRow row, PermissionsDescriptor perm,
365: boolean[] colsChanged) throws StandardException {
366: TablePermsDescriptor tablePerms = (TablePermsDescriptor) perm;
367: int changeCount = 0;
368: changeCount += orOnePermission(row, colsChanged,
369: SELECTPRIV_COL_NUM, tablePerms.getSelectPriv());
370: changeCount += orOnePermission(row, colsChanged,
371: DELETEPRIV_COL_NUM, tablePerms.getDeletePriv());
372: changeCount += orOnePermission(row, colsChanged,
373: INSERTPRIV_COL_NUM, tablePerms.getInsertPriv());
374: changeCount += orOnePermission(row, colsChanged,
375: UPDATEPRIV_COL_NUM, tablePerms.getUpdatePriv());
376: changeCount += orOnePermission(row, colsChanged,
377: REFERENCESPRIV_COL_NUM, tablePerms.getReferencesPriv());
378: changeCount += orOnePermission(row, colsChanged,
379: TRIGGERPRIV_COL_NUM, tablePerms.getTriggerPriv());
380:
381: return changeCount;
382: } // end of orPermissions
383:
384: private int orOnePermission(ExecRow row, boolean[] colsChanged,
385: int column, String permission) throws StandardException {
386: if (permission.charAt(0) == 'N')
387: return 0;
388:
389: if (SanityManager.DEBUG)
390: SanityManager
391: .ASSERT(permission.charAt(0) == 'Y'
392: || permission.charAt(0) == 'y',
393: "Invalid permission passed to SYSTABLEPERMSRowFactory.orOnePermission");
394: DataValueDescriptor existingPermDVD = row.getColumn(column);
395: char existingPerm = existingPermDVD.getString().charAt(0);
396: if (existingPerm == 'Y' || existingPerm == permission.charAt(0))
397: return 0;
398: existingPermDVD.setValue(permission);
399: colsChanged[column - 1] = true;
400: return 1;
401: } // end of orOnePermission
402:
403: /**
404: * Remove a set of permissions from a row from this catalog table
405: *
406: * @param row an existing row
407: * @param perm a permission descriptor of the appropriate class for this PermissionsCatalogRowFactory class.
408: * @param colsChanged An array with one element for each column in row. It is updated to
409: * indicate which columns in row were changed
410: *
411: * @return -1 if there are no permissions left in the row, otherwise the number of columns that were changed.
412: *
413: * @exception StandardException standard error policy
414: */
415: public int removePermissions(ExecRow row,
416: PermissionsDescriptor perm, boolean[] colsChanged)
417: throws StandardException {
418: TablePermsDescriptor tablePerms = (TablePermsDescriptor) perm;
419: int changeCount = 0;
420: boolean permissionsLeft = (removeOnePermission(row,
421: colsChanged, SELECTPRIV_COL_NUM, tablePerms
422: .getSelectPriv())
423: | removeOnePermission(row, colsChanged,
424: DELETEPRIV_COL_NUM, tablePerms.getDeletePriv())
425: | removeOnePermission(row, colsChanged,
426: INSERTPRIV_COL_NUM, tablePerms.getInsertPriv())
427: | removeOnePermission(row, colsChanged,
428: UPDATEPRIV_COL_NUM, tablePerms.getUpdatePriv())
429: | removeOnePermission(row, colsChanged,
430: REFERENCESPRIV_COL_NUM, tablePerms
431: .getReferencesPriv()) | removeOnePermission(
432: row, colsChanged, TRIGGERPRIV_COL_NUM, tablePerms
433: .getTriggerPriv()));
434: if (!permissionsLeft)
435: return -1;
436: for (int i = 0; i < colsChanged.length; i++) {
437: if (colsChanged[i])
438: changeCount++;
439: }
440: return changeCount;
441: } // end of removePermissions
442:
443: private boolean removeOnePermission(ExecRow row,
444: boolean[] colsChanged, int column, String permission)
445: throws StandardException {
446: DataValueDescriptor existingPermDVD = row.getColumn(column);
447: char existingPerm = existingPermDVD.getString().charAt(0);
448:
449: if (permission.charAt(0) == 'N') // Don't remove this one
450: return existingPerm != 'N'; // The grantee still has some permissions on this table
451: if (SanityManager.DEBUG)
452: SanityManager
453: .ASSERT(permission.charAt(0) == 'Y'
454: || permission.charAt(0) == 'y',
455: "Invalid permission passed to SYSTABLEPERMSRowFactory.removeOnePermission");
456: if (existingPerm != 'N') {
457: existingPermDVD.setValue("N");
458: colsChanged[column - 1] = true;
459: }
460: return false;
461: } // end of removeOnePermission
462:
463: /**
464: * @see PermissionsCatalogRowFactory#setUUIDOfThePassedDescriptor
465: */
466: public void setUUIDOfThePassedDescriptor(ExecRow row,
467: PermissionsDescriptor perm) throws StandardException {
468: DataValueDescriptor existingPermDVD = row
469: .getColumn(TABLEPERMSID_COL_NUM);
470: perm.setUUID(getUUIDFactory().recreateUUID(
471: existingPermDVD.getString()));
472: }
473: }
|