diff options
author | Lionel Elie Mamane <lionel@mamane.lu> | 2011-09-16 17:25:46 +0200 |
---|---|---|
committer | Lionel Elie Mamane <lionel@mamane.lu> | 2011-11-17 21:15:30 +0100 |
commit | 4ab98d466333ff797a4911bc4dfe51761a487118 (patch) | |
tree | dc5eb535b8d911cc04c29c10ba9c4e2dbd9f4e6a /connectivity/source | |
parent | 878f6b5bc0ab70e66b3ba91b7d069dc78700cd20 (diff) |
Overhaul DatabaseMetaData::getTablePrivileges
Diffstat (limited to 'connectivity/source')
-rw-r--r-- | connectivity/source/drivers/postgresql/pq_databasemetadata.cxx | 153 |
1 files changed, 47 insertions, 106 deletions
diff --git a/connectivity/source/drivers/postgresql/pq_databasemetadata.cxx b/connectivity/source/drivers/postgresql/pq_databasemetadata.cxx index 530b52c2ba3b..0141454f885b 100644 --- a/connectivity/source/drivers/postgresql/pq_databasemetadata.cxx +++ b/connectivity/source/drivers/postgresql/pq_databasemetadata.cxx @@ -821,6 +821,10 @@ sal_Bool DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( ) throw (SQL } +// LEM TODO: positioned (through cursor) updates and deletes seem +// to be supported; see {UPDATE,DELETE} /table/ (...) WHERE CURRENT OF /cursor_name/" syntax +// and http://www.postgresql.org/docs/9.1/static/view-pg-cursors.html +// http://www.postgresql.org/docs/9.1/static/libpq-example.html actually uses a cursor :) sal_Bool DatabaseMetaData::supportsPositionedDelete( ) throw (SQLException, RuntimeException) { // LEM: jdbc driver says not, although the comments in it seem old @@ -1008,7 +1012,7 @@ sal_Int32 DatabaseMetaData::getMaxCatalogNameLength( ) throw (SQLException, Run sal_Int32 DatabaseMetaData::getMaxRowSize( ) throw (SQLException, RuntimeException) { - // jdbc driver seays 1GB, but http://www.postgresql.org/about/ says 1.6TB + // jdbc driver says 1GB, but http://www.postgresql.org/about/ says 1.6TB // and that 1GB is the maximum _field_ size // The row limit does not fit into a sal_Int32 return 0; @@ -1643,68 +1647,19 @@ static void columnMetaData2DatabaseTypeDescription( const OUString& columnNamePattern ) throw (SQLException, RuntimeException) { //LEM TODO: implement! See JDBC driver + // In the meantime, maybe better to throw exception SQLException with + // SQLState == "IM001" MutexGuard guard( m_refMutex->mutex ); checkClosed(); return new SequenceResultSet( m_refMutex, *this, Sequence< OUString >(), Sequence< Sequence< Any > > (), m_pSettings->tc ); } -static void addPrivilegesToVector( - sal_Int32 privilege, const OUString &catalog, const OUString & schema, - const OUString &tableName, const OUString &grantor, const OUString &grantee, - bool grantable, SequenceAnyVector &vec ) -{ - Statics & statics = getStatics(); - for( int index = 1; index <= PRIVILEGE_MAX ; index = index << 1 ) - { - OUString privname; - switch( privilege & index ) - { - case PRIVILEGE_SELECT: - privname = statics.SELECT; break; - case PRIVILEGE_UPDATE: - privname = statics.UPDATE; break; - case PRIVILEGE_INSERT: - privname = statics.INSERT; break; - case PRIVILEGE_DELETE: - privname = statics.DELETE; break; - case PRIVILEGE_RULE: - privname = statics.RULE; break; - case PRIVILEGE_REFERENCES: - privname = statics.REFERENCES; break; - case PRIVILEGE_TRIGGER: - privname = statics.TRIGGER; break; - case PRIVILEGE_EXECUTE: - privname = statics.EXECUTE; break; - case PRIVILEGE_USAGE: - privname = statics.USAGE; break; - case PRIVILEGE_CREATE: - privname = statics.CREATE; break; - case PRIVILEGE_TEMPORARY: - privname = statics.TEMPORARY; break; - default: - break; - } - - Sequence< Any > seq( 7 ); - seq[0] <<= catalog; - seq[1] <<= schema; - seq[2] <<= tableName; - seq[3] <<= grantor; - seq[4] <<= grantee; - seq[5] <<= privname; - seq[6] <<= (grantable ? statics.YES : statics.NO ); - vec.push_back( seq ); - } -} - - ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getTablePrivileges( const ::com::sun::star::uno::Any& catalog, const OUString& schemaPattern, const OUString& tableNamePattern ) throw (SQLException, RuntimeException) { - // LEM TODO: review MutexGuard guard( m_refMutex->mutex ); checkClosed(); @@ -1718,68 +1673,54 @@ static void addPrivilegesToVector( log( m_pSettings, LogLevel::INFO, buf.makeStringAndClear() ); } - // algorithm - - // get the pg_class.relact item for the concrete table - // get userid for username from pg_shadow (or pg_user view) - // get the group names mentioned in pg_class.relact from pg_group - // identify, which groups the current user belongs to - // calculate the union of all permissions (1 public, 1 user, n groups) - - // 1. TABLE_CAT string => table catalog (may be NULL ) - // 2. TABLE_SCHEM string => table schema (may be NULL ) - // 3. TABLE_NAME string => table name - // 4. GRANTOR => grantor of access (may be NULL ) - // 5. GRANTEE string => grantee of access - // 6. PRIVILEGE string => name of access (SELECT, INSERT, UPDATE, REFERENCES, ...) - // 7. IS_GRANTABLE string => "YES" if grantee is permitted to grant to - // others; "NO" if not; NULL if unknown - Reference< XPreparedStatement > statement = m_origin->prepareStatement( ASCII_STR( - "SELECT pg_namespace.nspname, " - "pg_class.relname, " - "pg_class.relacl, " - "pg_user.usename " - "FROM pg_class, pg_user, pg_namespace " - "WHERE pg_class.relowner = pg_user.usesysid " - "AND ( pg_class.relkind = 'r' OR pg_class.relkind = 'v' ) " - "AND pg_class.relnamespace = pg_namespace.oid " - "AND pg_namespace.nspname LIKE ? " - "AND pg_class.relname LIKE ?" - "ORDER BY pg_namespace.nspname || pg_class.relname " - ) ); + " WITH RECURSIVE roles AS (" + " SELECT oid, rolname, rolinherit, rolsuper FROM pg_catalog.pg_roles" + " UNION ALL" + " VALUES (0, 'PUBLIC', TRUE, FALSE)" + " ), direct_privs_oids AS (" + " SELECT c.relname, c.relnamespace, c.relowner, (aclexplode(c.relacl)).*" + " FROM pg_catalog.pg_class c" + " WHERE c.relkind IN ('r', 'v') AND c.relname LIKE ?" + " UNION ALL" + " SELECT c.relname, c.relnamespace, c.relowner, c.relowner, c.relowner, p.privilege, TRUE" + " FROM pg_catalog.pg_class c," + " (VALUES ('SELECT'), ('INSERT'), ('UPDATE'), ('DELETE'), ('TRUNCATE'), ('REFERENCES'), ('TRIGGER')) p (privilege)" + " WHERE c.relkind IN ('r', 'v') AND c.relacl IS NULL AND c.relname LIKE ?" + " ), direct_privs AS (" + " SELECT dpo.relname, pn.nspname, dpo.relowner, pr_grantor.rolname AS grantor, dpo.grantee, dpo.privilege_type, dpo.is_grantable" + " FROM direct_privs_oids dpo INNER JOIN roles pr_grantor ON dpo.grantor = pr_grantor.oid" + " INNER JOIN pg_catalog.pg_namespace pn ON pn.oid = dpo.relnamespace" + " WHERE pn.nspname LIKE ?" + " ), memberships(roleid, membership) AS (" + " SELECT pr.oid, 0" + " FROM pg_catalog.pg_roles pr" + " UNION" + " SELECT pr.oid, pr.oid" + " FROM roles pr" + " UNION" + " SELECT m.roleid, pam.roleid" + " FROM roles pr INNER JOIN pg_catalog.pg_auth_members pam ON pr.oid = pam.member" + " INNER JOIN memberships m ON pam.member = m.membership" + " WHERE pr.rolinherit" + " )" + " SELECT current_database() AS TABLE_CAT, dp.nspname AS TABLE_SCHEM, dp.relname AS TABLE_NAME," + " dp.grantor AS GRANTOR, pr_grantee.rolname AS GRANTEE, dp.privilege_type AS PRIVILEGE," + " CASE WHEN dp.is_grantable OR (dp.relowner = pr_grantee.oid) THEN 'YES' ELSE 'NO' END AS IS_GRANTABLE" + " FROM direct_privs dp INNER JOIN memberships m ON dp.grantee = m. membership" + " INNER JOIN roles pr_grantee ON pr_grantee.oid = m.roleid" + " ORDER BY dp.nspname, dp.relname, dp.privilege_type" + )); Reference< XParameters > parameters( statement, UNO_QUERY_THROW ); - parameters->setString( 1 , schemaPattern ); + parameters->setString( 3 , schemaPattern ); + parameters->setString( 1 , tableNamePattern ); parameters->setString( 2 , tableNamePattern ); Reference< XResultSet > rs = statement->executeQuery(); - Reference< XRow > xRow( rs, UNO_QUERY_THROW ); - SequenceAnyVector vec; - while( rs->next() ) - { - // TODO calculate privileges ! - sal_Int32 privilege = 0; - privilege = - PRIVILEGE_SELECT | PRIVILEGE_UPDATE | PRIVILEGE_INSERT | - PRIVILEGE_DELETE | PRIVILEGE_RULE | PRIVILEGE_REFERENCES | - PRIVILEGE_TRIGGER| PRIVILEGE_EXECUTE| PRIVILEGE_USAGE | - PRIVILEGE_CREATE |PRIVILEGE_TEMPORARY; - - addPrivilegesToVector( privilege, - m_pSettings->catalog, - xRow->getString( 1 ), - xRow->getString( 2 ), - xRow->getString( 4 ), - m_pSettings->user, - m_pSettings->user == xRow->getString( 4 ), - vec ); - } - return new SequenceResultSet( - m_refMutex, *this, getStatics().tablePrivilegesNames, - Sequence< Sequence< Any > > ( &vec[0], vec.size() ), m_pSettings->tc ); + return rs; } ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getBestRowIdentifier( |