1 /*************************************************************************
3 * $RCSfile: pq_databasemetadata.cxx,v $
5 * $Revision: 1.1.2.11 $
7 * last change: $Author: jbu $ $Date: 2007/02/15 20:04:47 $
9 * The Contents of this file are made available subject to the terms of
10 * either of the following licenses
12 * - GNU Lesser General Public License Version 2.1
13 * - Sun Industry Standards Source License Version 1.1
15 * Sun Microsystems Inc., October, 2000
17 * GNU Lesser General Public License Version 2.1
18 * =============================================
19 * Copyright 2000 by Sun Microsystems, Inc.
20 * 901 San Antonio Road, Palo Alto, CA 94303, USA
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License version 2.1, as published by the Free Software Foundation.
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * Lesser General Public License for more details.
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this library; if not, write to the Free Software
33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
37 * Sun Industry Standards Source License Version 1.1
38 * =================================================
39 * The contents of this file are subject to the Sun Industry Standards
40 * Source License Version 1.1 (the "License"); You may not use this file
41 * except in compliance with the License. You may obtain a copy of the
42 * License at http://www.openoffice.org/license.html.
44 * Software provided under this License is provided on an "AS IS" basis,
45 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
46 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
47 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
48 * See the License for the specific provisions governing your rights and
49 * obligations concerning the Software.
51 * The Initial Developer of the Original Code is: Joerg Budischewski
53 * Copyright: 2000 by Sun Microsystems, Inc.
55 * All Rights Reserved.
57 * Contributor(s): Joerg Budischewski
60 ************************************************************************/
62 #include "pq_databasemetadata.hxx"
63 #include "pq_driver.hxx"
64 #include "pq_sequenceresultset.hxx"
65 #include "pq_statics.hxx"
66 #include "pq_tools.hxx"
68 #include <rtl/ustrbuf.hxx>
70 #include<com/sun/star/sdbc/TransactionIsolation.hpp>
71 #include<com/sun/star/sdbc/ResultSetType.hpp>
72 #include<com/sun/star/sdbc/XPreparedStatement.hpp>
73 #include<com/sun/star/sdbc/XParameters.hpp>
74 #include<com/sun/star/sdbc/DataType.hpp>
75 #include<com/sun/star/sdbc/IndexType.hpp>
76 #include<com/sun/star/sdbc/ColumnValue.hpp>
77 #include<com/sun/star/sdbc/ColumnSearch.hpp>
79 using ::osl::MutexGuard
;
81 using ::rtl::OUString
;
83 using com::sun::star::sdbc::SQLException
;
84 using com::sun::star::sdbc::XStatement
;
85 using com::sun::star::sdbc::XResultSet
;
86 using com::sun::star::sdbc::XRow
;
87 using com::sun::star::sdbc::XCloseable
;
88 using com::sun::star::sdbc::XParameters
;
89 using com::sun::star::sdbc::XPreparedStatement
;
90 // using com::sun::star::sdbc::IndexType;
91 // using com::sun::star::sdbc::DataType;
93 using com::sun::star::uno::RuntimeException
;
94 using com::sun::star::uno::Sequence
;
96 using com::sun::star::uno::Reference
;
97 using com::sun::star::uno::Sequence
;
98 using com::sun::star::uno::Any
;
99 using com::sun::star::uno::makeAny
;
100 using com::sun::star::uno::UNO_QUERY
;
102 namespace pq_sdbc_driver
107 com::sun::star::uno::Sequence
< com::sun::star::uno::Any
>,
108 Allocator
< com::sun::star::uno::Sequence
< com::sun::star::uno::Any
> >
112 #define ASCII_STR(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
114 static const int MAX_COLUMNS_IN_GROUPBY
= 16;
115 static const int MAX_COLUMNS_IN_INDEX
= 32;
116 static const int MAX_COLUMNS_IN_ORDER_BY
= 16;
117 static const int MAX_COLUMNS_IN_SELECT
= 1024;
118 static const int MAX_IDENTIFIER_LENGTH
= 63;
119 static const int MAX_COLUMNS_IN_TABLE
= 1024;
120 static const int MAX_CONNECTIONS
= 0xffff;
121 static const int MAX_STATEMENTS
= 0xffff;
122 static const int MAX_STATEMENT_LENGTH
= -1;
123 static const int MAX_TABLES_IN_SELECT
= 0xffff;
124 static const int MAX_USER_NAME_LENGTH
= MAX_IDENTIFIER_LENGTH
;
127 // alphabetically ordered !
128 static const int PRIVILEGE_CREATE
= 0x1;
129 static const int PRIVILEGE_DELETE
= 0x2;
130 static const int PRIVILEGE_EXECUTE
= 0x4;
131 static const int PRIVILEGE_INSERT
= 0x8;
132 static const int PRIVILEGE_REFERENCES
= 0x10;
133 static const int PRIVILEGE_RULE
= 0x20;
134 static const int PRIVILEGE_SELECT
= 0x40;
135 static const int PRIVILEGE_TEMPORARY
= 0x80;
136 static const int PRIVILEGE_TRIGGER
= 0x100;
137 static const int PRIVILEGE_UPDATE
= 0x200;
138 static const int PRIVILEGE_USAGE
= 0x400;
139 static const int PRIVILEGE_MAX
= PRIVILEGE_USAGE
;
141 void DatabaseMetaData::checkClosed()
142 throw (SQLException
, RuntimeException
)
146 DatabaseMetaData::DatabaseMetaData(
147 const ::rtl::Reference
< RefCountedMutex
> & refMutex
,
148 const ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> & origin
,
149 ConnectionSettings
*pSettings
)
150 : m_pSettings( pSettings
),
152 m_refMutex( refMutex
)
158 sal_Bool
DatabaseMetaData::allProceduresAreCallable( ) throw (SQLException
, RuntimeException
)
164 sal_Bool
DatabaseMetaData::allTablesAreSelectable( ) throw (SQLException
, RuntimeException
)
169 OUString
DatabaseMetaData::getURL( ) throw (SQLException
, RuntimeException
)
175 OUString
DatabaseMetaData::getUserName( ) throw (SQLException
, RuntimeException
)
177 return m_pSettings
->user
;
180 sal_Bool
DatabaseMetaData::isReadOnly( ) throw (SQLException
, RuntimeException
)
186 sal_Bool
DatabaseMetaData::nullsAreSortedHigh( ) throw (SQLException
, RuntimeException
)
191 sal_Bool
DatabaseMetaData::nullsAreSortedLow( ) throw (SQLException
, RuntimeException
)
193 return ! nullsAreSortedHigh();
196 sal_Bool
DatabaseMetaData::nullsAreSortedAtStart( ) throw (SQLException
, RuntimeException
)
198 return ! nullsAreSortedHigh();
201 sal_Bool
DatabaseMetaData::nullsAreSortedAtEnd( ) throw (SQLException
, RuntimeException
)
203 return nullsAreSortedHigh();
206 OUString
DatabaseMetaData::getDatabaseProductName( ) throw (SQLException
, RuntimeException
)
208 return ASCII_STR( "postgresql");
211 OUString
DatabaseMetaData::getDatabaseProductVersion( ) throw (SQLException
, RuntimeException
)
213 return ASCII_STR( POSTGRESQL_VERSION
);
215 OUString
DatabaseMetaData::getDriverName( ) throw (SQLException
, RuntimeException
)
217 return ASCII_STR( "postgresql-sdbc" );
220 OUString
DatabaseMetaData::getDriverVersion( ) throw (SQLException
, RuntimeException
)
222 return ASCII_STR( PQ_SDBC_DRIVER_VERSION
);
225 sal_Int32
DatabaseMetaData::getDriverMajorVersion( ) throw (RuntimeException
)
227 return PQ_SDBC_MAJOR
;
230 sal_Int32
DatabaseMetaData::getDriverMinorVersion( ) throw (RuntimeException
)
232 return PQ_SDBC_MINOR
;
235 sal_Bool
DatabaseMetaData::usesLocalFiles( ) throw (SQLException
, RuntimeException
)
240 sal_Bool
DatabaseMetaData::usesLocalFilePerTable( ) throw (SQLException
, RuntimeException
)
245 sal_Bool
DatabaseMetaData::supportsMixedCaseIdentifiers( ) throw (SQLException
, RuntimeException
)
250 sal_Bool
DatabaseMetaData::storesUpperCaseIdentifiers( ) throw (SQLException
, RuntimeException
)
255 sal_Bool
DatabaseMetaData::storesLowerCaseIdentifiers( ) throw (SQLException
, RuntimeException
)
261 sal_Bool
DatabaseMetaData::storesMixedCaseIdentifiers( ) throw (SQLException
, RuntimeException
)
267 sal_Bool
DatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
)
272 sal_Bool
DatabaseMetaData::storesUpperCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
)
278 sal_Bool
DatabaseMetaData::storesLowerCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
)
284 sal_Bool
DatabaseMetaData::storesMixedCaseQuotedIdentifiers( ) throw (SQLException
, RuntimeException
)
290 OUString
DatabaseMetaData::getIdentifierQuoteString( ) throw (SQLException
, RuntimeException
)
292 return ASCII_STR( "\"" );
295 OUString
DatabaseMetaData::getSQLKeywords( ) throw (SQLException
, RuntimeException
)
308 OUString
DatabaseMetaData::getNumericFunctions( ) throw (SQLException
, RuntimeException
)
314 OUString
DatabaseMetaData::getStringFunctions( ) throw (SQLException
, RuntimeException
)
320 OUString
DatabaseMetaData::getSystemFunctions( ) throw (SQLException
, RuntimeException
)
325 OUString
DatabaseMetaData::getTimeDateFunctions( ) throw (SQLException
, RuntimeException
)
330 OUString
DatabaseMetaData::getSearchStringEscape( ) throw (SQLException
, RuntimeException
)
332 return ASCII_STR( "\\" );
334 OUString
DatabaseMetaData::getExtraNameCharacters( ) throw (SQLException
, RuntimeException
)
340 sal_Bool
DatabaseMetaData::supportsAlterTableWithAddColumn( ) throw (SQLException
, RuntimeException
)
345 sal_Bool
DatabaseMetaData::supportsAlterTableWithDropColumn( ) throw (SQLException
, RuntimeException
)
350 sal_Bool
DatabaseMetaData::supportsColumnAliasing( ) throw (SQLException
, RuntimeException
)
355 sal_Bool
DatabaseMetaData::nullPlusNonNullIsNull( ) throw (SQLException
, RuntimeException
)
360 sal_Bool
DatabaseMetaData::supportsTypeConversion( ) throw (SQLException
, RuntimeException
) // TODO, DON'T KNOW
365 sal_Bool
DatabaseMetaData::supportsConvert( sal_Int32 fromType
, sal_Int32 toType
) throw (SQLException
, RuntimeException
) // TODO
370 sal_Bool
DatabaseMetaData::supportsTableCorrelationNames( ) throw (SQLException
, RuntimeException
) // TODO, don't know
376 sal_Bool
DatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw (SQLException
, RuntimeException
) // TODO, don't know
381 sal_Bool
DatabaseMetaData::supportsExpressionsInOrderBy( ) throw (SQLException
, RuntimeException
)
386 sal_Bool
DatabaseMetaData::supportsOrderByUnrelated( ) throw (SQLException
, RuntimeException
)
391 sal_Bool
DatabaseMetaData::supportsGroupBy( ) throw (SQLException
, RuntimeException
)
396 sal_Bool
DatabaseMetaData::supportsGroupByUnrelated( ) throw (SQLException
, RuntimeException
) // TODO, DONT know
402 sal_Bool
DatabaseMetaData::supportsGroupByBeyondSelect( ) throw (SQLException
, RuntimeException
) // TODO, DON'T know
408 sal_Bool
DatabaseMetaData::supportsLikeEscapeClause( ) throw (SQLException
, RuntimeException
)
413 sal_Bool
DatabaseMetaData::supportsMultipleResultSets( ) throw (SQLException
, RuntimeException
)
418 sal_Bool
DatabaseMetaData::supportsMultipleTransactions( ) throw (SQLException
, RuntimeException
)
423 sal_Bool
DatabaseMetaData::supportsNonNullableColumns( ) throw (SQLException
, RuntimeException
)
429 sal_Bool
DatabaseMetaData::supportsMinimumSQLGrammar( ) throw (SQLException
, RuntimeException
)
434 sal_Bool
DatabaseMetaData::supportsCoreSQLGrammar( ) throw (SQLException
, RuntimeException
)
439 sal_Bool
DatabaseMetaData::supportsExtendedSQLGrammar( ) throw (SQLException
, RuntimeException
)
444 sal_Bool
DatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw (SQLException
, RuntimeException
)
449 sal_Bool
DatabaseMetaData::supportsANSI92IntermediateSQL( ) throw (SQLException
, RuntimeException
)
454 sal_Bool
DatabaseMetaData::supportsANSI92FullSQL( ) throw (SQLException
, RuntimeException
)
459 sal_Bool
DatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw (SQLException
, RuntimeException
)
465 sal_Bool
DatabaseMetaData::supportsOuterJoins( ) throw (SQLException
, RuntimeException
)
470 sal_Bool
DatabaseMetaData::supportsFullOuterJoins( ) throw (SQLException
, RuntimeException
)
475 sal_Bool
DatabaseMetaData::supportsLimitedOuterJoins( ) throw (SQLException
, RuntimeException
)
481 OUString
DatabaseMetaData::getSchemaTerm( ) throw (SQLException
, RuntimeException
)
483 return ASCII_STR( "SCHEMA" );
486 OUString
DatabaseMetaData::getProcedureTerm( ) throw (SQLException
, RuntimeException
)
492 OUString
DatabaseMetaData::getCatalogTerm( ) throw (SQLException
, RuntimeException
)
494 // TODO is this correct ?
495 return ASCII_STR( "DATABASE" );
498 sal_Bool
DatabaseMetaData::isCatalogAtStart( ) throw (SQLException
, RuntimeException
) // TODO don't know
504 OUString
DatabaseMetaData::getCatalogSeparator( ) throw (SQLException
, RuntimeException
)
507 return ASCII_STR( "." );
510 sal_Bool
DatabaseMetaData::supportsSchemasInDataManipulation( ) throw (SQLException
, RuntimeException
)
515 sal_Bool
DatabaseMetaData::supportsSchemasInProcedureCalls( ) throw (SQLException
, RuntimeException
)
520 sal_Bool
DatabaseMetaData::supportsSchemasInTableDefinitions( ) throw (SQLException
, RuntimeException
)
525 sal_Bool
DatabaseMetaData::supportsSchemasInIndexDefinitions( ) throw (SQLException
, RuntimeException
)
530 sal_Bool
DatabaseMetaData::supportsSchemasInPrivilegeDefinitions( ) throw (SQLException
, RuntimeException
)
535 sal_Bool
DatabaseMetaData::supportsCatalogsInDataManipulation( ) throw (SQLException
, RuntimeException
)
540 sal_Bool
DatabaseMetaData::supportsCatalogsInProcedureCalls( ) throw (SQLException
, RuntimeException
)
545 sal_Bool
DatabaseMetaData::supportsCatalogsInTableDefinitions( ) throw (SQLException
, RuntimeException
)
551 sal_Bool
DatabaseMetaData::supportsCatalogsInIndexDefinitions( ) throw (SQLException
, RuntimeException
)
557 sal_Bool
DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( ) throw (SQLException
, RuntimeException
)
563 sal_Bool
DatabaseMetaData::supportsPositionedDelete( ) throw (SQLException
, RuntimeException
)
569 sal_Bool
DatabaseMetaData::supportsPositionedUpdate( ) throw (SQLException
, RuntimeException
)
576 sal_Bool
DatabaseMetaData::supportsSelectForUpdate( ) throw (SQLException
, RuntimeException
)
583 sal_Bool
DatabaseMetaData::supportsStoredProcedures( ) throw (SQLException
, RuntimeException
)
590 sal_Bool
DatabaseMetaData::supportsSubqueriesInComparisons( ) throw (SQLException
, RuntimeException
)
596 sal_Bool
DatabaseMetaData::supportsSubqueriesInExists( ) throw (SQLException
, RuntimeException
)
602 sal_Bool
DatabaseMetaData::supportsSubqueriesInIns( ) throw (SQLException
, RuntimeException
)
608 sal_Bool
DatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw (SQLException
, RuntimeException
)
614 sal_Bool
DatabaseMetaData::supportsCorrelatedSubqueries( ) throw (SQLException
, RuntimeException
)
619 sal_Bool
DatabaseMetaData::supportsUnion( ) throw (SQLException
, RuntimeException
)
624 sal_Bool
DatabaseMetaData::supportsUnionAll( ) throw (SQLException
, RuntimeException
)
629 sal_Bool
DatabaseMetaData::supportsOpenCursorsAcrossCommit( ) throw (SQLException
, RuntimeException
)
635 sal_Bool
DatabaseMetaData::supportsOpenCursorsAcrossRollback( ) throw (SQLException
, RuntimeException
)
641 sal_Bool
DatabaseMetaData::supportsOpenStatementsAcrossCommit( ) throw (SQLException
, RuntimeException
)
646 sal_Bool
DatabaseMetaData::supportsOpenStatementsAcrossRollback( ) throw (SQLException
, RuntimeException
)
652 sal_Int32
DatabaseMetaData::getMaxBinaryLiteralLength( ) throw (SQLException
, RuntimeException
)
658 sal_Int32
DatabaseMetaData::getMaxCharLiteralLength( ) throw (SQLException
, RuntimeException
)
663 sal_Int32
DatabaseMetaData::getMaxColumnNameLength( ) throw (SQLException
, RuntimeException
) //TODO, don't know
665 return MAX_IDENTIFIER_LENGTH
;
668 sal_Int32
DatabaseMetaData::getMaxColumnsInGroupBy( ) throw (SQLException
, RuntimeException
) //TODO, don't know
670 return MAX_COLUMNS_IN_GROUPBY
;
673 sal_Int32
DatabaseMetaData::getMaxColumnsInIndex( ) throw (SQLException
, RuntimeException
) //TODO, don't know
675 return MAX_COLUMNS_IN_INDEX
;
678 sal_Int32
DatabaseMetaData::getMaxColumnsInOrderBy( ) throw (SQLException
, RuntimeException
) //TODO, don't know
680 return MAX_COLUMNS_IN_ORDER_BY
;
683 sal_Int32
DatabaseMetaData::getMaxColumnsInSelect( ) throw (SQLException
, RuntimeException
) //TODO, don't know
685 return MAX_COLUMNS_IN_SELECT
;
688 sal_Int32
DatabaseMetaData::getMaxColumnsInTable( ) throw (SQLException
, RuntimeException
) //TODO, don't know
690 return MAX_COLUMNS_IN_TABLE
;
693 sal_Int32
DatabaseMetaData::getMaxConnections( ) throw (SQLException
, RuntimeException
) //TODO, don't know
695 return MAX_CONNECTIONS
;
698 sal_Int32
DatabaseMetaData::getMaxCursorNameLength( ) throw (SQLException
, RuntimeException
) //TODO, don't know
700 return MAX_IDENTIFIER_LENGTH
;
703 sal_Int32
DatabaseMetaData::getMaxIndexLength( ) throw (SQLException
, RuntimeException
) //TODO, don't know
705 return MAX_IDENTIFIER_LENGTH
;
708 sal_Int32
DatabaseMetaData::getMaxSchemaNameLength( ) throw (SQLException
, RuntimeException
)
710 return MAX_IDENTIFIER_LENGTH
;
713 sal_Int32
DatabaseMetaData::getMaxProcedureNameLength( ) throw (SQLException
, RuntimeException
)
715 return MAX_IDENTIFIER_LENGTH
;
718 sal_Int32
DatabaseMetaData::getMaxCatalogNameLength( ) throw (SQLException
, RuntimeException
)
720 return MAX_IDENTIFIER_LENGTH
;
723 sal_Int32
DatabaseMetaData::getMaxRowSize( ) throw (SQLException
, RuntimeException
)
728 sal_Bool
DatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw (SQLException
, RuntimeException
)
733 sal_Int32
DatabaseMetaData::getMaxStatementLength( ) throw (SQLException
, RuntimeException
) //TODO, don't know
735 return MAX_STATEMENT_LENGTH
;
738 sal_Int32
DatabaseMetaData::getMaxStatements( ) throw (SQLException
, RuntimeException
) //TODO, don't know
740 return MAX_STATEMENTS
;
743 sal_Int32
DatabaseMetaData::getMaxTableNameLength( ) throw (SQLException
, RuntimeException
)
745 return MAX_IDENTIFIER_LENGTH
;
748 sal_Int32
DatabaseMetaData::getMaxTablesInSelect( ) throw (SQLException
, RuntimeException
)
750 return MAX_TABLES_IN_SELECT
;
753 sal_Int32
DatabaseMetaData::getMaxUserNameLength( ) throw (SQLException
, RuntimeException
)
755 return MAX_USER_NAME_LENGTH
;
758 sal_Int32
DatabaseMetaData::getDefaultTransactionIsolation( ) throw (SQLException
, RuntimeException
)
760 return com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED
;
763 sal_Bool
DatabaseMetaData::supportsTransactions( ) throw (SQLException
, RuntimeException
)
768 sal_Bool
DatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level
) throw (SQLException
, RuntimeException
)
773 sal_Bool
DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions( )
774 throw (SQLException
, RuntimeException
)
779 sal_Bool
DatabaseMetaData::supportsDataManipulationTransactionsOnly( ) throw (SQLException
, RuntimeException
)
784 sal_Bool
DatabaseMetaData::dataDefinitionCausesTransactionCommit( ) throw (SQLException
, RuntimeException
)
790 sal_Bool
DatabaseMetaData::dataDefinitionIgnoredInTransactions( ) throw (SQLException
, RuntimeException
)
795 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getProcedures(
796 const ::com::sun::star::uno::Any
& catalog
,
797 const OUString
& schemaPattern
,
798 const OUString
& procedureNamePattern
) throw (SQLException
, RuntimeException
)
800 // 1. PROCEDURE_CAT string => procedure catalog (may be NULL )
801 // 2. PROCEDURE_SCHEM string => procedure schema (may be NULL )
802 // 3. PROCEDURE_NAME string => procedure name
803 // 4. reserved for future use
804 // 5. reserved for future use
805 // 6. reserved for future use
806 // 7. REMARKS string => explanatory comment on the procedure
807 // 8. PROCEDURE_TYPE short => kind of procedure:
808 // * UNKNOWN - May return a result
809 // * NO - Does not return a result
810 // * RETURN - Returns a result
812 MutexGuard
guard( m_refMutex
->mutex
);
814 return new SequenceResultSet(
815 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
818 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getProcedureColumns(
819 const ::com::sun::star::uno::Any
& catalog
,
820 const OUString
& schemaPattern
,
821 const OUString
& procedureNamePattern
,
822 const OUString
& columnNamePattern
) throw (SQLException
, RuntimeException
)
824 MutexGuard
guard( m_refMutex
->mutex
);
826 return new SequenceResultSet(
827 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
830 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTables(
831 const ::com::sun::star::uno::Any
& catalog
,
832 const OUString
& schemaPattern
,
833 const OUString
& tableNamePattern
,
834 const ::com::sun::star::uno::Sequence
< OUString
>& types
)
835 throw (SQLException
, RuntimeException
)
837 Statics
&statics
= getStatics();
839 MutexGuard
guard( m_refMutex
->mutex
);
842 if( isLog( m_pSettings
, LogLevel::INFO
) )
844 rtl::OUStringBuffer
buf( 128 );
845 buf
.appendAscii( "DatabaseMetaData::getTables got called with " );
846 buf
.append( schemaPattern
);
847 buf
.appendAscii( "." );
848 buf
.append( tableNamePattern
);
849 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
851 // ignore catalog, as a single pq connection does not support multiple catalogs
853 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
856 "DISTINCT ON (pg_namespace.nspname, relname ) " // avoid duplicates (pg_settings !)
857 "pg_namespace.nspname, relname, relkind, pg_description.description "
858 "FROM pg_namespace, pg_class LEFT JOIN pg_description ON pg_class.oid = pg_description.objoid "
859 "WHERE relnamespace = pg_namespace.oid "
860 "AND ( relkind = 'r' OR relkind = 'v') "
861 "AND pg_namespace.nspname LIKE ? "
862 "AND relname LIKE ? "
863 // "ORDER BY pg_namespace.nspname || relname"
866 Reference
< XParameters
> parameters( statement
, UNO_QUERY
);
867 parameters
->setString( 1 , schemaPattern
);
868 parameters
->setString( 2 , tableNamePattern
);
870 Reference
< XResultSet
> rs
= statement
->executeQuery();
871 Reference
< XRow
> xRow( rs
, UNO_QUERY
);
872 SequenceAnyVector vec
;
876 Sequence
< Any
> row( 5 );
878 row
[0] <<= m_pSettings
->catalog
;
879 row
[1] <<= xRow
->getString( 1 );
880 row
[2] <<= xRow
->getString( 2 );
881 OUString type
= xRow
->getString(3);
882 if( 0 == type
.compareToAscii( "r" ) )
884 if( 0 == xRow
->getString(1).compareToAscii( "pg_catalog" ) )
886 row
[3] <<= statics
.SYSTEM_TABLE
;
890 row
[3] <<= statics
.TABLE
;
893 else if( 0 == type
.compareToAscii( "v" ) )
895 row
[3] <<= statics
.VIEW
;
899 row
[3] <<= statics
.UNKNOWN
;
901 row
[4] <<= xRow
->getString(4);
903 // no description in postgresql AFAIK
904 vec
.push_back( row
);
906 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
910 return new SequenceResultSet(
911 m_refMutex
, *this, statics
.tablesRowNames
,
912 Sequence
< Sequence
< Any
> > ( &vec
[0],vec
.size() ), m_pSettings
->tc
);
915 struct SortInternalSchemasLastAndPublicFirst
917 bool operator () ( const Sequence
< Any
> & a
, const Sequence
< Any
> & b
)
924 if( valueA
.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 )
928 else if( valueB
.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 )
932 else if( valueA
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) &&
933 valueB
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) )
935 ret
= valueA
.compareTo( valueB
) < 0; // sorts equal !
937 else if( valueA
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ))
939 ret
= false; // sorts last !
941 else if( valueB
.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "pg_" ) ) )
943 ret
= true; // sorts dorst !
948 ret
= (valueA
.compareTo( valueB
) < 0);
954 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getSchemas( )
955 throw (SQLException
, RuntimeException
)
957 MutexGuard
guard( m_refMutex
->mutex
);
960 if( isLog( m_pSettings
, LogLevel::INFO
) )
962 log( m_pSettings
, LogLevel::INFO
, "DatabaseMetaData::getSchemas() got called" );
964 // <b>TABLE_SCHEM</b> string =&gt; schema name
965 Reference
< XStatement
> statement
= m_origin
->createStatement();
966 Reference
< XResultSet
> rs
= statement
->executeQuery(
967 ASCII_STR("SELECT nspname from pg_namespace") );
969 Reference
< XRow
> xRow( rs
, UNO_QUERY
);
970 SequenceAnyVector vec
;
973 Sequence
<Any
> row(1);
974 row
[0] <<= xRow
->getString(1);
975 vec
.push_back( row
);
978 // sort public first, sort internal schemas last, sort rest in alphabetic order
979 std::sort( vec
.begin(), vec
.end(), SortInternalSchemasLastAndPublicFirst() );
981 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
984 return new SequenceResultSet(
985 m_refMutex
, *this, getStatics().schemaNames
,
986 Sequence
< Sequence
< Any
> > ( &vec
[0], vec
.size() ), m_pSettings
->tc
);
989 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getCatalogs( )
990 throw (SQLException
, RuntimeException
)
992 MutexGuard
guard( m_refMutex
->mutex
);
994 return new SequenceResultSet(
995 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
998 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTableTypes( )
999 throw (SQLException
, RuntimeException
)
1001 MutexGuard
guard( m_refMutex
->mutex
);
1003 return new SequenceResultSet(
1004 m_refMutex
, *this, getStatics().tableTypeNames
, getStatics().tableTypeData
,
1009 /** returns the constant from sdbc.DataType
1011 sal_Int32
typeNameToDataType( const OUString
&typeName
, const OUString
&typtype
)
1013 // sal_Int32 ret = com::sun::star::sdbc::DataType::DISTINCT;
1014 // map all unknown types to memo (longvarchar). This allows to show them in
1015 // string representation. Additionally, the edit-table-type-selection-box
1016 // is not so unuseable anymore.
1017 sal_Int32 ret
= com::sun::star::sdbc::DataType::LONGVARCHAR
;
1018 if( 0 == typtype
.compareToAscii( "b" ) )
1020 // as long as the OOo framework does not support arrays,
1021 // the user is better of with interpreting arrays as strings !
1022 // if( typeName.getLength() && '_' == typeName[0] )
1024 // its just a naming convention, but as long as we don't have anything better,
1025 // we take it as granted
1026 // ret = com::sun::star::sdbc::DataType::ARRAY;
1029 Statics
&statics
= getStatics();
1030 BaseTypeMap::iterator ii
= statics
.baseTypeMap
.find( typeName
);
1031 if( ii
!= statics
.baseTypeMap
.end() )
1036 else if( 0 == typtype
.compareToAscii( "c" ) )
1038 ret
= com::sun::star::sdbc::DataType::STRUCT
;
1040 else if( 0 == typtype
.compareToAscii( "d" ) )
1042 ret
= com::sun::star::sdbc::DataType::LONGVARCHAR
;
1047 static bool isSystemColumn( const OUString
&columnName
)
1050 columnName
.compareToAscii( "oid" ) == 0 ||
1051 columnName
.compareToAscii( "tableoid" ) == 0 ||
1052 columnName
.compareToAscii( "xmin" ) == 0 ||
1053 columnName
.compareToAscii( "cmin" ) == 0 ||
1054 columnName
.compareToAscii( "xmax" ) == 0 ||
1055 columnName
.compareToAscii( "cmax" ) == 0 ||
1056 columnName
.compareToAscii( "ctid" ) == 0;
1059 // is not exported by the postgres header
1060 const static int PQ_VARHDRSZ
= sizeof( sal_Int32
);
1062 static void extractPrecisionAndScale(
1063 sal_Int32 dataType
, sal_Int32 atttypmod
, sal_Int32
*precision
, sal_Int32
*scale
)
1065 if( atttypmod
< PQ_VARHDRSZ
)
1074 case com::sun::star::sdbc::DataType::NUMERIC
:
1075 case com::sun::star::sdbc::DataType::DECIMAL
:
1077 *precision
= ( ( atttypmod
- PQ_VARHDRSZ
) >> 16 ) & 0xffff;
1078 *scale
= (atttypmod
- PQ_VARHDRSZ
) & 0xffff;
1082 *precision
= atttypmod
- PQ_VARHDRSZ
;
1088 struct DatabaseTypeDescription
1090 DatabaseTypeDescription()
1092 DatabaseTypeDescription( const OUString
&name
, const OUString
& type
) :
1096 DatabaseTypeDescription( const DatabaseTypeDescription
&source
) :
1097 typeName( source
.typeName
),
1098 typeType( source
.typeType
)
1100 DatabaseTypeDescription
& operator = ( const DatabaseTypeDescription
& source
)
1102 typeName
= source
.typeName
;
1103 typeType
= source
.typeType
;
1110 typedef std::hash_map
1113 DatabaseTypeDescription
,
1114 ::std::hash
< sal_Int32
>,
1115 ::std::equal_to
< sal_Int32
>,
1116 Allocator
< ::std::pair
< sal_Int32
, DatabaseTypeDescription
> >
1117 > Oid2DatabaseTypeDescriptionMap
;
1119 static void columnMetaData2DatabaseTypeDescription(
1120 Oid2DatabaseTypeDescriptionMap
&oidMap
,
1121 const Reference
< XResultSet
> &rs
,
1122 const Reference
< XStatement
> &stmt
)
1124 Reference
< XRow
> row( rs
, UNO_QUERY
);
1126 rtl::OUStringBuffer
queryBuf(128);
1127 queryBuf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT oid,typtype,typname FROM pg_TYPE WHERE " ) );
1130 if( row
->getString( 9 ).equalsAscii( "d" ) && oidMap
.find( row
->getInt( 12 ) ) == oidMap
.end() )
1132 oidMap
[row
->getInt(12)] = DatabaseTypeDescription();
1134 queryBuf
.appendAscii( " OR " );
1135 queryBuf
.appendAscii( "oid = " );
1136 queryBuf
.append( row
->getInt(12 ), 10 );
1144 Reference
< XResultSet
> rsDomain
= stmt
->executeQuery( queryBuf
.makeStringAndClear() );
1145 row
= Reference
< XRow
>( rsDomain
, UNO_QUERY
);
1146 while( rsDomain
->next() )
1148 oidMap
[row
->getInt(1)] = DatabaseTypeDescription(row
->getString(3), row
->getString(2) );
1150 disposeNoThrow( stmt
);
1157 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getColumns(
1158 const ::com::sun::star::uno::Any
& catalog
,
1159 const OUString
& schemaPattern
,
1160 const OUString
& tableNamePattern
,
1161 const OUString
& columnNamePattern
) throw (SQLException
, RuntimeException
)
1163 Statics
&statics
= getStatics();
1166 MutexGuard
guard( m_refMutex
->mutex
);
1169 if( isLog( m_pSettings
, LogLevel::INFO
) )
1171 rtl::OUStringBuffer
buf( 128 );
1172 buf
.appendAscii( "DatabaseMetaData::getColumns got called with " );
1173 buf
.append( schemaPattern
);
1174 buf
.appendAscii( "." );
1175 buf
.append( tableNamePattern
);
1176 buf
.appendAscii( "." );
1177 buf
.append( columnNamePattern
);
1178 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1181 // ignore catalog, as a single pq connection
1182 // does not support multiple catalogs eitherway
1184 // 1. TABLE_CAT string => table catalog (may be NULL)
1186 // 2. TABLE_SCHEM string => table schema (may be NULL)
1187 // => pg_namespace.nspname
1188 // 3. TABLE_NAME string => table name
1189 // => pg_class.relname
1190 // 4. COLUMN_NAME string => column name
1191 // => pg_attribure.attname
1192 // 5. DATA_TYPE short => SQL type from java.sql.Types
1193 // => pg_type.typname => sdbc.DataType
1194 // 6. TYPE_NAME string => Data source dependent type name, for a UDT the
1195 // type name is fully qualified
1196 // => pg_type.typname
1197 // 7. COLUMN_SIZE long => column size. For char or date types this is
1198 // the maximum number of characters, for numeric
1199 // or decimal types this is precision.
1200 // => pg_attribute.atttypmod
1201 // 8. BUFFER_LENGTH is not used.
1203 // 9. DECIMAL_DIGITS long => the number of fractional digits
1204 // => don't know ! TODO !
1205 // 10. NUM_PREC_RADIX long => Radix (typically either 10 or 2)
1207 // 11. NULLABLE long => is NULL allowed?
1208 // NO_NULLS - might not allow NULL values
1209 // NULABLE - definitely allows NULL values
1210 // NULLABLE_UNKNOWN - nullability unknown
1211 // => pg_attribute.attnotnull
1212 // 12. REMARKS string => comment describing column (may be NULL )
1213 // => Don't know, there does not seem to exist something like
1215 // 13. COLUMN_DEF string => default value (may be NULL)
1216 // => pg_type.typdefault
1217 // 14. SQL_DATA_TYPE long => unused
1219 // 15. SQL_DATETIME_SUB long => unused
1221 // 16. CHAR_OCTET_LENGTH long => for char types the maximum number of
1222 // bytes in the column
1223 // => pg_type.typlen
1224 // 17. ORDINAL_POSITION int => index of column in table (starting at 1)
1225 // pg_attribute.attnum
1226 // 18. IS_NULLABLE string => "NO" means column definitely does not allow
1227 // NULL values; "YES" means the column might
1228 // allow NULL values. An empty string means
1230 // => pg_attribute.attnotnull
1231 // select objoid,description,objsubid,pg_attribute.attname from pg_attribute LEFT JOIN pg_description ON pg_attribute.attrelid=pg_description.objoid and pg_attribute.attnum = pg_description.objsubid
1233 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
1236 "SELECT pg_namespace.nspname, " // 1
1237 "pg_class.relname, " // 2
1238 "pg_attribute.attname, " // 3
1239 "pg_type.typname, " // 4
1240 "pg_attribute.atttypmod, " // 5
1241 "pg_attribute.attnotnull, " // 6
1242 "pg_type.typdefault, " // 7
1243 "pg_attribute.attnum, " // 8
1244 "pg_type.typtype, " // 9
1245 "pg_attrdef.adsrc, " // 10
1246 "pg_description.description, " // 11
1247 "pg_type.typbasetype " // 12
1249 "pg_attribute LEFT JOIN pg_attrdef ON pg_attribute.attrelid = pg_attrdef.adrelid AND pg_attribute.attnum = pg_attrdef.adnum "
1250 "LEFT JOIN pg_description ON pg_attribute.attrelid = pg_description.objoid AND pg_attribute.attnum=pg_description.objsubid,"
1251 " pg_type, pg_namespace "
1252 "WHERE pg_attribute.attrelid = pg_class.oid "
1253 "AND pg_attribute.atttypid = pg_type.oid "
1254 "AND pg_class.relnamespace = pg_namespace.oid "
1255 "AND pg_namespace.nspname LIKE ? "
1256 "AND pg_class.relname LIKE ? "
1257 "AND pg_attribute.attname LIKE ? "
1258 "ORDER BY pg_namespace.nspname || pg_class.relname || pg_attribute.attnum"
1261 Reference
< XParameters
> parameters( statement
, UNO_QUERY
);
1262 parameters
->setString( 1 , schemaPattern
);
1263 parameters
->setString( 2 , tableNamePattern
);
1264 parameters
->setString( 3 , columnNamePattern
);
1266 Reference
< XResultSet
> rs
= statement
->executeQuery();
1267 Reference
< XRow
> xRow( rs
, UNO_QUERY
);
1268 SequenceAnyVector vec
;
1270 Oid2DatabaseTypeDescriptionMap domainMap
;
1271 Reference
< XStatement
> domainTypeStmt
= m_origin
->createStatement();
1272 columnMetaData2DatabaseTypeDescription( domainMap
, rs
, domainTypeStmt
);
1276 OUString columnName
= xRow
->getString(3);
1277 if( m_pSettings
->showSystemColumns
|| ! isSystemColumn( columnName
) )
1279 sal_Int32 precision
, scale
, type
;
1280 Sequence
< Any
> row( 18 );
1281 row
[0] <<= m_pSettings
->catalog
;
1282 row
[1] <<= xRow
->getString(1); //
1283 row
[2] <<= xRow
->getString(2);
1284 row
[3] <<= columnName
;
1285 if( xRow
->getString(9).equalsAscii( "d" ) )
1287 DatabaseTypeDescription
desc( domainMap
[xRow
->getInt(12)] );
1288 type
= typeNameToDataType( desc
.typeName
, desc
.typeType
);
1292 type
= typeNameToDataType( xRow
->getString(4), xRow
->getString(9) );
1294 extractPrecisionAndScale( type
, xRow
->getInt(5) , &precision
, &scale
);
1296 row
[5] <<= xRow
->getString(4);
1297 row
[6] <<= precision
;
1299 if( xRow
->getBoolean( 6 ) && ! isSystemColumn(xRow
->getString(3)) )
1301 row
[10] <<= OUString::valueOf(com::sun::star::sdbc::ColumnValue::NO_NULLS
);
1302 row
[17] <<= statics
.NO
;
1306 row
[10] <<= OUString::valueOf(com::sun::star::sdbc::ColumnValue::NULLABLE
);
1307 row
[17] <<= statics
.YES
;
1310 row
[11] <<= xRow
->getString( 11 ); // comment
1311 row
[12] <<= xRow
->getString(10); // COLUMN_DEF = pg_type.typdefault
1312 row
[15] <<= precision
;
1313 row
[16] <<= xRow
->getString(8) ;
1315 // no description in postgresql AFAIK
1316 vec
.push_back( row
);
1319 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1320 if( closeable
.is() )
1323 return new SequenceResultSet(
1324 m_refMutex
, *this, statics
.columnRowNames
,
1325 Sequence
< Sequence
< Any
> > ( &vec
[0],vec
.size() ), m_pSettings
->tc
);
1328 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getColumnPrivileges(
1329 const ::com::sun::star::uno::Any
& catalog
,
1330 const OUString
& schema
,
1331 const OUString
& table
,
1332 const OUString
& columnNamePattern
) throw (SQLException
, RuntimeException
)
1334 MutexGuard
guard( m_refMutex
->mutex
);
1336 return new SequenceResultSet(
1337 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1340 static void addPrivilegesToVector(
1341 sal_Int32 privilege
, const OUString
&catalog
, const OUString
& schema
,
1342 const OUString
&tableName
, const OUString
&grantor
, const OUString
&grantee
,
1343 bool grantable
, SequenceAnyVector
&vec
)
1345 Statics
& statics
= getStatics();
1346 for( int index
= 1; index
<= PRIVILEGE_MAX
; index
= index
<< 1 )
1349 switch( privilege
& index
)
1351 case PRIVILEGE_SELECT
:
1352 privname
= statics
.SELECT
; break;
1353 case PRIVILEGE_UPDATE
:
1354 privname
= statics
.UPDATE
; break;
1355 case PRIVILEGE_INSERT
:
1356 privname
= statics
.INSERT
; break;
1357 case PRIVILEGE_DELETE
:
1358 privname
= statics
.DELETE
; break;
1359 case PRIVILEGE_RULE
:
1360 privname
= statics
.RULE
; break;
1361 case PRIVILEGE_REFERENCES
:
1362 privname
= statics
.REFERENCES
; break;
1363 case PRIVILEGE_TRIGGER
:
1364 privname
= statics
.TRIGGER
; break;
1365 case PRIVILEGE_EXECUTE
:
1366 privname
= statics
.EXECUTE
; break;
1367 case PRIVILEGE_USAGE
:
1368 privname
= statics
.USAGE
; break;
1369 case PRIVILEGE_CREATE
:
1370 privname
= statics
.CREATE
; break;
1371 case PRIVILEGE_TEMPORARY
:
1372 privname
= statics
.TEMPORARY
; break;
1377 Sequence
< Any
> seq( 7 );
1380 seq
[2] <<= tableName
;
1383 seq
[5] <<= privname
;
1384 seq
[6] <<= (grantable
? statics
.YES
: statics
.NO
);
1385 vec
.push_back( seq
);
1390 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTablePrivileges(
1391 const ::com::sun::star::uno::Any
& catalog
,
1392 const OUString
& schemaPattern
,
1393 const OUString
& tableNamePattern
) throw (SQLException
, RuntimeException
)
1395 MutexGuard
guard( m_refMutex
->mutex
);
1398 if( isLog( m_pSettings
, LogLevel::INFO
) )
1400 rtl::OUStringBuffer
buf( 128 );
1401 buf
.appendAscii( "DatabaseMetaData::getTablePrivileges got called with " );
1402 buf
.append( schemaPattern
);
1403 buf
.appendAscii( "." );
1404 buf
.append( tableNamePattern
);
1405 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1410 // get the pg_class.relact item for the concrete table
1411 // get userid for username from pg_shadow (or pg_user view)
1412 // get the group names mentioned in pg_class.relact from pg_group
1413 // identify, which groups the current user belongs to
1414 // calculate the union of all permissions (1 public, 1 user, n groups)
1416 // 1. TABLE_CAT string => table catalog (may be NULL )
1417 // 2. TABLE_SCHEM string => table schema (may be NULL )
1418 // 3. TABLE_NAME string => table name
1419 // 4. GRANTOR => grantor of access (may be NULL )
1420 // 5. GRANTEE string => grantee of access
1421 // 6. PRIVILEGE string => name of access (SELECT, INSERT, UPDATE, REFERENCES, ...)
1422 // 7. IS_GRANTABLE string => "YES" if grantee is permitted to grant to
1423 // others; "NO" if not; NULL if unknown
1425 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
1427 "SELECT pg_namespace.nspname, "
1428 "pg_class.relname, "
1431 "FROM pg_class, pg_user, pg_namespace "
1432 "WHERE pg_class.relowner = pg_user.usesysid "
1433 "AND ( pg_class.relkind = 'r' OR pg_class.relkind = 'v' ) "
1434 "AND pg_class.relnamespace = pg_namespace.oid "
1435 "AND pg_namespace.nspname LIKE ? "
1436 "AND pg_class.relname LIKE ?"
1437 "ORDER BY pg_namespace.nspname || pg_class.relname "
1440 Reference
< XParameters
> parameters( statement
, UNO_QUERY
);
1441 parameters
->setString( 1 , schemaPattern
);
1442 parameters
->setString( 2 , tableNamePattern
);
1444 Reference
< XResultSet
> rs
= statement
->executeQuery();
1445 Reference
< XRow
> xRow( rs
, UNO_QUERY
);
1446 SequenceAnyVector vec
;
1449 // TODO calculate privileges !
1450 sal_Int32 privilege
= 0;
1452 PRIVILEGE_SELECT
| PRIVILEGE_UPDATE
| PRIVILEGE_INSERT
|
1453 PRIVILEGE_DELETE
| PRIVILEGE_RULE
| PRIVILEGE_REFERENCES
|
1454 PRIVILEGE_TRIGGER
| PRIVILEGE_EXECUTE
| PRIVILEGE_USAGE
|
1455 PRIVILEGE_CREATE
|PRIVILEGE_TEMPORARY
;
1457 addPrivilegesToVector( privilege
,
1458 m_pSettings
->catalog
,
1459 xRow
->getString( 1 ),
1460 xRow
->getString( 2 ),
1461 xRow
->getString( 4 ),
1463 m_pSettings
->user
== xRow
->getString( 4 ),
1467 return new SequenceResultSet(
1468 m_refMutex
, *this, getStatics().tablePrivilegesNames
,
1469 Sequence
< Sequence
< Any
> > ( &vec
[0], vec
.size() ), m_pSettings
->tc
);
1472 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getBestRowIdentifier(
1473 const ::com::sun::star::uno::Any
& catalog
,
1474 const OUString
& schema
,
1475 const OUString
& table
,
1477 sal_Bool nullable
) throw (SQLException
, RuntimeException
)
1479 MutexGuard
guard( m_refMutex
->mutex
);
1481 return new SequenceResultSet(
1482 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1485 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getVersionColumns(
1486 const ::com::sun::star::uno::Any
& catalog
,
1487 const OUString
& schema
,
1488 const OUString
& table
) throw (SQLException
, RuntimeException
)
1490 MutexGuard
guard( m_refMutex
->mutex
);
1492 return new SequenceResultSet(
1493 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1496 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getPrimaryKeys(
1497 const ::com::sun::star::uno::Any
& catalog
,
1498 const OUString
& schema
,
1499 const OUString
& table
) throw (SQLException
, RuntimeException
)
1501 MutexGuard
guard( m_refMutex
->mutex
);
1504 // 1. TABLE_CAT string => table catalog (may be NULL )
1505 // 2. TABLE_SCHEM string => table schema (may be NULL )
1506 // 3. TABLE_NAME string => table name
1507 // 4. COLUMN_NAME string => column name
1508 // 5. KEY_SEQ short => sequence number within primary key
1509 // 6. PK_NAME string => primary key name (may be NULL )
1511 if( isLog( m_pSettings
, LogLevel::INFO
) )
1513 rtl::OUStringBuffer
buf( 128 );
1514 buf
.appendAscii( "DatabaseMetaData::getPrimaryKeys got called with " );
1515 buf
.append( schema
);
1516 buf
.appendAscii( "." );
1517 buf
.append( table
);
1518 log( m_pSettings
, LogLevel::INFO
, buf
.makeStringAndClear() );
1521 Reference
< XPreparedStatement
> statement
= m_origin
->prepareStatement(
1523 "SELECT nmsp.nspname, "
1528 "FROM pg_constraint as con,pg_class as cl, pg_namespace as nmsp "
1529 "WHERE con.connamespace = nmsp.oid AND con.conrelid = cl.oid AND con.contype = 'p' "
1530 "AND nmsp.nspname LIKE ? AND cl.relname LIKE ?" ) );
1532 Reference
< XParameters
> parameters( statement
, UNO_QUERY
);
1533 parameters
->setString( 1 , schema
);
1534 parameters
->setString( 2 , table
);
1536 Reference
< XResultSet
> rs
= statement
->executeQuery();
1537 Reference
< XRow
> xRow( rs
, UNO_QUERY
);
1538 SequenceAnyVector vec
;
1542 Sequence
< Any
> row( 6 );
1543 row
[0] <<= m_pSettings
->catalog
;
1544 row
[1] <<= xRow
->getString(1); //
1545 row
[2] <<= xRow
->getString(2);
1546 OUString array
= xRow
->getString(3);
1547 row
[4] <<= xRow
->getString(5); // the relid
1548 row
[5] <<= xRow
->getString(4);
1551 // now retrieve the columns information
1552 // unfortunately, postgresql does not allow array of variable size in
1553 // WHERE clauses (in the default installation), so we have to choose
1554 // this expensive and somewhat ugly way
1555 // annotation: postgresql shouldn't have choosen an array here, instead they
1556 // should have multiple rows per table
1557 while( array
[i
] && '}' != array
[i
] )
1561 while( array
[i
] && array
[i
] != '}' && array
[i
] != ',' ) i
++;
1562 row
[3] <<= OUString( &array
[start
], i
- start
);
1563 vec
.push_back( row
);
1567 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1568 if( closeable
.is() )
1572 SequenceAnyVector::iterator ii
= vec
.begin();
1573 OUString lastTableOid
;
1575 Sequence
< Sequence
< Any
> > ret( vec
.size() );
1577 for( ; ii
!= vec
.end() ; ++ ii
)
1580 Sequence
< Any
> row
= *ii
;
1584 row
[4] >>= tableOid
;
1586 statement
= m_origin
->prepareStatement(
1588 "SELECT att.attname FROM "
1589 "pg_attribute AS att, pg_class AS cl WHERE "
1590 "att.attrelid = ? AND att.attnum = ?" ));
1592 parameters
= Reference
< XParameters
>( statement
, UNO_QUERY
);
1593 parameters
->setString( 1 , tableOid
);
1594 parameters
->setString( 2 , attnum
);
1596 rs
= statement
->executeQuery();
1597 xRow
= Reference
< XRow
>( rs
, UNO_QUERY
);
1601 row
[3] <<= xRow
->getString( 1 );
1602 if( tableOid
!= lastTableOid
)
1604 lastTableOid
= tableOid
;
1605 row
[4] <<= OUString::valueOf( index
);
1608 Reference
< XCloseable
> closeable( statement
, UNO_QUERY
);
1609 if( closeable
.is() )
1611 ret
[elements
] = row
;
1614 return new SequenceResultSet(
1615 m_refMutex
, *this, getStatics().primaryKeyNames
, ret
, m_pSettings
->tc
);
1618 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getImportedKeys(
1619 const ::com::sun::star::uno::Any
& catalog
,
1620 const OUString
& schema
,
1621 const OUString
& table
) throw (SQLException
, RuntimeException
)
1623 // MutexGuard guard( m_refMutex->mutex );
1626 // Statics &st = getStatics();
1627 // Int2StringMap mainMap;
1628 // fillAttnum2attnameMap( mainMap, m_origin, m_schemaName, m_tableName );
1630 // Reference< XPreparedStatement > stmt = m_origin->prepareStatement(
1632 // "SELECT conname, " // 1
1633 // "confupdtype, " // 2
1634 // "confdeltype, " // 3
1635 // "class2.relname, " // 4
1636 // "nmsp2.nspname, " // 5
1639 // "FROM pg_constraint INNER JOIN pg_class ON conrelid = pg_class.oid "
1640 // "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
1641 // "LEFT JOIN pg_class AS class2 ON confrelid = class2.oid "
1642 // "LEFT JOIN pg_namespace AS nmsp2 ON class2.relnamespace=nmsp2.oid "
1643 // "WHERE pg_class.relname = ? AND "
1644 // "pg_namespace.nspname = ? "
1645 // "AND contype = 'f'"));
1647 // Reference< XResultSet > rs = stmt->executeQuery();
1648 // Reference< XRow > row( rs, UNO_QUERY );
1649 // while( rs->next() )
1652 // static const PKTABLE_CAT = 0;
1653 // static const PKTABLE_SCHEM = 1;
1654 // static const PKTABLE_NAME = 2;
1655 // static const PKCOLUMN_NAME = 3;
1656 // static const FKTABLE_CAT = 4;
1657 // static const FKTABLE_SCHEM = 5;
1658 // static const FKTABLE_NAME = 6;
1659 // static const FKCOLUMN_NAME = 7;
1660 // static const KEY_SEQ = 8;
1661 // static const UPDATE_RULE = 9;
1662 // static const DELETE_RULE = 10;
1663 // static const FK_NAME = 11;
1664 // static const PK_NAME = 12;
1665 // static const DEFERRABILITY = 13;
1667 // OUString pkSchema = xRow->getString(6);
1668 // OUString pkTable = xRow->getString(5);
1670 // Int2StringMap foreignMap;
1671 // fillAttnum2attnameMap( foreignMap, m_origin,pkSchema, pkTable);
1673 // Sequence< rtl::OUString > pkColNames =
1674 // convertMappedIntArray2StringArray(
1675 // foreignMap, string2intarray( row->getString( 7 ) ) );
1676 // Sequence< rtl::OUString > fkColNames =
1677 // convertMappedIntArray2StringArray(
1678 // mainMap, string2intarray( row->getString( 6 ) ) );
1680 // for( sal_Int32 i = 0 ; i < pkColNames.getLength() ; i ++ )
1682 // Sequence< Any > theRow( 14 );
1684 // theRow[PKTABLE_SCHEM] = makeAny( pkSchema );
1685 // theRow[PKTABLE_NAME] = makeAny( pkTable );
1686 // theRow[PKCOLUMN_NAME] = makeAny( pkColNames[i] );
1687 // theRow[FKTABLE_SCHEM] = makeAny( schema );
1688 // theRow[FKTABLE_NAME] = makeAny( table );
1689 // theRow[FKCOLUMN_NAME] = makeAny( fkColNames[i] );
1690 // theRow[KEY_SEQ] = makeAny( OUString::valueOf( i ) );
1694 // pKey->setPropertyValue_NoBroadcast_public(
1695 // st.PRIVATE_FOREIGN_COLUMNS,
1696 // makeAny( resolveColumnNames(foreignMap, xRow->getString(8) ) ) );
1699 // fake the getImportedKey() function call in
1700 // dbaccess/source/ui/relationdesigin/RelationController.cxx
1701 // it seems to be the only place in the office, where this function is needed
1702 return new SequenceResultSet(
1703 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (1), m_pSettings
->tc
);
1706 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getExportedKeys(
1707 const ::com::sun::star::uno::Any
& catalog
,
1708 const OUString
& schema
,
1709 const OUString
& table
) throw (SQLException
, RuntimeException
)
1711 throw ::com::sun::star::sdbc::SQLException(
1712 ASCII_STR( "pq_databasemetadata: imported keys from tables not supported " ),
1714 OUString(), 1, Any() );
1717 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getCrossReference(
1718 const ::com::sun::star::uno::Any
& primaryCatalog
,
1719 const OUString
& primarySchema
,
1720 const OUString
& primaryTable
,
1721 const ::com::sun::star::uno::Any
& foreignCatalog
,
1722 const OUString
& foreignSchema
,
1723 const OUString
& foreignTable
) throw (SQLException
, RuntimeException
)
1725 MutexGuard
guard( m_refMutex
->mutex
);
1727 return new SequenceResultSet(
1728 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
1732 struct TypeInfoByDataTypeSorter
1734 bool operator () ( const Sequence
< Any
> & a
, const Sequence
< Any
> & b
)
1738 a
[1 /*DATA_TYPE*/] >>= valueA
;
1739 b
[1 /*DATA_TYPE*/] >>= valueB
;
1740 if( valueB
.toInt32() == valueA
.toInt32() )
1744 a
[0 /*TYPE_NAME*/] >>= nameA
;
1745 b
[0 /*TYPE_NAME*/] >>= nameB
;
1746 if( nameA
.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 )
1748 if( nameB
.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 )
1750 return nameA
.compareTo( nameB
) < 0;
1753 return valueA
.toInt32() < valueB
.toInt32();
1754 // sal_Int32 valueA;
1755 // sal_Int32 valueB;
1756 // a[1 /*DATA_TYPE*/] >>= valueA;
1757 // b[1 /*DATA_TYPE*/] >>= valueB;
1758 // if( valueB == valueA )
1762 // a[0 /*TYPE_NAME*/] >>= nameA;
1763 // b[0 /*TYPE_NAME*/] >>= nameB;
1764 // return nameA.compareTo( nameB ) < 0;
1767 // return valueA < valueB;
1771 static sal_Int32
calcSearchable( sal_Int32 dataType
)
1773 sal_Int32 ret
= com::sun::star::sdbc::ColumnSearch::FULL
;
1774 if( com::sun::star::sdbc::DataType::BINARY
== dataType
||
1775 com::sun::star::sdbc::DataType::VARBINARY
== dataType
||
1776 com::sun::star::sdbc::DataType::LONGVARBINARY
== dataType
)
1777 sal_Int32 ret
= com::sun::star::sdbc::ColumnSearch::NONE
;
1782 static sal_Int32
getMaxScale( sal_Int32 dataType
)
1785 if( dataType
== com::sun::star::sdbc::DataType::NUMERIC
)
1786 ret
= 1000; // see pg-docs DataType/numeric
1787 // else if( dataType == DataType::DOUBLE )
1789 // else if( dataType == DataType::FLOAT )
1797 const char * typeName
;
1798 const char * createParam
;
1800 sal_Int32 precision
;
1803 sal_Int32 searchable
;
1806 static void pgTypeInfo2ResultSet(
1807 SequenceAnyVector
&vec
,
1808 const Reference
< XResultSet
> &rs
)
1810 static const sal_Int32 TYPE_NAME
= 0; // string Type name
1811 static const sal_Int32 DATA_TYPE
= 1; // short SQL data type from java.sql.Types
1812 static const sal_Int32 PRECISION
= 2; // long maximum precision
1813 static const sal_Int32 CREATE_PARAMS
= 5; // string => parameters used in creating the type (may be NULL )
1814 static const sal_Int32 NULLABLE
= 6; // short ==> can you use NULL for this type?
1815 // - NO_NULLS - does not allow NULL values
1816 // - NULLABLE - allows NULL values
1817 // - NULLABLE_UNKNOWN - nullability unknown
1819 static const sal_Int32 CASE_SENSITIVE
= 7; // boolean==> is it case sensitive
1820 static const sal_Int32 SEARCHABLE
= 8; // short ==>; can you use
1821 // "WHERE" based on this type:
1822 // - NONE - No support
1823 // - CHAR - Only supported with WHERE .. LIKE
1824 // - BASIC - Supported except for WHERE .. LIKE
1825 // - FULL - Supported for all WHERE ..
1826 static const sal_Int32 UNSIGNED_ATTRIBUTE
= 9; // boolean ==> is it unsigned?
1827 static const sal_Int32 FIXED_PREC_SCALE
= 10; // boolean ==> can it be a money value?
1828 static const sal_Int32 AUTO_INCREMENT
= 11; // boolean ==> can it be used for
1829 // an auto-increment value?
1830 static const sal_Int32 MINIMUM_SCALE
= 13; // short ==> minimum scale supported
1831 static const sal_Int32 MAXIMUM_SCALE
= 14; // short ==> maximum scale supported
1832 static const sal_Int32 NUM_PREC_RADIX
= 17; // long ==> usually 2 or 10
1834 /* not filled so far
1835 3. LITERAL_PREFIX string ==> prefix used to quote a literal
1837 4, LITERAL_SUFFIX string ==> suffix used to quote a literal
1839 5. CREATE_PARAMS string ==> parameters used in creating thw type (may be <NULL/>)
1840 12. LOCAL_TYPE_NAME string ==> localized version of type name (may be <NULL/>)
1841 15, SQL_DATA_TYPE long ==> unused
1842 16. SQL_DATETIME_SUB long ==> unused
1844 Reference
< XRow
> xRow( rs
, UNO_QUERY
);
1847 Sequence
< Any
> row(18);
1849 sal_Int32 dataType
=typeNameToDataType(xRow
->getString(5),xRow
->getString(2));
1850 sal_Int32 precision
= xRow
->getString(3).toInt32();
1852 if( dataType
== com::sun::star::sdbc::DataType::CHAR
||
1853 dataType
== com::sun::star::sdbc::DataType::VARCHAR
&&
1854 xRow
->getString(TYPE_NAME
+1).equalsIgnoreAsciiCaseAscii( "varchar") )
1856 // reflect varchar as varchar with upper limit !
1857 //NOTE: the sql spec requires varchar to have an upper limit, however
1858 // in postgresql the upper limit is optional, no limit means unlimited
1860 precision
= 0x40000000; // about 1 GB, see character type docs in postgresql
1861 row
[CREATE_PARAMS
] <<= ASCII_STR( "length" );
1863 else if( dataType
== com::sun::star::sdbc::DataType::NUMERIC
)
1866 row
[CREATE_PARAMS
] <<= ASCII_STR( "length, scale" );
1869 row
[TYPE_NAME
] <<= xRow
->getString(1);
1870 row
[DATA_TYPE
] <<= OUString::valueOf(dataType
);
1871 row
[PRECISION
] <<= OUString::valueOf( precision
);
1872 sal_Int32 nullable
= xRow
->getBoolean(4) ?
1873 com::sun::star::sdbc::ColumnValue::NO_NULLS
:
1874 com::sun::star::sdbc::ColumnValue::NULLABLE
;
1875 row
[NULLABLE
] <<= OUString::valueOf(nullable
);
1876 row
[CASE_SENSITIVE
] <<= OUString::valueOf((sal_Int32
)1);
1877 row
[SEARCHABLE
] <<= OUString::valueOf( calcSearchable( dataType
) );
1878 row
[UNSIGNED_ATTRIBUTE
] <<= ASCII_STR( "0" ); //
1879 if( com::sun::star::sdbc::DataType::INTEGER
== dataType
||
1880 com::sun::star::sdbc::DataType::BIGINT
== dataType
)
1881 row
[AUTO_INCREMENT
] <<= ASCII_STR( "1" ); // TODO
1883 row
[AUTO_INCREMENT
] <<= ASCII_STR( "0" ); // TODO
1884 row
[MINIMUM_SCALE
] <<= ASCII_STR( "0" ); // TODO: what is this ?
1885 row
[MAXIMUM_SCALE
] <<= OUString::valueOf( getMaxScale( dataType
) );
1886 row
[NUM_PREC_RADIX
] <<= ASCII_STR( "10" ); // TODO: what is this ?
1887 vec
.push_back( row
);
1893 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getTypeInfo( )
1894 throw (SQLException
, RuntimeException
)
1896 // Note: Indexes start at 0 (in the API doc, they start at 1)
1897 MutexGuard
guard( m_refMutex
->mutex
);
1900 if( isLog( m_pSettings
, LogLevel::INFO
) )
1902 log( m_pSettings
, LogLevel::INFO
, "DatabaseMetaData::getTypeInfo() got called" );
1905 Reference
< XStatement
> statement
= m_origin
->createStatement();
1906 Reference
< XResultSet
> rs
= statement
->executeQuery(
1908 "SELECT pg_type.typname AS typname," //1
1909 "pg_type.typtype AS typtype," //2
1910 "pg_type.typlen AS typlen," //3
1911 "pg_type.typnotnull AS typnotnull," //4
1912 "pg_type.typname AS typname " //5
1914 "WHERE pg_type.typtype = 'b' "
1915 "OR pg_type.typtype = 'p'"
1918 SequenceAnyVector vec
;
1919 pgTypeInfo2ResultSet( vec
, rs
);
1921 // check for domain types
1922 rs
= statement
->executeQuery(
1924 "SELECT t1.typname as typname,"
1925 "t2.typtype AS typtype,"
1926 "t2.typlen AS typlen,"
1927 "t2.typnotnull AS typnotnull,"
1928 "t2.typname as realtypname "
1929 "FROM pg_type as t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype=t2.oid "
1930 "WHERE t1.typtype = 'd'" ) );
1931 pgTypeInfo2ResultSet( vec
, rs
);
1933 std::sort( vec
.begin(), vec
.end(), TypeInfoByDataTypeSorter() );
1935 return new SequenceResultSet(
1938 getStatics().typeinfoColumnNames
,
1939 Sequence
< Sequence
< Any
> > ( &vec
[0] , vec
.size() ),
1941 &( getStatics().typeInfoMetaData
));
1945 static sal_Int32
seqContains( const Sequence
< sal_Int32
> &seq
, sal_Int32 value
)
1948 for( int i
= 0; i
< seq
.getLength(); i
++ )
1950 if( seq
[i
] == value
)
1959 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getIndexInfo(
1960 const ::com::sun::star::uno::Any
& catalog
,
1961 const OUString
& schema
,
1962 const OUString
& table
,
1964 sal_Bool approximate
) throw (SQLException
, RuntimeException
)
1966 MutexGuard
guard( m_refMutex
->mutex
);
1970 1. TABLE_CAT string -> table catalog (may be NULL )
1971 2. TABLE_SCHEM string -> table schema (may be NULL )
1972 3. TABLE_NAME string -> table name
1973 4. NON_UNIQUE boolean -> Can index values be non-unique?
1974 false when TYPE is tableIndexStatistic
1975 5. INDEX_QUALIFIER string -> index catalog (may be NULL );
1976 NULL when TYPE is tableIndexStatistic
1977 6. INDEX_NAME string -> index name; NULL when TYPE is tableIndexStatistic
1978 7. TYPE short -> index type:
1979 * 0 - this identifies table statistics that are returned
1980 in conjuction with a table's index descriptions
1981 * CLUSTERED - this is a clustered index
1982 * HASHED - this is a hashed index
1983 * OTHER - this is some other style of index
1984 8. ORDINAL_POSITION short -> column sequence number within index;
1985 zero when TYPE is tableIndexStatistic
1986 9. COLUMN_NAME string -> column name; NULL when TYPE is tableIndexStatistic
1987 10. ASC_OR_DESC string -> column sort sequence, "A"= ascending,
1988 "D" = descending, may be NULL if sort sequence
1989 is not supported; NULL when TYPE is tableIndexStatistic
1990 11. CARDINALITY long -> When TYPE is tableIndexStatistic, then this is
1991 the number of rows in the table; otherwise, it
1992 is the number of unique values in the index.
1993 12. PAGES long -> When TYPE is tableIndexStatisic then this is
1994 the number of pages used for the table, otherwise
1995 it is the number of pages used for the current index.
1996 13. FILTER_CONDITION string -> Filter condition, if any. (may be NULL )
1999 static const sal_Int32 C_SCHEMA
= 1;
2000 static const sal_Int32 C_TABLENAME
= 2;
2001 static const sal_Int32 C_INDEXNAME
= 3;
2002 static const sal_Int32 C_IS_CLUSTERED
= 4;
2003 static const sal_Int32 C_IS_UNIQUE
= 5;
2004 static const sal_Int32 C_IS_PRIMARY
= 6;
2005 static const sal_Int32 C_COLUMNS
= 7;
2007 static const sal_Int32 R_TABLE_SCHEM
= 1;
2008 static const sal_Int32 R_TABLE_NAME
= 2;
2009 static const sal_Int32 R_NON_UNIQUE
= 3;
2010 static const sal_Int32 R_INDEX_NAME
= 5;
2011 static const sal_Int32 R_TYPE
= 6;
2012 static const sal_Int32 R_ORDINAL_POSITION
= 7;
2013 static const sal_Int32 R_COLUMN_NAME
= 8;
2015 Reference
< XPreparedStatement
> stmt
= m_origin
->prepareStatement(
2017 "SELECT nspname, " // 1
2018 "pg_class.relname, " // 2
2019 "class2.relname, " // 3
2020 "indisclustered, " // 4
2021 "indisunique, " // 5
2022 "indisprimary, " // 6
2024 "FROM pg_index INNER JOIN pg_class ON indrelid = pg_class.oid "
2025 "INNER JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid "
2026 "INNER JOIN pg_class as class2 ON pg_index.indexrelid = class2.oid "
2027 "WHERE nspname = ? AND pg_class.relname = ?" ) );
2029 Reference
< XParameters
> param ( stmt
, UNO_QUERY
);
2030 param
->setString( 1, schema
);
2031 param
->setString( 2, table
);
2032 Reference
< XResultSet
> rs
= stmt
->executeQuery();
2033 Reference
< XRow
> xRow ( rs
, UNO_QUERY
);
2035 SequenceAnyVector vec
;
2038 Sequence
< sal_Int32
> columns
= parseIntArray( xRow
->getString(C_COLUMNS
) );
2039 Reference
< XPreparedStatement
> columnsStmt
= m_origin
->prepareStatement(
2041 "SELECT attnum, attname "
2042 "FROM pg_attribute "
2043 " INNER JOIN pg_class ON attrelid = pg_class.oid "
2044 " INNER JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid "
2045 " WHERE pg_namespace.nspname=? AND pg_class.relname=?" ) );
2046 Reference
< XParameters
> paramColumn ( columnsStmt
, UNO_QUERY
);
2047 OUString currentSchema
= xRow
->getString( C_SCHEMA
);
2048 OUString currentTable
= xRow
->getString( C_TABLENAME
);
2049 OUString currentIndexName
= xRow
->getString( C_INDEXNAME
);
2050 sal_Bool isNonUnique
= ! xRow
->getBoolean( C_IS_UNIQUE
);
2051 sal_Bool isPrimary
= xRow
->getBoolean( C_IS_PRIMARY
);
2052 sal_Int32 indexType
= xRow
->getBoolean( C_IS_CLUSTERED
) ?
2053 com::sun::star::sdbc::IndexType::CLUSTERED
:
2054 com::sun::star::sdbc::IndexType::HASHED
;
2056 paramColumn
->setString( C_SCHEMA
, currentSchema
);
2057 paramColumn
->setString( C_TABLENAME
, currentTable
);
2059 Reference
< XResultSet
> rsColumn
= columnsStmt
->executeQuery();
2060 Reference
< XRow
> rowColumn( rsColumn
, UNO_QUERY
);
2061 while( rsColumn
->next() )
2063 sal_Int32 pos
= seqContains( columns
, rowColumn
->getInt( 1 ) );
2064 if( pos
>= 0 && ( ! isNonUnique
|| ! unique
) )
2066 Sequence
< Any
> result( 13 );
2067 result
[R_TABLE_SCHEM
] = makeAny(currentSchema
);
2068 result
[R_TABLE_NAME
] = makeAny(currentTable
);
2069 result
[R_INDEX_NAME
] = makeAny(currentIndexName
);
2070 result
[R_NON_UNIQUE
] =
2071 Any( &isNonUnique
, getBooleanCppuType() );
2072 result
[R_TYPE
] = makeAny( indexType
);
2073 result
[R_COLUMN_NAME
] = makeAny( rowColumn
->getString(2) );
2074 sal_Int32 nPos
= ((sal_Int32
)pos
+1); // MSVC++ nonsense
2075 result
[R_ORDINAL_POSITION
] = makeAny( nPos
);
2076 vec
.push_back( result
);
2080 return new SequenceResultSet(
2081 m_refMutex
, *this, getStatics().indexinfoColumnNames
,
2082 Sequence
< Sequence
< Any
> > ( &vec
[0] , vec
.size() ),
2086 sal_Bool
DatabaseMetaData::supportsResultSetType( sal_Int32 setType
)
2087 throw (SQLException
, RuntimeException
)
2090 setType
== com::sun::star::sdbc::ResultSetType::SCROLL_INSENSITIVE
||
2091 setType
== com::sun::star::sdbc::ResultSetType::FORWARD_ONLY
;
2094 sal_Bool
DatabaseMetaData::supportsResultSetConcurrency(
2095 sal_Int32 setType
, sal_Int32 concurrency
) throw (SQLException
, RuntimeException
)
2097 return supportsResultSetType( setType
) &&
2098 (concurrency
== com::sun::star::sdbc::TransactionIsolation::READ_COMMITTED
||
2099 concurrency
== com::sun::star::sdbc::TransactionIsolation::SERIALIZABLE
);
2102 sal_Bool
DatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2107 sal_Bool
DatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2112 sal_Bool
DatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2117 sal_Bool
DatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2122 sal_Bool
DatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2127 sal_Bool
DatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2132 sal_Bool
DatabaseMetaData::updatesAreDetected( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2137 sal_Bool
DatabaseMetaData::deletesAreDetected( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2141 sal_Bool
DatabaseMetaData::insertsAreDetected( sal_Int32 setType
) throw (SQLException
, RuntimeException
)
2146 sal_Bool
DatabaseMetaData::supportsBatchUpdates( ) throw (SQLException
, RuntimeException
)
2151 ::com::sun::star::uno::Reference
< XResultSet
> DatabaseMetaData::getUDTs( const ::com::sun::star::uno::Any
& catalog
, const OUString
& schemaPattern
, const OUString
& typeNamePattern
, const ::com::sun::star::uno::Sequence
< sal_Int32
>& types
) throw (SQLException
, RuntimeException
)
2153 MutexGuard
guard( m_refMutex
->mutex
);
2155 return new SequenceResultSet(
2156 m_refMutex
, *this, Sequence
< OUString
>(), Sequence
< Sequence
< Any
> > (), m_pSettings
->tc
);
2159 ::com::sun::star::uno::Reference
< com::sun::star::sdbc::XConnection
> DatabaseMetaData::getConnection()
2160 throw (SQLException
, RuntimeException
)