--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.catalog.SYSTABLEPERMSRowFactory\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.catalog;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.uuid.UUIDFactory;\r
+import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;\r
+import org.apache.derby.iapi.sql.execute.ExecIndexRow;\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.sql.execute.ExecutionFactory;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+import org.apache.derby.iapi.types.RowLocation;\r
+import org.apache.derby.iapi.types.SQLChar;\r
+import org.apache.derby.iapi.types.StringDataValue;\r
+\r
+/**\r
+ * Factory for creating a SYSTABLEPERMS row.\r
+ *\r
+ */\r
+\r
+public class SYSTABLEPERMSRowFactory extends PermissionsCatalogRowFactory\r
+{\r
+ static final String TABLENAME_STRING = "SYSTABLEPERMS";\r
+\r
+ // Column numbers for the SYSTABLEPERMS table. 1 based\r
+ private static final int TABLEPERMSID_COL_NUM = 1;\r
+ private static final int GRANTEE_COL_NUM = 2;\r
+ private static final int GRANTOR_COL_NUM = 3;\r
+ private static final int TABLEID_COL_NUM = 4;\r
+ private static final int SELECTPRIV_COL_NUM = 5;\r
+ private static final int DELETEPRIV_COL_NUM = 6;\r
+ private static final int INSERTPRIV_COL_NUM = 7;\r
+ private static final int UPDATEPRIV_COL_NUM = 8;\r
+ private static final int REFERENCESPRIV_COL_NUM = 9;\r
+ private static final int TRIGGERPRIV_COL_NUM = 10;\r
+ private static final int COLUMN_COUNT = 10;\r
+\r
+ public static final int GRANTEE_TABLE_GRANTOR_INDEX_NUM = 0;\r
+ public static final int TABLEPERMSID_INDEX_NUM = 1;\r
+ public static final int TABLEID_INDEX_NUM = 2;\r
+ private static final int[][] indexColumnPositions = \r
+ { \r
+ { GRANTEE_COL_NUM, TABLEID_COL_NUM, GRANTOR_COL_NUM},\r
+ { TABLEPERMSID_COL_NUM },\r
+ { TABLEID_COL_NUM }\r
+ };\r
+\r
+ private static final boolean[] indexUniqueness = { true, true, false};\r
+ \r
+ private static final String[] uuids =\r
+ {\r
+ "b8450018-0103-0e39-b8e7-00000010f010" // catalog UUID\r
+ ,"004b0019-0103-0e39-b8e7-00000010f010" // heap UUID\r
+ ,"c851401a-0103-0e39-b8e7-00000010f010" // index1\r
+ ,"80220011-010c-426e-c599-0000000f1120" // index2\r
+ ,"f81e0010-010c-bc85-060d-000000109ab8" // index3\r
+ };\r
+\r
+ SYSTABLEPERMSRowFactory(UUIDFactory uuidf, ExecutionFactory ef, DataValueFactory dvf)\r
+ {\r
+ super(uuidf,ef,dvf);\r
+ initInfo(COLUMN_COUNT, TABLENAME_STRING, indexColumnPositions, indexUniqueness, uuids);\r
+ }\r
+\r
+ public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent) throws StandardException\r
+ {\r
+ UUID oid;\r
+ DataValueDescriptor grantee = null;\r
+ DataValueDescriptor grantor = null;\r
+ String tablePermID = null;\r
+ String tableID = null;\r
+ String selectPriv = null;\r
+ String deletePriv = null;\r
+ String insertPriv = null;\r
+ String updatePriv = null;\r
+ String referencesPriv = null;\r
+ String triggerPriv = null;\r
+\r
+ if( td == null)\r
+ {\r
+ grantee = getNullAuthorizationID();\r
+ grantor = getNullAuthorizationID();\r
+ }\r
+ else\r
+ {\r
+ TablePermsDescriptor tpd = (TablePermsDescriptor) td;\r
+ oid = tpd.getUUID();\r
+ if ( oid == null )\r
+ {\r
+ oid = getUUIDFactory().createUUID();\r
+ tpd.setUUID(oid);\r
+ }\r
+ tablePermID = oid.toString();\r
+\r
+ grantee = getAuthorizationID( tpd.getGrantee());\r
+ grantor = getAuthorizationID( tpd.getGrantor());\r
+ tableID = tpd.getTableUUID().toString();\r
+ selectPriv = tpd.getSelectPriv();\r
+ deletePriv = tpd.getDeletePriv();\r
+ insertPriv = tpd.getInsertPriv();\r
+ updatePriv = tpd.getUpdatePriv();\r
+ referencesPriv = tpd.getReferencesPriv();\r
+ triggerPriv = tpd.getTriggerPriv();\r
+ }\r
+ ExecRow row = getExecutionFactory().getValueRow( COLUMN_COUNT);\r
+ row.setColumn( TABLEPERMSID_COL_NUM, new SQLChar(tablePermID));\r
+ row.setColumn( GRANTEE_COL_NUM, grantee);\r
+ row.setColumn( GRANTOR_COL_NUM, grantor);\r
+ row.setColumn( TABLEID_COL_NUM, new SQLChar(tableID));\r
+ row.setColumn( SELECTPRIV_COL_NUM, new SQLChar(selectPriv));\r
+ row.setColumn( DELETEPRIV_COL_NUM, new SQLChar(deletePriv));\r
+ row.setColumn( INSERTPRIV_COL_NUM, new SQLChar(insertPriv));\r
+ row.setColumn( UPDATEPRIV_COL_NUM, new SQLChar(updatePriv));\r
+ row.setColumn( REFERENCESPRIV_COL_NUM, new SQLChar( referencesPriv));\r
+ row.setColumn( TRIGGERPRIV_COL_NUM, new SQLChar(triggerPriv));\r
+\r
+ return row;\r
+ } // end of makeRow\r
+ \r
+ /** builds a tuple descriptor from a row */\r
+ public TupleDescriptor buildDescriptor(ExecRow row,\r
+ TupleDescriptor parentTuple,\r
+ DataDictionary dataDictionary)\r
+ throws StandardException\r
+ {\r
+ if( SanityManager.DEBUG)\r
+ SanityManager.ASSERT( row.nColumns() == COLUMN_COUNT,\r
+ "Wrong size row passed to SYSTABLEPERMSRowFactory.buildDescriptor");\r
+\r
+ String tablePermsUUIDString = row.getColumn(TABLEPERMSID_COL_NUM).getString();\r
+ UUID tablePermsUUID = getUUIDFactory().recreateUUID(tablePermsUUIDString);\r
+ String tableUUIDString = row.getColumn( TABLEID_COL_NUM).getString();\r
+ UUID tableUUID = getUUIDFactory().recreateUUID(tableUUIDString);\r
+ String selectPriv = row.getColumn( SELECTPRIV_COL_NUM).getString();\r
+ String deletePriv = row.getColumn( DELETEPRIV_COL_NUM).getString();\r
+ String insertPriv = row.getColumn( INSERTPRIV_COL_NUM).getString();\r
+ String updatePriv = row.getColumn( UPDATEPRIV_COL_NUM).getString();\r
+ String referencesPriv = row.getColumn( REFERENCESPRIV_COL_NUM).getString();\r
+ String triggerPriv = row.getColumn( TRIGGERPRIV_COL_NUM).getString();\r
+ if( SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT( "y".equals(selectPriv) || "Y".equals(selectPriv) || "N".equals(selectPriv),\r
+ "Invalid SYSTABLEPERMS.selectPriv column value: " + selectPriv);\r
+ SanityManager.ASSERT( "y".equals(deletePriv) || "Y".equals(deletePriv) || "N".equals(deletePriv),\r
+ "Invalid SYSTABLEPERMS.deletePriv column value: " + deletePriv);\r
+ SanityManager.ASSERT( "y".equals(insertPriv) || "Y".equals(insertPriv) || "N".equals(insertPriv),\r
+ "Invalid SYSTABLEPERMS.insertPriv column value: " + insertPriv);\r
+ SanityManager.ASSERT( "y".equals(updatePriv) || "Y".equals(updatePriv) || "N".equals(updatePriv),\r
+ "Invalid SYSTABLEPERMS.updatePriv column value: " + updatePriv);\r
+ SanityManager.ASSERT( "y".equals(referencesPriv) || "Y".equals(referencesPriv) || "N".equals(referencesPriv),\r
+ "Invalid SYSTABLEPERMS.referencesPriv column value: " + referencesPriv);\r
+ SanityManager.ASSERT( "y".equals(triggerPriv) || "Y".equals(triggerPriv) || "N".equals(triggerPriv),\r
+ "Invalid SYSTABLEPERMS.triggerPriv column value: " + triggerPriv);\r
+ }\r
+\r
+ TablePermsDescriptor tabPermsDesc =\r
+ new TablePermsDescriptor( dataDictionary,\r
+ getAuthorizationID( row, GRANTEE_COL_NUM),\r
+ getAuthorizationID( row, GRANTOR_COL_NUM),\r
+ tableUUID,\r
+ selectPriv, deletePriv, insertPriv,\r
+ updatePriv, referencesPriv, triggerPriv);\r
+ tabPermsDesc.setUUID(tablePermsUUID);\r
+ return tabPermsDesc;\r
+ } // end of buildDescriptor\r
+\r
+ /** builds a column list for the catalog */\r
+ public SystemColumn[] buildColumnList()\r
+ {\r
+ return new SystemColumn[] {\r
+ SystemColumnImpl.getUUIDColumn("TABLEPERMSID", false),\r
+ SystemColumnImpl.getIdentifierColumn("GRANTEE", false),\r
+ SystemColumnImpl.getIdentifierColumn("GRANTOR", false),\r
+ SystemColumnImpl.getUUIDColumn("TABLEID", false),\r
+ SystemColumnImpl.getIndicatorColumn("SELECTPRIV"),\r
+ SystemColumnImpl.getIndicatorColumn("DELETEPRIV"),\r
+ SystemColumnImpl.getIndicatorColumn("INSERTPRIV"),\r
+ SystemColumnImpl.getIndicatorColumn("UPDATEPRIV"),\r
+ SystemColumnImpl.getIndicatorColumn("REFERENCESPRIV"),\r
+ SystemColumnImpl.getIndicatorColumn("TRIGGERPRIV"),\r
+ };\r
+ }\r
+\r
+ /**\r
+ * builds a key row given for a given index number.\r
+ */\r
+ public ExecIndexRow buildIndexKeyRow( int indexNumber,\r
+ PermissionsDescriptor perm) \r
+ throws StandardException\r
+ {\r
+ ExecIndexRow row = null;\r
+ \r
+ switch( indexNumber)\r
+ {\r
+ case GRANTEE_TABLE_GRANTOR_INDEX_NUM:\r
+ // RESOLVE We do not support the FOR GRANT OPTION, so table permission rows are unique on the\r
+ // grantee and table UUID columns. The grantor column will always have the name of the owner of the\r
+ // table. So the index key, used for searching the index, only has grantee and table UUID columns.\r
+ // It does not have a grantor column.\r
+ //\r
+ // If we support FOR GRANT OPTION then there may be multiple table permissions rows for a\r
+ // (grantee, tableID) combination. We must either handle the multiple rows, which is necessary for\r
+ // checking permissions, or add a grantor column to the key, which is necessary for granting or revoking\r
+ // permissions.\r
+ row = getExecutionFactory().getIndexableRow( 2);\r
+ row.setColumn(1, getAuthorizationID( perm.getGrantee()));\r
+ String tableUUIDStr = ((TablePermsDescriptor) perm).getTableUUID().toString();\r
+ row.setColumn(2, new SQLChar(tableUUIDStr));\r
+ break;\r
+ case TABLEPERMSID_INDEX_NUM:\r
+ row = getExecutionFactory().getIndexableRow( 1);\r
+ String tablePermsUUIDStr = perm.getObjectID().toString();\r
+ row.setColumn(1, new SQLChar(tablePermsUUIDStr));\r
+ break;\r
+ case TABLEID_INDEX_NUM:\r
+ row = getExecutionFactory().getIndexableRow( 1);\r
+ tableUUIDStr = ((TablePermsDescriptor) perm).getTableUUID().toString();\r
+ row.setColumn(1, new SQLChar(tableUUIDStr));\r
+ break;\r
+ }\r
+ return row;\r
+ } // end of buildIndexRow\r
+ \r
+ public int getPrimaryKeyIndexNumber()\r
+ {\r
+ return GRANTEE_TABLE_GRANTOR_INDEX_NUM;\r
+ }\r
+\r
+ /**\r
+ * Or a set of permissions in with a row from this catalog table\r
+ *\r
+ * @param row an existing row\r
+ * @param perm a permission descriptor of the appropriate class for this PermissionsCatalogRowFactory class.\r
+ * @param colsChanged An array with one element for each column in row. It is updated to\r
+ * indicate which columns in row were changed\r
+ *\r
+ * @return The number of columns that were changed.\r
+ *\r
+ * @exception StandardException standard error policy\r
+ */\r
+ public int orPermissions( ExecRow row, PermissionsDescriptor perm, boolean[] colsChanged)\r
+ throws StandardException\r
+ {\r
+ TablePermsDescriptor tablePerms = (TablePermsDescriptor) perm;\r
+ int changeCount = 0;\r
+ changeCount += orOnePermission( row, colsChanged, SELECTPRIV_COL_NUM, tablePerms.getSelectPriv());\r
+ changeCount += orOnePermission( row, colsChanged, DELETEPRIV_COL_NUM, tablePerms.getDeletePriv());\r
+ changeCount += orOnePermission( row, colsChanged, INSERTPRIV_COL_NUM, tablePerms.getInsertPriv());\r
+ changeCount += orOnePermission( row, colsChanged, UPDATEPRIV_COL_NUM, tablePerms.getUpdatePriv());\r
+ changeCount += orOnePermission( row, colsChanged, REFERENCESPRIV_COL_NUM, tablePerms.getReferencesPriv());\r
+ changeCount += orOnePermission( row, colsChanged, TRIGGERPRIV_COL_NUM, tablePerms.getTriggerPriv());\r
+\r
+ return changeCount;\r
+ } // end of orPermissions\r
+\r
+ private int orOnePermission( ExecRow row, boolean[] colsChanged, int column, String permission)\r
+ throws StandardException\r
+ {\r
+ if( permission.charAt(0) == 'N')\r
+ return 0;\r
+\r
+ if( SanityManager.DEBUG)\r
+ SanityManager.ASSERT( permission.charAt(0) == 'Y' || permission.charAt(0) == 'y',\r
+ "Invalid permission passed to SYSTABLEPERMSRowFactory.orOnePermission");\r
+ DataValueDescriptor existingPermDVD = row.getColumn( column);\r
+ char existingPerm = existingPermDVD.getString().charAt(0);\r
+ if( existingPerm == 'Y' || existingPerm == permission.charAt(0))\r
+ return 0;\r
+ existingPermDVD.setValue( permission);\r
+ colsChanged[ column - 1] = true;\r
+ return 1;\r
+ } // end of orOnePermission\r
+\r
+ /**\r
+ * Remove a set of permissions from a row from this catalog table\r
+ *\r
+ * @param row an existing row\r
+ * @param perm a permission descriptor of the appropriate class for this PermissionsCatalogRowFactory class.\r
+ * @param colsChanged An array with one element for each column in row. It is updated to\r
+ * indicate which columns in row were changed\r
+ *\r
+ * @return -1 if there are no permissions left in the row, otherwise the number of columns that were changed.\r
+ *\r
+ * @exception StandardException standard error policy\r
+ */\r
+ public int removePermissions( ExecRow row, PermissionsDescriptor perm, boolean[] colsChanged)\r
+ throws StandardException\r
+ {\r
+ TablePermsDescriptor tablePerms = (TablePermsDescriptor) perm;\r
+ int changeCount = 0;\r
+ boolean permissionsLeft =\r
+ ( removeOnePermission( row, colsChanged, SELECTPRIV_COL_NUM, tablePerms.getSelectPriv()) |\r
+ removeOnePermission( row, colsChanged, DELETEPRIV_COL_NUM, tablePerms.getDeletePriv()) |\r
+ removeOnePermission( row, colsChanged, INSERTPRIV_COL_NUM, tablePerms.getInsertPriv()) |\r
+ removeOnePermission( row, colsChanged, UPDATEPRIV_COL_NUM, tablePerms.getUpdatePriv()) |\r
+ removeOnePermission( row, colsChanged, REFERENCESPRIV_COL_NUM, tablePerms.getReferencesPriv()) |\r
+ removeOnePermission( row, colsChanged, TRIGGERPRIV_COL_NUM, tablePerms.getTriggerPriv()));\r
+ if( ! permissionsLeft)\r
+ return -1;\r
+ for( int i = 0; i < colsChanged.length; i++)\r
+ {\r
+ if( colsChanged[ i])\r
+ changeCount++;\r
+ }\r
+ return changeCount;\r
+ } // end of removePermissions\r
+\r
+ private boolean removeOnePermission( ExecRow row, boolean[] colsChanged, int column, String permission)\r
+ throws StandardException\r
+ {\r
+ DataValueDescriptor existingPermDVD = row.getColumn( column);\r
+ char existingPerm = existingPermDVD.getString().charAt(0);\r
+\r
+ if( permission.charAt(0) == 'N') // Don't remove this one\r
+ return existingPerm != 'N'; // The grantee still has some permissions on this table\r
+ if( SanityManager.DEBUG)\r
+ SanityManager.ASSERT( permission.charAt(0) == 'Y' || permission.charAt(0) == 'y',\r
+ "Invalid permission passed to SYSTABLEPERMSRowFactory.removeOnePermission");\r
+ if( existingPerm != 'N')\r
+ {\r
+ existingPermDVD.setValue( "N");\r
+ colsChanged[ column - 1] = true;\r
+ }\r
+ return false;\r
+ } // end of removeOnePermission\r
+ \r
+ /** \r
+ * @see PermissionsCatalogRowFactory#setUUIDOfThePassedDescriptor\r
+ */\r
+ public void setUUIDOfThePassedDescriptor(ExecRow row, PermissionsDescriptor perm)\r
+ throws StandardException\r
+ {\r
+ DataValueDescriptor existingPermDVD = row.getColumn(TABLEPERMSID_COL_NUM);\r
+ perm.setUUID(getUUIDFactory().recreateUUID(existingPermDVD.getString()));\r
+ }\r
+}\r