merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / postgresql / pq_databasemetadata.cxx
blob66d90edef1307e2e9853cb0123af3133e96f1d3b
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,
34 * MA 02111-1307 USA
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 ************************************************************************/
61 #include <algorithm>
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
104 typedef
105 std::vector
107 com::sun::star::uno::Sequence< com::sun::star::uno::Any >,
108 Allocator< com::sun::star::uno::Sequence< com::sun::star::uno::Any > >
109 > SequenceAnyVector;
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 ),
151 m_origin( origin ),
152 m_refMutex( refMutex )
158 sal_Bool DatabaseMetaData::allProceduresAreCallable( ) throw (SQLException, RuntimeException)
160 // TODO
161 return sal_False;
164 sal_Bool DatabaseMetaData::allTablesAreSelectable( ) throw (SQLException, RuntimeException)
166 return sal_True;
169 OUString DatabaseMetaData::getURL( ) throw (SQLException, RuntimeException)
171 // TODO
172 return OUString();
175 OUString DatabaseMetaData::getUserName( ) throw (SQLException, RuntimeException)
177 return m_pSettings->user;
180 sal_Bool DatabaseMetaData::isReadOnly( ) throw (SQLException, RuntimeException)
182 return sal_False;
186 sal_Bool DatabaseMetaData::nullsAreSortedHigh( ) throw (SQLException, RuntimeException)
188 return sal_False;
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)
237 return sal_True;
240 sal_Bool DatabaseMetaData::usesLocalFilePerTable( ) throw (SQLException, RuntimeException)
242 return sal_True;
245 sal_Bool DatabaseMetaData::supportsMixedCaseIdentifiers( ) throw (SQLException, RuntimeException)
247 return sal_False;
250 sal_Bool DatabaseMetaData::storesUpperCaseIdentifiers( ) throw (SQLException, RuntimeException)
252 return sal_False;
255 sal_Bool DatabaseMetaData::storesLowerCaseIdentifiers( ) throw (SQLException, RuntimeException)
257 return sal_False;
261 sal_Bool DatabaseMetaData::storesMixedCaseIdentifiers( ) throw (SQLException, RuntimeException)
263 return sal_False;
267 sal_Bool DatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException)
269 return sal_False;
272 sal_Bool DatabaseMetaData::storesUpperCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException)
274 return sal_False;
278 sal_Bool DatabaseMetaData::storesLowerCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException)
280 return sal_False;
284 sal_Bool DatabaseMetaData::storesMixedCaseQuotedIdentifiers( ) throw (SQLException, RuntimeException)
286 return sal_False;
290 OUString DatabaseMetaData::getIdentifierQuoteString( ) throw (SQLException, RuntimeException)
292 return ASCII_STR( "\"" );
295 OUString DatabaseMetaData::getSQLKeywords( ) throw (SQLException, RuntimeException)
297 return ASCII_STR(
298 "ANALYZE,"
299 "ANALYSE,"
300 "DO,"
301 "ILIKE,"
302 "LIMIT,"
303 "NEW,"
304 "OFFSET,"
305 "OLD,"
306 "PLACING" );
308 OUString DatabaseMetaData::getNumericFunctions( ) throw (SQLException, RuntimeException)
310 // TODO
311 return OUString();
314 OUString DatabaseMetaData::getStringFunctions( ) throw (SQLException, RuntimeException)
316 // TODO
317 return OUString();
320 OUString DatabaseMetaData::getSystemFunctions( ) throw (SQLException, RuntimeException)
322 // TODO
323 return OUString();
325 OUString DatabaseMetaData::getTimeDateFunctions( ) throw (SQLException, RuntimeException)
327 // TODO
328 return OUString();
330 OUString DatabaseMetaData::getSearchStringEscape( ) throw (SQLException, RuntimeException)
332 return ASCII_STR( "\\" );
334 OUString DatabaseMetaData::getExtraNameCharacters( ) throw (SQLException, RuntimeException)
336 // TODO
337 return OUString();
340 sal_Bool DatabaseMetaData::supportsAlterTableWithAddColumn( ) throw (SQLException, RuntimeException)
342 return sal_True;
345 sal_Bool DatabaseMetaData::supportsAlterTableWithDropColumn( ) throw (SQLException, RuntimeException)
347 return sal_True;
350 sal_Bool DatabaseMetaData::supportsColumnAliasing( ) throw (SQLException, RuntimeException)
352 return sal_True;
355 sal_Bool DatabaseMetaData::nullPlusNonNullIsNull( ) throw (SQLException, RuntimeException)
357 return sal_True;
360 sal_Bool DatabaseMetaData::supportsTypeConversion( ) throw (SQLException, RuntimeException) // TODO, DON'T KNOW
362 return sal_False;
365 sal_Bool DatabaseMetaData::supportsConvert( sal_Int32 fromType, sal_Int32 toType ) throw (SQLException, RuntimeException) // TODO
367 return sal_False;
370 sal_Bool DatabaseMetaData::supportsTableCorrelationNames( ) throw (SQLException, RuntimeException) // TODO, don't know
372 return sal_True;
376 sal_Bool DatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw (SQLException, RuntimeException) // TODO, don't know
379 return sal_True;
381 sal_Bool DatabaseMetaData::supportsExpressionsInOrderBy( ) throw (SQLException, RuntimeException)
383 return sal_True;
386 sal_Bool DatabaseMetaData::supportsOrderByUnrelated( ) throw (SQLException, RuntimeException)
388 return sal_True;
391 sal_Bool DatabaseMetaData::supportsGroupBy( ) throw (SQLException, RuntimeException)
393 return sal_True;
396 sal_Bool DatabaseMetaData::supportsGroupByUnrelated( ) throw (SQLException, RuntimeException) // TODO, DONT know
399 return sal_True;
402 sal_Bool DatabaseMetaData::supportsGroupByBeyondSelect( ) throw (SQLException, RuntimeException) // TODO, DON'T know
405 return sal_True;
408 sal_Bool DatabaseMetaData::supportsLikeEscapeClause( ) throw (SQLException, RuntimeException)
410 return sal_True;
413 sal_Bool DatabaseMetaData::supportsMultipleResultSets( ) throw (SQLException, RuntimeException)
415 return sal_True;
418 sal_Bool DatabaseMetaData::supportsMultipleTransactions( ) throw (SQLException, RuntimeException)
420 return sal_False;
423 sal_Bool DatabaseMetaData::supportsNonNullableColumns( ) throw (SQLException, RuntimeException)
425 return sal_True;
429 sal_Bool DatabaseMetaData::supportsMinimumSQLGrammar( ) throw (SQLException, RuntimeException)
431 return sal_True;
434 sal_Bool DatabaseMetaData::supportsCoreSQLGrammar( ) throw (SQLException, RuntimeException)
436 return sal_True;
439 sal_Bool DatabaseMetaData::supportsExtendedSQLGrammar( ) throw (SQLException, RuntimeException)
441 return sal_True;
444 sal_Bool DatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw (SQLException, RuntimeException)
446 return sal_True;
449 sal_Bool DatabaseMetaData::supportsANSI92IntermediateSQL( ) throw (SQLException, RuntimeException)
451 return sal_True;
454 sal_Bool DatabaseMetaData::supportsANSI92FullSQL( ) throw (SQLException, RuntimeException)
456 return sal_True;
459 sal_Bool DatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw (SQLException, RuntimeException)
461 // TODO
462 return sal_True;
465 sal_Bool DatabaseMetaData::supportsOuterJoins( ) throw (SQLException, RuntimeException)
467 return sal_True;
470 sal_Bool DatabaseMetaData::supportsFullOuterJoins( ) throw (SQLException, RuntimeException)
472 return sal_True;
475 sal_Bool DatabaseMetaData::supportsLimitedOuterJoins( ) throw (SQLException, RuntimeException)
477 return sal_True;
481 OUString DatabaseMetaData::getSchemaTerm( ) throw (SQLException, RuntimeException)
483 return ASCII_STR( "SCHEMA" );
486 OUString DatabaseMetaData::getProcedureTerm( ) throw (SQLException, RuntimeException)
488 // don't know
489 return OUString();
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
501 return sal_True;
504 OUString DatabaseMetaData::getCatalogSeparator( ) throw (SQLException, RuntimeException)
506 // TODO don't know
507 return ASCII_STR( "." );
510 sal_Bool DatabaseMetaData::supportsSchemasInDataManipulation( ) throw (SQLException, RuntimeException)
512 return sal_True;
515 sal_Bool DatabaseMetaData::supportsSchemasInProcedureCalls( ) throw (SQLException, RuntimeException)
517 return sal_True;
520 sal_Bool DatabaseMetaData::supportsSchemasInTableDefinitions( ) throw (SQLException, RuntimeException)
522 return sal_True;
525 sal_Bool DatabaseMetaData::supportsSchemasInIndexDefinitions( ) throw (SQLException, RuntimeException)
527 return sal_True;
530 sal_Bool DatabaseMetaData::supportsSchemasInPrivilegeDefinitions( ) throw (SQLException, RuntimeException)
532 return sal_True;
535 sal_Bool DatabaseMetaData::supportsCatalogsInDataManipulation( ) throw (SQLException, RuntimeException)
537 return sal_False;
540 sal_Bool DatabaseMetaData::supportsCatalogsInProcedureCalls( ) throw (SQLException, RuntimeException)
542 return sal_False;
545 sal_Bool DatabaseMetaData::supportsCatalogsInTableDefinitions( ) throw (SQLException, RuntimeException)
547 return sal_False;
551 sal_Bool DatabaseMetaData::supportsCatalogsInIndexDefinitions( ) throw (SQLException, RuntimeException)
553 return sal_False;
557 sal_Bool DatabaseMetaData::supportsCatalogsInPrivilegeDefinitions( ) throw (SQLException, RuntimeException)
559 return sal_False;
563 sal_Bool DatabaseMetaData::supportsPositionedDelete( ) throw (SQLException, RuntimeException)
565 // TODO
566 return sal_True;
569 sal_Bool DatabaseMetaData::supportsPositionedUpdate( ) throw (SQLException, RuntimeException)
571 // TODO
572 return sal_True;
576 sal_Bool DatabaseMetaData::supportsSelectForUpdate( ) throw (SQLException, RuntimeException)
578 // TODO
579 return sal_False;
583 sal_Bool DatabaseMetaData::supportsStoredProcedures( ) throw (SQLException, RuntimeException)
585 // TODO
586 return sal_False;
590 sal_Bool DatabaseMetaData::supportsSubqueriesInComparisons( ) throw (SQLException, RuntimeException)
592 // TODO , don't know
593 return sal_True;
596 sal_Bool DatabaseMetaData::supportsSubqueriesInExists( ) throw (SQLException, RuntimeException)
598 // TODO , don't know
599 return sal_True;
602 sal_Bool DatabaseMetaData::supportsSubqueriesInIns( ) throw (SQLException, RuntimeException)
604 // TODO , don't know
605 return sal_True;
608 sal_Bool DatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw (SQLException, RuntimeException)
610 // TODO , don't know
611 return sal_True;
614 sal_Bool DatabaseMetaData::supportsCorrelatedSubqueries( ) throw (SQLException, RuntimeException)
616 // TODO , don't know
617 return sal_True;
619 sal_Bool DatabaseMetaData::supportsUnion( ) throw (SQLException, RuntimeException)
621 return sal_True;
624 sal_Bool DatabaseMetaData::supportsUnionAll( ) throw (SQLException, RuntimeException)
626 return sal_True;
629 sal_Bool DatabaseMetaData::supportsOpenCursorsAcrossCommit( ) throw (SQLException, RuntimeException)
631 // TODO, don't know
632 return sal_False;
635 sal_Bool DatabaseMetaData::supportsOpenCursorsAcrossRollback( ) throw (SQLException, RuntimeException)
637 // TODO, don't know
638 return sal_False;
641 sal_Bool DatabaseMetaData::supportsOpenStatementsAcrossCommit( ) throw (SQLException, RuntimeException)
643 // TODO, don't know
644 return sal_False;
646 sal_Bool DatabaseMetaData::supportsOpenStatementsAcrossRollback( ) throw (SQLException, RuntimeException)
648 // TODO, don't know
649 return sal_False;
652 sal_Int32 DatabaseMetaData::getMaxBinaryLiteralLength( ) throw (SQLException, RuntimeException)
654 // TODO, don't know
655 return -1;
658 sal_Int32 DatabaseMetaData::getMaxCharLiteralLength( ) throw (SQLException, RuntimeException)
660 return -1;
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)
725 return -1;
728 sal_Bool DatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw (SQLException, RuntimeException)
730 return sal_False;
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)
765 return sal_False;
768 sal_Bool DatabaseMetaData::supportsTransactionIsolationLevel( sal_Int32 level ) throw (SQLException, RuntimeException)
770 return sal_False;
773 sal_Bool DatabaseMetaData::supportsDataDefinitionAndDataManipulationTransactions( )
774 throw (SQLException, RuntimeException)
776 return sal_True;
779 sal_Bool DatabaseMetaData::supportsDataManipulationTransactionsOnly( ) throw (SQLException, RuntimeException)
781 return sal_False;
784 sal_Bool DatabaseMetaData::dataDefinitionCausesTransactionCommit( ) throw (SQLException, RuntimeException)
786 // don't know
787 return sal_True;
790 sal_Bool DatabaseMetaData::dataDefinitionIgnoredInTransactions( ) throw (SQLException, RuntimeException)
792 return sal_True;
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 =&gt; procedure catalog (may be NULL )
801 // 2. PROCEDURE_SCHEM string =&gt; procedure schema (may be NULL )
802 // 3. PROCEDURE_NAME string =&gt; procedure name
803 // 4. reserved for future use
804 // 5. reserved for future use
805 // 6. reserved for future use
806 // 7. REMARKS string =&gt; explanatory comment on the procedure
807 // 8. PROCEDURE_TYPE short =&gt; 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 );
813 checkClosed();
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 );
825 checkClosed();
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 );
840 checkClosed();
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(
854 ASCII_STR(
855 "SELECT "
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"
864 ) );
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;
874 while( rs->next() )
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;
888 else
890 row[3] <<= statics.TABLE;
893 else if( 0 == type.compareToAscii( "v" ) )
895 row[3] <<= statics.VIEW;
897 else
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 );
907 if( closeable.is() )
908 closeable->close();
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 )
919 OUString valueA;
920 OUString valueB;
921 a[0] >>= valueA;
922 b[0] >>= valueB;
923 bool ret = false;
924 if( valueA.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 )
926 ret = true;
928 else if( valueB.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "public" ) ) == 0 )
930 ret = false;
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 !
946 else
948 ret = (valueA.compareTo( valueB ) < 0);
950 return ret;
954 ::com::sun::star::uno::Reference< XResultSet > DatabaseMetaData::getSchemas( )
955 throw (SQLException, RuntimeException)
957 MutexGuard guard( m_refMutex->mutex );
958 checkClosed();
960 if( isLog( m_pSettings, LogLevel::INFO ) )
962 log( m_pSettings, LogLevel::INFO, "DatabaseMetaData::getSchemas() got called" );
964 // <b>TABLE_SCHEM</b> string =&amp;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;
971 while( rs->next() )
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 );
982 if( closeable.is() )
983 closeable->close();
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 );
993 checkClosed();
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 );
1002 checkClosed();
1003 return new SequenceResultSet(
1004 m_refMutex, *this, getStatics().tableTypeNames, getStatics().tableTypeData,
1005 m_pSettings->tc );
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] )
1023 // {
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;
1027 // }
1028 // base type
1029 Statics &statics = getStatics();
1030 BaseTypeMap::iterator ii = statics.baseTypeMap.find( typeName );
1031 if( ii != statics.baseTypeMap.end() )
1033 ret = ii->second;
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;
1044 return ret;
1047 static bool isSystemColumn( const OUString &columnName )
1049 return
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 )
1067 *precision = 0;
1068 *scale = 0;
1070 else
1072 switch( dataType )
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;
1079 break;
1081 default:
1082 *precision = atttypmod - PQ_VARHDRSZ;
1083 *scale = 0;
1088 struct DatabaseTypeDescription
1090 DatabaseTypeDescription()
1092 DatabaseTypeDescription( const OUString &name, const OUString & type ) :
1093 typeName( name ),
1094 typeType( 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;
1104 return *this;
1106 OUString typeName;
1107 OUString typeType;
1110 typedef std::hash_map
1112 sal_Int32,
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 );
1125 int domains = 0;
1126 rtl::OUStringBuffer queryBuf(128);
1127 queryBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "SELECT oid,typtype,typname FROM pg_TYPE WHERE " ) );
1128 while( rs->next() )
1130 if( row->getString( 9 ).equalsAscii( "d" ) && oidMap.find( row->getInt( 12 ) ) == oidMap.end() )
1132 oidMap[row->getInt(12)] = DatabaseTypeDescription();
1133 if( domains )
1134 queryBuf.appendAscii( " OR " );
1135 queryBuf.appendAscii( "oid = " );
1136 queryBuf.append( row->getInt(12 ), 10 );
1137 domains ++;
1140 rs->beforeFirst();
1142 if( domains )
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();
1165 // continue !
1166 MutexGuard guard( m_refMutex->mutex );
1167 checkClosed();
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)
1185 // => not supported
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.
1202 // => 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)
1206 // => TODO ??
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
1214 // that in postgres
1215 // 13. COLUMN_DEF string => default value (may be NULL)
1216 // => pg_type.typdefault
1217 // 14. SQL_DATA_TYPE long => unused
1218 // => empty
1219 // 15. SQL_DATETIME_SUB long => unused
1220 // => empty
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
1229 // nobody knows.
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(
1234 ASCII_STR(
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
1248 "FROM pg_class, "
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"
1259 ) );
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 );
1274 while( rs->next() )
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 );
1290 else
1292 type = typeNameToDataType( xRow->getString(4), xRow->getString(9) );
1294 extractPrecisionAndScale( type, xRow->getInt(5) , &precision, &scale );
1295 row[4] <<= type;
1296 row[5] <<= xRow->getString(4);
1297 row[6] <<= precision;
1298 row[8] <<= scale;
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;
1304 else
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() )
1321 closeable->close();
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 );
1335 checkClosed();
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 )
1348 OUString privname;
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;
1373 default:
1374 break;
1377 Sequence< Any > seq( 7 );
1378 seq[0] <<= catalog;
1379 seq[1] <<= schema;
1380 seq[2] <<= tableName;
1381 seq[3] <<= grantor;
1382 seq[4] <<= grantee;
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 );
1396 checkClosed();
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() );
1408 // algorithm
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 =&gt; table catalog (may be NULL )
1417 // 2. TABLE_SCHEM string =&gt; table schema (may be NULL )
1418 // 3. TABLE_NAME string =&gt; table name
1419 // 4. GRANTOR =&gt; grantor of access (may be NULL )
1420 // 5. GRANTEE string =&gt; grantee of access
1421 // 6. PRIVILEGE string =&gt; name of access (SELECT, INSERT, UPDATE, REFERENCES, ...)
1422 // 7. IS_GRANTABLE string =&gt; "YES" if grantee is permitted to grant to
1423 // others; "NO" if not; NULL if unknown
1425 Reference< XPreparedStatement > statement = m_origin->prepareStatement(
1426 ASCII_STR(
1427 "SELECT pg_namespace.nspname, "
1428 "pg_class.relname, "
1429 "pg_class.relacl, "
1430 "pg_user.usename "
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 "
1438 ) );
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;
1447 while( rs->next() )
1449 // TODO calculate privileges !
1450 sal_Int32 privilege = 0;
1451 privilege =
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 ),
1462 m_pSettings->user,
1463 m_pSettings->user == xRow->getString( 4 ),
1464 vec );
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,
1476 sal_Int32 scope,
1477 sal_Bool nullable ) throw (SQLException, RuntimeException)
1479 MutexGuard guard( m_refMutex->mutex );
1480 checkClosed();
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 );
1491 checkClosed();
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 );
1502 checkClosed();
1504 // 1. TABLE_CAT string =&gt; table catalog (may be NULL )
1505 // 2. TABLE_SCHEM string =&gt; table schema (may be NULL )
1506 // 3. TABLE_NAME string =&gt; table name
1507 // 4. COLUMN_NAME string =&gt; column name
1508 // 5. KEY_SEQ short =&gt; sequence number within primary key
1509 // 6. PK_NAME string =&gt; 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(
1522 ASCII_STR(
1523 "SELECT nmsp.nspname, "
1524 "cl.relname, "
1525 "con.conkey, "
1526 "con.conname, "
1527 "con.conrelid "
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;
1540 while( rs->next() )
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);
1550 int i = 0;
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] )
1559 i++;
1560 int start = 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() )
1569 closeable->close();
1572 SequenceAnyVector::iterator ii = vec.begin();
1573 OUString lastTableOid;
1574 sal_Int32 index;
1575 Sequence< Sequence< Any > > ret( vec.size() );
1576 int elements = 0;
1577 for( ; ii != vec.end() ; ++ ii )
1580 Sequence< Any > row = *ii;
1581 OUString tableOid;
1582 OUString attnum;
1584 row[4] >>= tableOid;
1585 row[3] >>= attnum;
1586 statement = m_origin->prepareStatement(
1587 ASCII_STR(
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 );
1598 if( rs->next() )
1600 // column name
1601 row[3] <<= xRow->getString( 1 );
1602 if( tableOid != lastTableOid )
1603 index = 1;
1604 lastTableOid = tableOid;
1605 row[4] <<= OUString::valueOf( index );
1606 index ++;
1608 Reference< XCloseable > closeable( statement, UNO_QUERY );
1609 if( closeable.is() )
1610 closeable->close();
1611 ret[elements] = row;
1612 elements ++;
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 );
1624 // checkClosed();
1626 // Statics &st = getStatics();
1627 // Int2StringMap mainMap;
1628 // fillAttnum2attnameMap( mainMap, m_origin, m_schemaName, m_tableName );
1630 // Reference< XPreparedStatement > stmt = m_origin->prepareStatement(
1631 // ASCII_STR(
1632 // "SELECT conname, " // 1
1633 // "confupdtype, " // 2
1634 // "confdeltype, " // 3
1635 // "class2.relname, " // 4
1636 // "nmsp2.nspname, " // 5
1637 // "conkey," // 6
1638 // "confkey " // 7
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() )
1650 // {
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 ++ )
1681 // {
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 ) );
1691 // theRow[
1694 // pKey->setPropertyValue_NoBroadcast_public(
1695 // st.PRIVATE_FOREIGN_COLUMNS,
1696 // makeAny( resolveColumnNames(foreignMap, xRow->getString(8) ) ) );
1698 // }
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 " ),
1713 *this,
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 );
1726 checkClosed();
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 )
1736 OUString valueA;
1737 OUString valueB;
1738 a[1 /*DATA_TYPE*/] >>= valueA;
1739 b[1 /*DATA_TYPE*/] >>= valueB;
1740 if( valueB.toInt32() == valueA.toInt32() )
1742 OUString nameA;
1743 OUString nameB;
1744 a[0 /*TYPE_NAME*/] >>= nameA;
1745 b[0 /*TYPE_NAME*/] >>= nameB;
1746 if( nameA.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 )
1747 return 1;
1748 if( nameB.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "int4" ) ) == 0 )
1749 return 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 )
1759 // {
1760 // OUString nameA;
1761 // OUString nameB;
1762 // a[0 /*TYPE_NAME*/] >>= nameA;
1763 // b[0 /*TYPE_NAME*/] >>= nameB;
1764 // return nameA.compareTo( nameB ) < 0;
1765 // }
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;
1779 return ret;
1782 static sal_Int32 getMaxScale( sal_Int32 dataType )
1784 sal_Int32 ret = 0;
1785 if( dataType == com::sun::star::sdbc::DataType::NUMERIC )
1786 ret = 1000; // see pg-docs DataType/numeric
1787 // else if( dataType == DataType::DOUBLE )
1788 // ret = 308;
1789 // else if( dataType == DataType::FLOAT )
1790 // ret =
1791 return ret;
1795 struct RawType
1797 const char * typeName;
1798 const char * createParam;
1799 sal_Int32 sdbcType;
1800 sal_Int32 precision;
1801 sal_Int32 nullable;
1802 bool caseSensitive;
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
1836 (may be <NULL/>)
1837 4, LITERAL_SUFFIX string ==> suffix used to quote a literal
1838 (may be <NULL/>)
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 );
1845 while( rs->next() )
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
1859 // length (=1GB).
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 )
1865 precision = 1000;
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
1882 else
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 );
1898 checkClosed();
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(
1907 ASCII_STR(
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
1913 "FROM pg_type "
1914 "WHERE pg_type.typtype = 'b' "
1915 "OR pg_type.typtype = 'p'"
1916 ) );
1918 SequenceAnyVector vec;
1919 pgTypeInfo2ResultSet( vec, rs );
1921 // check for domain types
1922 rs = statement->executeQuery(
1923 ASCII_STR(
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(
1936 m_refMutex,
1937 *this,
1938 getStatics().typeinfoColumnNames,
1939 Sequence< Sequence< Any > > ( &vec[0] , vec.size() ),
1940 m_pSettings->tc,
1941 &( getStatics().typeInfoMetaData ));
1945 static sal_Int32 seqContains( const Sequence< sal_Int32 > &seq, sal_Int32 value )
1947 sal_Int32 ret = -1;
1948 for( int i = 0; i < seq.getLength(); i ++ )
1950 if( seq[i] == value )
1952 ret = i;
1953 break;
1956 return ret;
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,
1963 sal_Bool unique,
1964 sal_Bool approximate ) throw (SQLException, RuntimeException)
1966 MutexGuard guard( m_refMutex->mutex );
1967 checkClosed();
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(
2016 ASCII_STR(
2017 "SELECT nspname, " // 1
2018 "pg_class.relname, " // 2
2019 "class2.relname, " // 3
2020 "indisclustered, " // 4
2021 "indisunique, " // 5
2022 "indisprimary, " // 6
2023 "indkey " // 7
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;
2036 while( rs->next() )
2038 Sequence< sal_Int32 > columns = parseIntArray( xRow->getString(C_COLUMNS) );
2039 Reference< XPreparedStatement > columnsStmt = m_origin->prepareStatement(
2040 ASCII_STR(
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() ),
2083 m_pSettings->tc );
2086 sal_Bool DatabaseMetaData::supportsResultSetType( sal_Int32 setType )
2087 throw (SQLException, RuntimeException)
2089 return
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)
2104 return sal_False;
2107 sal_Bool DatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException)
2109 return sal_False;
2112 sal_Bool DatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException)
2114 return sal_False;
2117 sal_Bool DatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException)
2119 return sal_False;
2122 sal_Bool DatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException)
2124 return sal_False;
2127 sal_Bool DatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) throw (SQLException, RuntimeException)
2129 return sal_False;
2132 sal_Bool DatabaseMetaData::updatesAreDetected( sal_Int32 setType ) throw (SQLException, RuntimeException)
2134 return sal_False;
2137 sal_Bool DatabaseMetaData::deletesAreDetected( sal_Int32 setType ) throw (SQLException, RuntimeException)
2139 return sal_False;
2141 sal_Bool DatabaseMetaData::insertsAreDetected( sal_Int32 setType ) throw (SQLException, RuntimeException)
2143 return sal_False;
2146 sal_Bool DatabaseMetaData::supportsBatchUpdates( ) throw (SQLException, RuntimeException)
2148 return sal_False;
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 );
2154 checkClosed();
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)
2162 return m_origin;