001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.catalog.SYSCOLPERMSRowFactory
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.sql.dictionary.ColPermsDescriptor;
025: import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
026: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
027: import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor;
028: import org.apache.derby.iapi.sql.dictionary.SystemColumn;
029: import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
030: import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;
031:
032: import org.apache.derby.iapi.error.StandardException;
033:
034: import org.apache.derby.iapi.services.sanity.SanityManager;
035: import org.apache.derby.iapi.sql.execute.ExecRow;
036: import org.apache.derby.iapi.sql.execute.ExecIndexRow;
037: import org.apache.derby.iapi.sql.execute.ExecutionFactory;
038: import org.apache.derby.iapi.types.TypeId;
039: import org.apache.derby.iapi.types.DataValueFactory;
040: import org.apache.derby.iapi.types.RowLocation;
041: import org.apache.derby.iapi.types.DataTypeDescriptor;
042: import org.apache.derby.iapi.types.DataValueDescriptor;
043: import org.apache.derby.iapi.types.NumberDataValue;
044: import org.apache.derby.iapi.types.StringDataValue;
045: import org.apache.derby.iapi.services.uuid.UUIDFactory;
046: import org.apache.derby.catalog.UUID;
047: import org.apache.derby.catalog.Statistics;
048: import org.apache.derby.iapi.services.io.FormatableBitSet;
049:
050: import java.sql.Timestamp;
051:
052: /**
053: * Factory for creating a SYSCOLPERMS row.
054: *
055: */
056:
057: class SYSCOLPERMSRowFactory extends PermissionsCatalogRowFactory {
058: static final String TABLENAME_STRING = "SYSCOLPERMS";
059:
060: // Column numbers for the SYSCOLPERMS table. 1 based
061: private static final int COLPERMSID_COL_NUM = 1;
062: private static final int GRANTEE_COL_NUM = 2;
063: private static final int GRANTOR_COL_NUM = 3;
064: private static final int TABLEID_COL_NUM = 4;
065: private static final int TYPE_COL_NUM = 5;
066: protected static final int COLUMNS_COL_NUM = 6;
067: private static final int COLUMN_COUNT = 6;
068:
069: static final int GRANTEE_TABLE_TYPE_GRANTOR_INDEX_NUM = 0;
070: static final int COLPERMSID_INDEX_NUM = 1;
071: static final int TABLEID_INDEX_NUM = 2;
072: protected static final int TOTAL_NUM_OF_INDEXES = 3;
073: private static final int[][] indexColumnPositions = {
074: { GRANTEE_COL_NUM, TABLEID_COL_NUM, TYPE_COL_NUM,
075: GRANTOR_COL_NUM }, { COLPERMSID_COL_NUM },
076: { TABLEID_COL_NUM } };
077:
078: private static final boolean[] indexUniqueness = { true, true,
079: false };
080:
081: private static final String[] uuids = {
082: "286cc01e-0103-0e39-b8e7-00000010f010" // catalog UUID
083: , "6074401f-0103-0e39-b8e7-00000010f010" // heap UUID
084: , "787c0020-0103-0e39-b8e7-00000010f010" // index1
085: , "c9a3808d-010c-42a2-ae15-0000000f67f8" //index2
086: , "80220011-010c-bc85-060d-000000109ab8" //index3
087: };
088:
089: private SystemColumn[] columnList;
090:
091: SYSCOLPERMSRowFactory(UUIDFactory uuidf, ExecutionFactory ef,
092: DataValueFactory dvf, boolean convertIdToLower) {
093: super (uuidf, ef, dvf, convertIdToLower);
094: initInfo(COLUMN_COUNT, TABLENAME_STRING, indexColumnPositions,
095: indexUniqueness, uuids);
096: }
097:
098: public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
099: throws StandardException {
100: UUID oid;
101: String colPermID = null;
102: DataValueDescriptor grantee = null;
103: DataValueDescriptor grantor = null;
104: String tableID = null;
105: String type = null;
106: FormatableBitSet columns = null;
107:
108: if (td == null) {
109: grantee = getNullAuthorizationID();
110: grantor = getNullAuthorizationID();
111: } else {
112: ColPermsDescriptor cpd = (ColPermsDescriptor) td;
113: oid = cpd.getUUID();
114: if (oid == null) {
115: oid = getUUIDFactory().createUUID();
116: cpd.setUUID(oid);
117: }
118: colPermID = oid.toString();
119: grantee = getAuthorizationID(cpd.getGrantee());
120: grantor = getAuthorizationID(cpd.getGrantor());
121: tableID = cpd.getTableUUID().toString();
122: type = cpd.getType();
123: columns = cpd.getColumns();
124: }
125: ExecRow row = getExecutionFactory().getValueRow(COLUMN_COUNT);
126: row.setColumn(COLPERMSID_COL_NUM, dvf
127: .getCharDataValue(colPermID));
128: row.setColumn(GRANTEE_COL_NUM, grantee);
129: row.setColumn(GRANTOR_COL_NUM, grantor);
130: row.setColumn(TABLEID_COL_NUM, dvf.getCharDataValue(tableID));
131: row.setColumn(TYPE_COL_NUM, dvf.getCharDataValue(type));
132: row.setColumn(COLUMNS_COL_NUM, dvf
133: .getDataValue((Object) columns));
134: return row;
135: } // end of makeRow
136:
137: /** builds a tuple descriptor from a row */
138: public TupleDescriptor buildDescriptor(ExecRow row,
139: TupleDescriptor parentTuple, DataDictionary dataDictionary)
140: throws StandardException {
141: if (SanityManager.DEBUG)
142: SanityManager
143: .ASSERT(row.nColumns() == COLUMN_COUNT,
144: "Wrong size row passed to SYSCOLPERMSRowFactory.buildDescriptor");
145:
146: String colPermsUUIDString = row.getColumn(COLPERMSID_COL_NUM)
147: .getString();
148: UUID colPermsUUID = getUUIDFactory().recreateUUID(
149: colPermsUUIDString);
150: String tableUUIDString = row.getColumn(TABLEID_COL_NUM)
151: .getString();
152: UUID tableUUID = getUUIDFactory().recreateUUID(tableUUIDString);
153: String type = row.getColumn(TYPE_COL_NUM).getString();
154: FormatableBitSet columns = (FormatableBitSet) row.getColumn(
155: COLUMNS_COL_NUM).getObject();
156: if (SanityManager.DEBUG)
157: SanityManager
158: .ASSERT("s".equals(type) || "S".equals(type)
159: || "u".equals(type) || "U".equals(type)
160: || "r".equals(type) || "R".equals(type),
161: "Invalid type passed to SYSCOLPERMSRowFactory.buildDescriptor");
162:
163: ColPermsDescriptor colPermsDesc = new ColPermsDescriptor(
164: dataDictionary,
165: getAuthorizationID(row, GRANTEE_COL_NUM),
166: getAuthorizationID(row, GRANTOR_COL_NUM), tableUUID,
167: type, columns);
168: colPermsDesc.setUUID(colPermsUUID);
169: return colPermsDesc;
170: } // end of buildDescriptor
171:
172: /** builds a column list for the catalog */
173: public SystemColumn[] buildColumnList() {
174: return new SystemColumn[] {
175: SystemColumnImpl.getUUIDColumn("COLPERMSID", false),
176: SystemColumnImpl.getIdentifierColumn("GRANTEE", false),
177: SystemColumnImpl.getIdentifierColumn("GRANTOR", false),
178: SystemColumnImpl.getUUIDColumn("TABLEID", false),
179: SystemColumnImpl.getIndicatorColumn("TYPE"),
180: SystemColumnImpl
181: .getJavaColumn(
182: "COLUMNS",
183: "org.apache.derby.iapi.services.io.FormatableBitSet",
184: false) };
185: }
186:
187: /**
188: * builds an index key row for a given index number.
189: */
190: public ExecIndexRow buildIndexKeyRow(int indexNumber,
191: PermissionsDescriptor perm) throws StandardException {
192: ExecIndexRow row = null;
193:
194: switch (indexNumber) {
195: case GRANTEE_TABLE_TYPE_GRANTOR_INDEX_NUM:
196: // RESOLVE We do not support the FOR GRANT OPTION, so column permission rows are unique on the
197: // grantee, table UUID, and type columns. The grantor column will always have the name of the owner of the
198: // table. So the index key, used for searching the index, only has grantee, table UUID, and type columns.
199: // It does not have a grantor column.
200: //
201: // If we support FOR GRANT OPTION then there may be multiple table permissions rows for a
202: // (grantee, tableID, type) combination. We must either handle the multiple rows, which is necessary for
203: // checking permissions, or add a grantor column to the key, which is necessary for granting or revoking
204: // permissions.
205: row = getExecutionFactory().getIndexableRow(3);
206: row.setColumn(1, getAuthorizationID(perm.getGrantee()));
207: ColPermsDescriptor colPerms = (ColPermsDescriptor) perm;
208: String tableUUIDStr = colPerms.getTableUUID().toString();
209: row.setColumn(2, getDataValueFactory().getCharDataValue(
210: tableUUIDStr));
211: row.setColumn(3, getDataValueFactory().getCharDataValue(
212: colPerms.getType()));
213: break;
214: case COLPERMSID_INDEX_NUM:
215: row = getExecutionFactory().getIndexableRow(1);
216: String colPermsUUIDStr = perm.getObjectID().toString();
217: row.setColumn(1, getDataValueFactory().getCharDataValue(
218: colPermsUUIDStr));
219: break;
220: case TABLEID_INDEX_NUM:
221: row = getExecutionFactory().getIndexableRow(1);
222: colPerms = (ColPermsDescriptor) perm;
223: tableUUIDStr = colPerms.getTableUUID().toString();
224: row.setColumn(1, getDataValueFactory().getCharDataValue(
225: tableUUIDStr));
226: break;
227: }
228: return row;
229: } // end of buildIndexKeyRow
230:
231: public int getPrimaryKeyIndexNumber() {
232: return GRANTEE_TABLE_TYPE_GRANTOR_INDEX_NUM;
233: }
234:
235: /**
236: * Or a set of permissions in with a row from this catalog table
237: *
238: * @param row an existing row
239: * @param perm a permission descriptor of the appropriate class for this PermissionsCatalogRowFactory class.
240: * @param colsChanged An array with one element for each column in row. It is updated to
241: * indicate which columns in row were changed
242: *
243: * @return The number of columns that were changed.
244: *
245: * @exception StandardException standard error policy
246: */
247: public int orPermissions(ExecRow row, PermissionsDescriptor perm,
248: boolean[] colsChanged) throws StandardException {
249: ColPermsDescriptor colPerms = (ColPermsDescriptor) perm;
250: FormatableBitSet existingColSet = (FormatableBitSet) row
251: .getColumn(COLUMNS_COL_NUM).getObject();
252: FormatableBitSet newColSet = colPerms.getColumns();
253:
254: boolean changed = false;
255: for (int i = newColSet.anySetBit(); i >= 0; i = newColSet
256: .anySetBit(i)) {
257: if (!existingColSet.get(i)) {
258: existingColSet.set(i);
259: changed = true;
260: }
261: }
262: if (changed) {
263: colsChanged[COLUMNS_COL_NUM - 1] = true;
264: return 1;
265: }
266: return 0;
267: } // end of orPermissions
268:
269: /**
270: * Remove a set of permissions from a row from this catalog table
271: *
272: * @param row an existing row
273: * @param perm a permission descriptor of the appropriate class for this PermissionsCatalogRowFactory class.
274: * @param colsChanged An array with one element for each column in row. It is updated to
275: * indicate which columns in row were changed
276: *
277: * @return -1 if there are no permissions left in the row, otherwise the number of columns that were changed.
278: *
279: * @exception StandardException standard error policy
280: */
281: public int removePermissions(ExecRow row,
282: PermissionsDescriptor perm, boolean[] colsChanged)
283: throws StandardException {
284: ColPermsDescriptor colPerms = (ColPermsDescriptor) perm;
285: FormatableBitSet removeColSet = colPerms.getColumns();
286: if (removeColSet == null)
287: // remove all of them
288: return -1;
289:
290: FormatableBitSet existingColSet = (FormatableBitSet) row
291: .getColumn(COLUMNS_COL_NUM).getObject();
292:
293: boolean changed = false;
294: for (int i = removeColSet.anySetBit(); i >= 0; i = removeColSet
295: .anySetBit(i)) {
296: if (existingColSet.get(i)) {
297: existingColSet.clear(i);
298: changed = true;
299: }
300: }
301: if (changed) {
302: colsChanged[COLUMNS_COL_NUM - 1] = true;
303: if (existingColSet.anySetBit() < 0)
304: return -1; // No column privileges left
305: return 1; // A change, but there are some privileges left
306: }
307: return 0; // no change
308: } // end of removePermissions
309:
310: /**
311: * @see PermissionsCatalogRowFactory#setUUIDOfThePassedDescriptor
312: */
313: public void setUUIDOfThePassedDescriptor(ExecRow row,
314: PermissionsDescriptor perm) throws StandardException {
315: DataValueDescriptor existingPermDVD = row
316: .getColumn(COLPERMSID_COL_NUM);
317: perm.setUUID(getUUIDFactory().recreateUUID(
318: existingPermDVD.getString()));
319: }
320: }
|