1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "DatabaseMetaData.hxx"
24 #include <rtl/ustrbuf.hxx>
25 #include <FDatabaseMetaDataResultSet.hxx>
27 #include <com/sun/star/sdbc/ColumnValue.hpp>
28 #include <com/sun/star/sdbc/DataType.hpp>
29 #include <com/sun/star/sdbc/IndexType.hpp>
30 #include <com/sun/star/sdbc/ResultSetType.hpp>
31 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
32 #include <com/sun/star/sdbc/TransactionIsolation.hpp>
33 #include <com/sun/star/sdbc/XParameters.hpp>
34 #include <com/sun/star/sdbc/XRow.hpp>
36 using namespace connectivity::firebird
;
38 using namespace ::rtl
;
40 using namespace com::sun::star
;
41 using namespace com::sun::star::uno
;
42 using namespace com::sun::star::lang
;
43 using namespace com::sun::star::beans
;
44 using namespace com::sun::star::sdbc
;
46 ODatabaseMetaData::ODatabaseMetaData(Connection
* _pCon
)
47 : m_pConnection(_pCon
)
49 OSL_ENSURE(m_pConnection
,"ODatabaseMetaData::ODatabaseMetaData: No connection set!");
52 ODatabaseMetaData::~ODatabaseMetaData()
56 //----- Catalog Info -- UNSUPPORTED -------------------------------------------
57 OUString SAL_CALL
ODatabaseMetaData::getCatalogSeparator() throw(SQLException
, RuntimeException
, std::exception
)
62 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxCatalogNameLength() throw(SQLException
, RuntimeException
, std::exception
)
67 OUString SAL_CALL
ODatabaseMetaData::getCatalogTerm() throw(SQLException
, RuntimeException
, std::exception
)
72 sal_Bool SAL_CALL
ODatabaseMetaData::isCatalogAtStart() throw(SQLException
, RuntimeException
, std::exception
)
77 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInTableDefinitions() throw(SQLException
, RuntimeException
, std::exception
)
82 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInIndexDefinitions() throw(SQLException
, RuntimeException
, std::exception
)
87 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInDataManipulation( ) throw(SQLException
, RuntimeException
, std::exception
)
92 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getCatalogs() throw(SQLException
, RuntimeException
, std::exception
)
94 OSL_FAIL("Not implemented yet!");
96 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCatalogs
);
99 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInProcedureCalls() throw(SQLException
, RuntimeException
, std::exception
)
104 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions() throw(SQLException
, RuntimeException
, std::exception
)
109 //----- Schema Info -- UNSUPPORTED --------------------------------------------
110 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInProcedureCalls()
111 throw(SQLException
, RuntimeException
, std::exception
)
116 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
117 throw(SQLException
, RuntimeException
, std::exception
)
122 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInDataManipulation()
123 throw(SQLException
, RuntimeException
, std::exception
)
128 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInIndexDefinitions()
129 throw(SQLException
, RuntimeException
, std::exception
)
134 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInTableDefinitions()
135 throw(SQLException
, RuntimeException
, std::exception
)
140 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxSchemaNameLength()
141 throw(SQLException
, RuntimeException
, std::exception
)
146 OUString SAL_CALL
ODatabaseMetaData::getSchemaTerm()
147 throw(SQLException
, RuntimeException
, std::exception
)
152 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getSchemas()
153 throw(SQLException
, RuntimeException
, std::exception
)
155 OSL_FAIL("Not implemented yet!");
157 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eSchemas
);
160 //----- Max Sizes/Lengths -----------------------------------------------------
161 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxBinaryLiteralLength() throw(SQLException
, RuntimeException
, std::exception
)
166 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxRowSize() throw(SQLException
, RuntimeException
, std::exception
)
171 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxCharLiteralLength() throw(SQLException
, RuntimeException
, std::exception
)
176 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnNameLength() throw(SQLException
, RuntimeException
, std::exception
)
181 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInIndex() throw(SQLException
, RuntimeException
, std::exception
)
184 // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
188 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxCursorNameLength() throw(SQLException
, RuntimeException
, std::exception
)
193 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxConnections() throw(SQLException
, RuntimeException
, std::exception
)
195 return 100; // Arbitrary
198 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInTable() throw(SQLException
, RuntimeException
, std::exception
)
200 // May however be smaller.
201 // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
205 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxStatementLength() throw(SQLException
, RuntimeException
, std::exception
)
210 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxTableNameLength() throw(SQLException
, RuntimeException
, std::exception
)
215 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxTablesInSelect( ) throw(SQLException
, RuntimeException
, std::exception
)
217 sal_Int32 nValue
= 0; // 0 means no limit
222 sal_Bool SAL_CALL
ODatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw(SQLException
, RuntimeException
, std::exception
)
227 // ---- Identifiers -----------------------------------------------------------
228 // Only quoted identifiers are case sensitive, unquoted are case insensitive
229 OUString SAL_CALL
ODatabaseMetaData::getIdentifierQuoteString()
230 throw(SQLException
, RuntimeException
, std::exception
)
236 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw(SQLException
, RuntimeException
, std::exception
)
241 sal_Bool SAL_CALL
ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
242 throw(SQLException
, RuntimeException
, std::exception
)
247 sal_Bool SAL_CALL
ODatabaseMetaData::storesMixedCaseQuotedIdentifiers()
248 throw(SQLException
, RuntimeException
, std::exception
)
250 // TODO: confirm this -- the documentation is highly ambiguous
251 // However it seems this should be true as quoted identifiers ARE
252 // stored mixed case.
256 sal_Bool SAL_CALL
ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
257 throw(SQLException
, RuntimeException
, std::exception
)
262 // ---- Unquoted Identifiers -------------------------------------------------
263 // All unquoted identifers are stored upper case.
264 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMixedCaseIdentifiers()
265 throw(SQLException
, RuntimeException
, std::exception
)
270 sal_Bool SAL_CALL
ODatabaseMetaData::storesLowerCaseIdentifiers()
271 throw(SQLException
, RuntimeException
, std::exception
)
276 sal_Bool SAL_CALL
ODatabaseMetaData::storesMixedCaseIdentifiers()
277 throw(SQLException
, RuntimeException
, std::exception
)
282 sal_Bool SAL_CALL
ODatabaseMetaData::storesUpperCaseIdentifiers()
283 throw(SQLException
, RuntimeException
, std::exception
)
288 // ---- SQL Feature Support ---------------------------------------------------
289 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCoreSQLGrammar()
290 throw(SQLException
, RuntimeException
, std::exception
)
295 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMinimumSQLGrammar()
296 throw(SQLException
, RuntimeException
, std::exception
)
301 sal_Bool SAL_CALL
ODatabaseMetaData::supportsAlterTableWithAddColumn()
302 throw(SQLException
, RuntimeException
, std::exception
)
307 sal_Bool SAL_CALL
ODatabaseMetaData::supportsAlterTableWithDropColumn()
308 throw(SQLException
, RuntimeException
, std::exception
)
313 sal_Bool SAL_CALL
ODatabaseMetaData::supportsPositionedDelete()
314 throw(SQLException
, RuntimeException
, std::exception
)
319 sal_Bool SAL_CALL
ODatabaseMetaData::supportsPositionedUpdate()
320 throw(SQLException
, RuntimeException
, std::exception
)
325 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOuterJoins()
326 throw(SQLException
, RuntimeException
, std::exception
)
331 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSelectForUpdate()
332 throw(SQLException
, RuntimeException
, std::exception
)
337 sal_Bool SAL_CALL
ODatabaseMetaData::allTablesAreSelectable()
338 throw(SQLException
, RuntimeException
, std::exception
)
340 // TODO: true if embedded, but unsure about remote server
344 sal_Bool SAL_CALL
ODatabaseMetaData::supportsConvert(sal_Int32 fromType
,
346 throw(SQLException
, RuntimeException
, std::exception
)
353 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTypeConversion()
354 throw(SQLException
, RuntimeException
, std::exception
)
359 sal_Bool SAL_CALL
ODatabaseMetaData::supportsColumnAliasing()
360 throw(SQLException
, RuntimeException
, std::exception
)
365 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTableCorrelationNames()
366 throw(SQLException
, RuntimeException
, std::exception
)
371 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxIndexLength( ) throw(SQLException
, RuntimeException
, std::exception
)
373 sal_Int32 nValue
= 0; // 0 means no limit
377 sal_Bool SAL_CALL
ODatabaseMetaData::supportsNonNullableColumns( ) throw(SQLException
, RuntimeException
, std::exception
)
382 OUString SAL_CALL
ODatabaseMetaData::getExtraNameCharacters( ) throw(SQLException
, RuntimeException
, std::exception
)
388 sal_Bool SAL_CALL
ODatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw(SQLException
, RuntimeException
, std::exception
)
392 // ---- Data definition stuff -------------------------------------------------
393 sal_Bool SAL_CALL
ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
394 throw(SQLException
, RuntimeException
, std::exception
)
399 sal_Bool SAL_CALL
ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
400 throw(SQLException
, RuntimeException
, std::exception
)
405 sal_Bool SAL_CALL
ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
406 throw(SQLException
, RuntimeException
, std::exception
)
411 sal_Bool SAL_CALL
ODatabaseMetaData::
412 supportsDataDefinitionAndDataManipulationTransactions()
413 throw(SQLException
, RuntimeException
, std::exception
)
417 //----- Transaction Support --------------------------------------------------
418 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTransactions()
419 throw(SQLException
, RuntimeException
, std::exception
)
424 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
425 throw(SQLException
, RuntimeException
, std::exception
)
430 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
431 throw(SQLException
, RuntimeException
, std::exception
)
436 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
437 throw(SQLException
, RuntimeException
, std::exception
)
442 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
443 throw(SQLException
, RuntimeException
, std::exception
)
448 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMultipleTransactions()
449 throw(SQLException
, RuntimeException
, std::exception
)
454 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTransactionIsolationLevel(
456 throw(SQLException
, RuntimeException
, std::exception
)
458 return aLevel
== TransactionIsolation::READ_UNCOMMITTED
459 || aLevel
== TransactionIsolation::READ_COMMITTED
460 || aLevel
== TransactionIsolation::REPEATABLE_READ
461 || aLevel
== TransactionIsolation::SERIALIZABLE
;
464 sal_Int32 SAL_CALL
ODatabaseMetaData::getDefaultTransactionIsolation()
465 throw(SQLException
, RuntimeException
, std::exception
)
467 return TransactionIsolation::REPEATABLE_READ
;
471 sal_Bool SAL_CALL
ODatabaseMetaData::supportsANSI92FullSQL( ) throw(SQLException
, RuntimeException
, std::exception
)
476 sal_Bool SAL_CALL
ODatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw(SQLException
, RuntimeException
, std::exception
)
478 return sal_True
; // should be supported at least
481 sal_Bool SAL_CALL
ODatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw(SQLException
, RuntimeException
, std::exception
)
486 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxStatements( ) throw(SQLException
, RuntimeException
, std::exception
)
488 sal_Int32 nValue
= 0; // 0 means no limit
492 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxProcedureNameLength( ) throw(SQLException
, RuntimeException
, std::exception
)
494 sal_Int32 nValue
= 31; // TODO: confirm
498 sal_Bool SAL_CALL
ODatabaseMetaData::allProceduresAreCallable( ) throw(SQLException
, RuntimeException
, std::exception
)
503 sal_Bool SAL_CALL
ODatabaseMetaData::supportsStoredProcedures( ) throw(SQLException
, RuntimeException
, std::exception
)
508 sal_Bool SAL_CALL
ODatabaseMetaData::isReadOnly( ) throw(SQLException
, RuntimeException
, std::exception
)
510 return m_pConnection
->isReadOnly();
513 sal_Bool SAL_CALL
ODatabaseMetaData::usesLocalFiles( ) throw(SQLException
, RuntimeException
, std::exception
)
515 return m_pConnection
->isEmbedded();
518 sal_Bool SAL_CALL
ODatabaseMetaData::usesLocalFilePerTable( ) throw(SQLException
, RuntimeException
, std::exception
)
523 sal_Bool SAL_CALL
ODatabaseMetaData::nullPlusNonNullIsNull( ) throw(SQLException
, RuntimeException
, std::exception
)
528 sal_Bool SAL_CALL
ODatabaseMetaData::supportsExpressionsInOrderBy( ) throw(SQLException
, RuntimeException
, std::exception
)
533 sal_Bool SAL_CALL
ODatabaseMetaData::supportsGroupBy( ) throw(SQLException
, RuntimeException
, std::exception
)
538 sal_Bool SAL_CALL
ODatabaseMetaData::supportsGroupByBeyondSelect( ) throw(SQLException
, RuntimeException
, std::exception
)
544 sal_Bool SAL_CALL
ODatabaseMetaData::supportsGroupByUnrelated( ) throw(SQLException
, RuntimeException
, std::exception
)
551 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMultipleResultSets( ) throw(SQLException
, RuntimeException
, std::exception
)
556 sal_Bool SAL_CALL
ODatabaseMetaData::supportsLikeEscapeClause( ) throw(SQLException
, RuntimeException
, std::exception
)
561 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOrderByUnrelated( ) throw(SQLException
, RuntimeException
, std::exception
)
566 sal_Bool SAL_CALL
ODatabaseMetaData::supportsUnion( ) throw(SQLException
, RuntimeException
, std::exception
)
571 sal_Bool SAL_CALL
ODatabaseMetaData::supportsUnionAll( ) throw(SQLException
, RuntimeException
, std::exception
)
576 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedAtEnd( ) throw(SQLException
, RuntimeException
, std::exception
)
581 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedAtStart( ) throw(SQLException
, RuntimeException
, std::exception
)
586 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedHigh( ) throw(SQLException
, RuntimeException
, std::exception
)
591 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedLow( ) throw(SQLException
, RuntimeException
, std::exception
)
596 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCorrelatedSubqueries( ) throw(SQLException
, RuntimeException
, std::exception
)
601 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInComparisons( ) throw(SQLException
, RuntimeException
, std::exception
)
606 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInExists( ) throw(SQLException
, RuntimeException
, std::exception
)
611 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInIns( ) throw(SQLException
, RuntimeException
, std::exception
)
616 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw(SQLException
, RuntimeException
, std::exception
)
621 sal_Bool SAL_CALL
ODatabaseMetaData::supportsANSI92IntermediateSQL( ) throw(SQLException
, RuntimeException
, std::exception
)
626 OUString SAL_CALL
ODatabaseMetaData::getURL() throw(SQLException
, RuntimeException
, std::exception
)
628 return m_pConnection
->getConnectionURL();
631 OUString SAL_CALL
ODatabaseMetaData::getUserName( ) throw(SQLException
, RuntimeException
, std::exception
)
637 OUString SAL_CALL
ODatabaseMetaData::getDriverName( ) throw(SQLException
, RuntimeException
, std::exception
)
643 OUString SAL_CALL
ODatabaseMetaData::getDriverVersion() throw(SQLException
, RuntimeException
, std::exception
)
649 OUString SAL_CALL
ODatabaseMetaData::getDatabaseProductVersion( ) throw(SQLException
, RuntimeException
, std::exception
)
655 OUString SAL_CALL
ODatabaseMetaData::getDatabaseProductName( ) throw(SQLException
, RuntimeException
, std::exception
)
661 OUString SAL_CALL
ODatabaseMetaData::getProcedureTerm( ) throw(SQLException
, RuntimeException
, std::exception
)
667 sal_Int32 SAL_CALL
ODatabaseMetaData::getDriverMajorVersion( ) throw(RuntimeException
, std::exception
)
672 sal_Int32 SAL_CALL
ODatabaseMetaData::getDriverMinorVersion( ) throw(RuntimeException
, std::exception
)
677 OUString SAL_CALL
ODatabaseMetaData::getSQLKeywords( ) throw(SQLException
, RuntimeException
, std::exception
)
683 OUString SAL_CALL
ODatabaseMetaData::getSearchStringEscape( ) throw(SQLException
, RuntimeException
, std::exception
)
689 OUString SAL_CALL
ODatabaseMetaData::getStringFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
694 OUString SAL_CALL
ODatabaseMetaData::getTimeDateFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
699 OUString SAL_CALL
ODatabaseMetaData::getSystemFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
704 OUString SAL_CALL
ODatabaseMetaData::getNumericFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
709 sal_Bool SAL_CALL
ODatabaseMetaData::supportsExtendedSQLGrammar( ) throw(SQLException
, RuntimeException
, std::exception
)
714 sal_Bool SAL_CALL
ODatabaseMetaData::supportsFullOuterJoins( ) throw(SQLException
, RuntimeException
, std::exception
)
719 sal_Bool SAL_CALL
ODatabaseMetaData::supportsLimitedOuterJoins( ) throw(SQLException
, RuntimeException
, std::exception
)
724 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInGroupBy( ) throw(SQLException
, RuntimeException
, std::exception
)
726 sal_Int32 nValue
= 0; // 0 means no limit
730 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInOrderBy( ) throw(SQLException
, RuntimeException
, std::exception
)
732 sal_Int32 nValue
= 0; // 0 means no limit
736 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInSelect( ) throw(SQLException
, RuntimeException
, std::exception
)
738 sal_Int32 nValue
= 0; // 0 means no limit
742 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxUserNameLength( ) throw(SQLException
, RuntimeException
, std::exception
)
747 sal_Bool SAL_CALL
ODatabaseMetaData::supportsResultSetType(sal_Int32 setType
)
748 throw(SQLException
, RuntimeException
, std::exception
)
752 case ResultSetType::FORWARD_ONLY
:
759 sal_Bool SAL_CALL
ODatabaseMetaData::supportsResultSetConcurrency(
760 sal_Int32 aResultSetType
,
761 sal_Int32 aConcurrency
)
762 throw(SQLException
, RuntimeException
, std::exception
)
764 if (aResultSetType
== ResultSetType::FORWARD_ONLY
765 && aConcurrency
== ResultSetConcurrency::READ_ONLY
)
771 sal_Bool SAL_CALL
ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
777 sal_Bool SAL_CALL
ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
783 sal_Bool SAL_CALL
ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
789 sal_Bool SAL_CALL
ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
795 sal_Bool SAL_CALL
ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
801 sal_Bool SAL_CALL
ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
807 sal_Bool SAL_CALL
ODatabaseMetaData::updatesAreDetected( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
813 sal_Bool SAL_CALL
ODatabaseMetaData::deletesAreDetected( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
819 sal_Bool SAL_CALL
ODatabaseMetaData::insertsAreDetected( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
825 sal_Bool SAL_CALL
ODatabaseMetaData::supportsBatchUpdates()
826 throw(SQLException
, RuntimeException
, std::exception
)
828 // No batch support in firebird
832 uno::Reference
< XConnection
> SAL_CALL
ODatabaseMetaData::getConnection()
833 throw(SQLException
, RuntimeException
, std::exception
)
835 return (uno::Reference
< XConnection
>) m_pConnection
;
838 // here follow all methods which return a resultset
839 // the first methods is an example implementation how to use this resultset
840 // of course you could implement it on your and you should do this because
841 // the general way is more memory expensive
843 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTableTypes( ) throw(SQLException
, RuntimeException
, std::exception
)
845 OSL_FAIL("Not implemented yet!");
847 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTableTypes
);
850 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTypeInfo()
851 throw(SQLException
, RuntimeException
, std::exception
)
853 SAL_INFO("connectivity.firebird", "getTypeInfo()");
855 // this returns an empty resultset where the column-names are already set
856 // in special the metadata of the resultset already returns the right columns
857 ODatabaseMetaDataResultSet
* pResultSet
=
858 new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTypeInfo
);
859 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
860 static ODatabaseMetaDataResultSet::ORows aResults
;
864 ODatabaseMetaDataResultSet::ORow
aRow(19);
867 aRow
[4] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
868 aRow
[5] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
869 aRow
[7] = new ORowSetValueDecorator(sal_True
); // Nullable
870 aRow
[8] = new ORowSetValueDecorator(sal_True
); // Case sensitive
871 aRow
[10] = new ORowSetValueDecorator(sal_False
); // Is unsigned
872 // FIXED_PREC_SCALE: docs state "can it be a money value? " however
873 // in reality this causes Base to treat all numbers as money formatted
874 // by default which is wrong (and formatting as money value is still
875 // possible for all values).
876 aRow
[11] = new ORowSetValueDecorator(sal_False
);
877 // Localised Type Name -- TODO: implement (but can be null):
878 aRow
[13] = new ORowSetValueDecorator();
879 aRow
[16] = new ORowSetValueDecorator(); // Unused
880 aRow
[17] = new ORowSetValueDecorator(); // Unused
881 aRow
[18] = new ORowSetValueDecorator(sal_Int16(10));// Radix
884 aRow
[1] = new ORowSetValueDecorator(OUString("CHAR"));
885 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT
));
886 aRow
[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
887 aRow
[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
888 aRow
[9] = new ORowSetValueDecorator(
889 sal_Int16(ColumnSearch::FULL
)); // Searchable
890 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
891 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
892 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
893 aResults
.push_back(aRow
);
896 aRow
[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
897 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING
));
898 aRow
[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
899 aRow
[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
900 aRow
[9] = new ORowSetValueDecorator(
901 sal_Int16(ColumnSearch::FULL
)); // Searchable
902 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
903 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
904 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
905 aResults
.push_back(aRow
);
907 // Integer Types common
909 aRow
[6] = new ORowSetValueDecorator(); // Create Params
910 aRow
[9] = new ORowSetValueDecorator(
911 sal_Int16(ColumnSearch::FULL
)); // Searchable
912 aRow
[12] = new ORowSetValueDecorator(sal_True
); // Autoincrement
913 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
914 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
917 aRow
[1] = new ORowSetValueDecorator(OUString("SMALLINT"));
918 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT
));
919 aRow
[3] = new ORowSetValueDecorator(sal_Int16(5)); // Prevision
920 aResults
.push_back(aRow
);
922 aRow
[1] = new ORowSetValueDecorator(OUString("INTEGER"));
923 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG
));
924 aRow
[3] = new ORowSetValueDecorator(sal_Int16(10)); // Precision
925 aResults
.push_back(aRow
);
927 aRow
[1] = new ORowSetValueDecorator(OUString("BIGINT"));
928 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64
));
929 aRow
[3] = new ORowSetValueDecorator(sal_Int16(20)); // Precision
930 aResults
.push_back(aRow
);
932 // Decimal Types common
934 aRow
[6] = new ORowSetValueDecorator(); // Create Params
935 aRow
[9] = new ORowSetValueDecorator(
936 sal_Int16(ColumnSearch::FULL
)); // Searchable
937 aRow
[12] = new ORowSetValueDecorator(sal_True
); // Autoincrement
940 aRow
[1] = new ORowSetValueDecorator(OUString("FLOAT"));
941 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT
));
942 aRow
[3] = new ORowSetValueDecorator(sal_Int16(7)); // Precision
943 aRow
[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
944 aRow
[15] = new ORowSetValueDecorator(sal_Int16(7)); // Max scale
945 aResults
.push_back(aRow
);
947 aRow
[1] = new ORowSetValueDecorator(OUString("DOUBLE PRECISION"));
948 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE
));
949 aRow
[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
950 aRow
[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
951 aRow
[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
952 aResults
.push_back(aRow
);
954 // aRow[1] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(SQL_D_FLOAT));
955 // aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_D_FLOAT));
956 // aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
957 // aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
958 // aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
959 // aResults.push_back(aRow);
960 // TODO: no idea whether D_FLOAT corresponds to an sql type
964 aRow
[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
965 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP
));
966 aRow
[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
967 aRow
[6] = new ORowSetValueDecorator(); // Create Params
968 aRow
[9] = new ORowSetValueDecorator(
969 sal_Int16(ColumnSearch::FULL
)); // Searchable
970 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
971 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
972 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
973 aResults
.push_back(aRow
);
977 aRow
[1] = new ORowSetValueDecorator(OUString("TIME"));
978 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME
));
979 aRow
[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
980 aRow
[6] = new ORowSetValueDecorator(); // Create Params
981 aRow
[9] = new ORowSetValueDecorator(
982 sal_Int16(ColumnSearch::FULL
)); // Searchable
983 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
984 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
985 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
986 aResults
.push_back(aRow
);
990 aRow
[1] = new ORowSetValueDecorator(OUString("DATE"));
991 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE
));
992 aRow
[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
993 aRow
[6] = new ORowSetValueDecorator(); // Create Params
994 aRow
[9] = new ORowSetValueDecorator(
995 sal_Int16(ColumnSearch::FULL
)); // Searchable
996 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
997 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
998 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
999 aResults
.push_back(aRow
);
1003 aRow
[1] = new ORowSetValueDecorator(OUString("BLOB"));
1004 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB
));
1005 aRow
[3] = new ORowSetValueDecorator(sal_Int32(0)); // Prevision = max length
1006 aRow
[6] = new ORowSetValueDecorator(); // Create Params
1007 aRow
[9] = new ORowSetValueDecorator(
1008 sal_Int16(ColumnSearch::NONE
)); // Searchable
1009 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
1010 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
1011 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
1012 aResults
.push_back(aRow
);
1017 // case SQL_QUAD: // Is a "Blob ID" according to the docs
1019 pResultSet
->setRows(aResults
);
1023 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getColumnPrivileges(
1024 const Any
& /*aCatalog*/,
1025 const OUString
& /*sSchema*/,
1026 const OUString
& sTable
,
1027 const OUString
& sColumnNamePattern
)
1028 throw(SQLException
, RuntimeException
, std::exception
)
1030 SAL_INFO("connectivity.firebird", "getColumnPrivileges() with "
1032 << " & ColumnNamePattern: " << sColumnNamePattern
);
1034 ODatabaseMetaDataResultSet
* pResultSet
= new
1035 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumnPrivileges
);
1036 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1037 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1039 static const OUString
wld("%");
1040 OUStringBuffer
queryBuf(
1042 "priv.RDB$RELATION_NAME, " // 1 Table name
1043 "priv.RDB$GRANTOR," // 2
1044 "priv.RDB$USER, " // 3 Grantee
1045 "priv.RDB$PRIVILEGE, " // 4
1046 "priv.RDB$GRANT_OPTION, " // 5 is Grantable
1047 "priv.RDB$FIELD_NAME " // 6 Column name
1048 "FROM RDB$USER_PRIVILEGES priv ");
1051 OUString sAppend
= "WHERE priv.RDB$RELATION_NAME = '%' ";
1052 queryBuf
.append(sAppend
.replaceAll("%", sTable
));
1054 if (!sColumnNamePattern
.isEmpty())
1057 if (sColumnNamePattern
.match(wld
))
1058 sAppend
= "AND priv.RDB$FIELD_NAME LIKE '%' ";
1060 sAppend
= "AND priv.RDB$FIELD_NAME = '%' ";
1062 queryBuf
.append(sAppend
.replaceAll(wld
, sColumnNamePattern
));
1065 queryBuf
.append(" ORDER BY priv.RDB$FIELD, "
1066 "priv.RDB$PRIVILEGE");
1068 OUString query
= queryBuf
.makeStringAndClear();
1070 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1071 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1072 ODatabaseMetaDataResultSet::ORows aResults
;
1074 ODatabaseMetaDataResultSet::ORow
aCurrentRow(8);
1075 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused
1076 aCurrentRow
[1] = new ORowSetValueDecorator(); // 1. TABLE_CAT Unsupported
1077 aCurrentRow
[2] = new ORowSetValueDecorator(); // 1. TABLE_SCHEM Unsupported
1082 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1084 aCurrentRow
[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(6)));
1085 aCurrentRow
[5] = new ORowSetValueDecorator(xRow
->getString(2)); // 5. GRANTOR
1086 aCurrentRow
[6] = new ORowSetValueDecorator(xRow
->getString(3)); // 6. GRANTEE
1087 aCurrentRow
[7] = new ORowSetValueDecorator(xRow
->getString(4)); // 7. Privilege
1088 aCurrentRow
[7] = new ORowSetValueDecorator(xRow
->getBoolean(5)); // 8. Grantable
1090 aResults
.push_back(aCurrentRow
);
1093 pResultSet
->setRows( aResults
);
1098 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getColumns(
1099 const Any
& /*catalog*/,
1100 const OUString
& /*schemaPattern*/,
1101 const OUString
& tableNamePattern
,
1102 const OUString
& columnNamePattern
)
1103 throw(SQLException
, RuntimeException
, std::exception
)
1105 SAL_INFO("connectivity.firebird", "getColumns() with "
1106 "TableNamePattern: " << tableNamePattern
<<
1107 " & ColumnNamePattern: " << columnNamePattern
);
1109 OUStringBuffer
queryBuf("SELECT "
1110 "relfields.RDB$RELATION_NAME, " // 1
1111 "relfields.RDB$FIELD_NAME, " // 2
1112 "relfields.RDB$DESCRIPTION," // 3
1113 "relfields.RDB$DEFAULT_VALUE, " // 4
1114 "relfields.RDB$FIELD_POSITION, "// 5
1115 "fields.RDB$FIELD_TYPE, " // 6
1116 "fields.RDB$FIELD_LENGTH, " // 7
1117 "fields.RDB$FIELD_PRECISION, " // 8
1118 // Specifically use relfields null flag -- the one in fields is used
1119 // for domains, whether a specific field is nullable is set in relfields,
1120 // this is also the one we manually fiddle when changin NULL/NOT NULL
1122 "relfields.RDB$NULL_FLAG " // 9
1123 "FROM RDB$RELATION_FIELDS relfields "
1124 "JOIN RDB$FIELDS fields "
1125 "on (fields.RDB$FIELD_NAME = relfields.RDB$FIELD_SOURCE) "
1128 if (!tableNamePattern
.isEmpty())
1131 if (tableNamePattern
.match("%"))
1132 sAppend
= "AND relfields.RDB$RELATION_NAME LIKE '%' ";
1134 sAppend
= "AND relfields.RDB$RELATION_NAME = '%' ";
1136 queryBuf
.append(sAppend
.replaceAll("%", tableNamePattern
));
1139 if (!columnNamePattern
.isEmpty())
1142 if (columnNamePattern
.match("%"))
1143 sAppend
= "AND relfields.RDB$FIELD_NAME LIKE '%' ";
1145 sAppend
= "AND relfields.RDB$FIELD_NAME = '%' ";
1147 queryBuf
.append(sAppend
.replaceAll("%", columnNamePattern
));
1150 OUString query
= queryBuf
.makeStringAndClear();
1152 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1153 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1154 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1156 ODatabaseMetaDataResultSet::ORows aResults
;
1157 ODatabaseMetaDataResultSet::ORow
aCurrentRow(19);
1159 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1160 aCurrentRow
[1] = new ORowSetValueDecorator(); // Catalog - can be null
1161 aCurrentRow
[2] = new ORowSetValueDecorator(); // Schema - can be null
1162 aCurrentRow
[8] = new ORowSetValueDecorator(); // Unused
1163 aCurrentRow
[10] = new ORowSetValueDecorator(sal_Int32(10)); // Radix: fixed in FB
1164 aCurrentRow
[14] = new ORowSetValueDecorator(); // Unused
1165 aCurrentRow
[15] = new ORowSetValueDecorator(); // Unused
1170 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1172 aCurrentRow
[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(2)));
1174 short aType
= getFBTypeFromBlrType(xRow
->getShort(6));
1175 aCurrentRow
[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType
));
1176 // 6. Typename (SQL_*)
1177 aCurrentRow
[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType
));
1181 sal_Int32 aColumnSize
= 0;
1186 aColumnSize
= xRow
->getShort(7);
1195 aColumnSize
= xRow
->getShort(8);
1206 aCurrentRow
[7] = new ORowSetValueDecorator(aColumnSize
);
1209 // 9. Decimal Digits
1211 aCurrentRow
[9] = new ORowSetValueDecorator(sal_Int32(0));
1214 if (xRow
->getShort(9))
1216 aCurrentRow
[11] = new ORowSetValueDecorator(ColumnValue::NO_NULLS
);
1220 aCurrentRow
[11] = new ORowSetValueDecorator(ColumnValue::NULLABLE
);
1222 // 12. Comments -- may be omitted
1224 OUString aDescription
;
1225 uno::Reference
< XBlob
> xDescriptionBlob
= xRow
->getBlob(3);
1226 if (xDescriptionBlob
.is())
1228 sal_Int32 aBlobLength
= (sal_Int32
) xDescriptionBlob
->length();
1229 aDescription
= OUString((char*) xDescriptionBlob
->getBytes(0, aBlobLength
).getArray(),
1231 RTL_TEXTENCODING_UTF8
);
1233 aCurrentRow
[12] = new ORowSetValueDecorator(aDescription
);
1235 // 13. Default -- may be omitted.
1237 uno::Reference
< XBlob
> xDefaultValueBlob
= xRow
->getBlob(4);
1238 if (xDefaultValueBlob
.is())
1242 aCurrentRow
[13] = new ORowSetValueDecorator();
1245 // 16. Bytes in Column for char
1246 if (aType
== SQL_TEXT
)
1248 aCurrentRow
[16] = new ORowSetValueDecorator(xRow
->getShort(7));
1250 else if (aType
== SQL_VARYING
)
1252 aCurrentRow
[16] = new ORowSetValueDecorator(sal_Int32(32767));
1256 aCurrentRow
[16] = new ORowSetValueDecorator(sal_Int32(0));
1258 // 17. Index of column
1260 short nColumnNumber
= xRow
->getShort(5);
1261 // Firebird stores column numbers beginning with 0 internally
1262 // SDBC expects column numbering to begin with 1.
1263 aCurrentRow
[17] = new ORowSetValueDecorator(sal_Int32(nColumnNumber
+ 1));
1266 if (xRow
->getShort(9))
1268 aCurrentRow
[18] = new ORowSetValueDecorator(OUString("NO"));
1272 aCurrentRow
[18] = new ORowSetValueDecorator(OUString("YES"));
1275 aResults
.push_back(aCurrentRow
);
1277 ODatabaseMetaDataResultSet
* pResultSet
= new
1278 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumns
);
1279 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1280 pResultSet
->setRows( aResults
);
1285 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTables(
1286 const Any
& /*catalog*/,
1287 const OUString
& /*schemaPattern*/,
1288 const OUString
& tableNamePattern
,
1289 const Sequence
< OUString
>& types
)
1290 throw(SQLException
, RuntimeException
, std::exception
)
1292 SAL_INFO("connectivity.firebird", "getTables() with "
1293 "TableNamePattern: " << tableNamePattern
);
1295 ODatabaseMetaDataResultSet
* pResultSet
= new
1296 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables
);
1297 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1298 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1300 static const OUString
wld("%");
1301 OUStringBuffer
queryBuf(
1303 "RDB$RELATION_NAME, "
1305 "RDB$RELATION_TYPE, "
1308 "FROM RDB$RELATIONS "
1311 // TODO: GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, SYNONYM
1312 if ((types
.getLength() == 0) || (types
.getLength() == 1 && types
[0].match(wld
)))
1314 // All table types? I.e. includes system tables.
1315 queryBuf
.append("(RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1) ");
1319 queryBuf
.append("( (0 = 1) ");
1320 for (int i
= 0; i
< types
.getLength(); i
++)
1322 if (types
[i
] == "SYSTEM TABLE")
1323 queryBuf
.append("OR (RDB$SYSTEM_FLAG = 1 AND RDB$VIEW_BLR IS NULL) ");
1324 else if (types
[i
] == "TABLE")
1325 queryBuf
.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NULL) ");
1326 else if (types
[i
] == "VIEW")
1327 queryBuf
.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NOT NULL) ");
1329 throw SQLException(); // TODO: implement other types, see above.
1331 queryBuf
.append(") ");
1334 if (!tableNamePattern
.isEmpty())
1337 if (tableNamePattern
.match(wld
))
1338 sAppend
= "AND RDB$RELATION_NAME LIKE '%' ";
1340 sAppend
= "AND RDB$RELATION_NAME = '%' ";
1342 queryBuf
.append(sAppend
.replaceAll(wld
, tableNamePattern
));
1345 queryBuf
.append(" ORDER BY RDB$RELATION_TYPE, RDB$RELATION_NAME");
1347 OUString query
= queryBuf
.makeStringAndClear();
1349 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1350 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1351 ODatabaseMetaDataResultSet::ORows aResults
;
1353 ODatabaseMetaDataResultSet::ORow
aCurrentRow(6);
1354 aCurrentRow
[0] = new ORowSetValueDecorator(); // 0. Unused
1355 aCurrentRow
[1] = new ORowSetValueDecorator(); // 1. Table_Cat Unsupported
1356 aCurrentRow
[2] = new ORowSetValueDecorator(); // 2. Table_Schem Unsupported
1361 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1364 // TODO: check this as the docs are a bit unclear.
1365 sal_Int16 nSystemFlag
= xRow
->getShort(2);
1366 sal_Int16 nTableType
= xRow
->getShort(3);
1367 xRow
->getBlob(5); // We have to retrieve a column to verify it is null.
1368 bool aIsView
= !xRow
->wasNull();
1369 OUString sTableType
;
1371 if (nSystemFlag
== 1)
1373 sTableType
= "SYSTEM TABLE";
1377 sTableType
= "VIEW";
1381 if (nTableType
== 0)
1382 sTableType
= "TABLE";
1385 aCurrentRow
[4] = new ORowSetValueDecorator(sTableType
);
1389 uno::Reference
< XBlob
> xBlob
= xRow
->getBlob(4);
1390 OUString sDescription
;
1394 // TODO: we should actually be using CLOB here instead.
1395 // However we haven't implemented CLOB yet, so use BLOB.
1396 sal_Int32 aBlobLength
= (sal_Int32
) xBlob
->length();
1397 sDescription
= OUString((char*) xBlob
->getBytes(0, aBlobLength
).getArray(),
1399 RTL_TEXTENCODING_UTF8
);
1402 aCurrentRow
[5] = new ORowSetValueDecorator(sDescription
);
1405 aResults
.push_back(aCurrentRow
);
1408 pResultSet
->setRows( aResults
);
1413 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getProcedureColumns(
1414 const Any
& catalog
, const OUString
& schemaPattern
,
1415 const OUString
& procedureNamePattern
, const OUString
& columnNamePattern
) throw(SQLException
, RuntimeException
, std::exception
)
1417 SAL_WARN("connectivity.firebird", "Not yet implemented");
1419 (void) schemaPattern
;
1420 (void) procedureNamePattern
;
1421 (void) columnNamePattern
;
1422 OSL_FAIL("Not implemented yet!");
1424 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedureColumns
);
1427 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getProcedures(
1428 const Any
& catalog
, const OUString
& schemaPattern
,
1429 const OUString
& procedureNamePattern
) throw(SQLException
, RuntimeException
, std::exception
)
1431 SAL_WARN("connectivity.firebird", "Not yet implemented");
1433 (void) schemaPattern
;
1434 (void) procedureNamePattern
;
1435 OSL_FAIL("Not implemented yet!");
1437 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedures
);
1440 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getVersionColumns(
1441 const Any
& catalog
, const OUString
& schema
, const OUString
& table
) throw(SQLException
, RuntimeException
, std::exception
)
1443 SAL_WARN("connectivity.firebird", "Not yet implemented");
1447 OSL_FAIL("Not implemented yet!");
1449 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eVersionColumns
);
1452 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getExportedKeys(
1453 const Any
& catalog
, const OUString
& schema
, const OUString
& table
) throw(SQLException
, RuntimeException
, std::exception
)
1455 // List the columns in a table which are foreign keys. This is actually
1456 // never used anywhere in the LO codebase currently. Retrieval from firebird
1457 // requires using a 5-table join.
1458 SAL_WARN("connectivity.firebird", "Not yet implemented");
1462 OSL_FAIL("Not implemented yet!");
1464 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eExportedKeys
);
1467 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getImportedKeys(
1468 const Any
& catalog
, const OUString
& schema
, const OUString
& table
) throw(SQLException
, RuntimeException
, std::exception
)
1470 // List the columns in a table (which must be primary key, or possibly just
1471 // unique) that are referred to in other foreign keys. Will have a similar
1472 // 5-table or so join as in getExportedKeys.
1473 SAL_WARN("connectivity.firebird", "Not yet implemented");
1477 OSL_FAIL("Not implemented yet!");
1479 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eImportedKeys
);
1482 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getPrimaryKeys(
1483 const Any
& /*aCatalog*/,
1484 const OUString
& /*sSchema*/,
1485 const OUString
& sTable
)
1486 throw(SQLException
, RuntimeException
, std::exception
)
1488 SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
1489 "Table: " << sTable
);
1491 OUStringBuffer
aQueryBuf("SELECT "
1492 "constr.RDB$RELATION_NAME, " // 1. Table Name
1493 "inds.RDB$FIELD_NAME, " // 2. Column Name
1494 "inds.RDB$FIELD_POSITION, " // 3. Sequence Number
1495 "constr.RDB$CONSTRAINT_NAME " // 4 Constraint name
1496 "FROM RDB$RELATION_CONSTRAINTS constr "
1497 "JOIN RDB$INDEX_SEGMENTS inds "
1498 "on (constr.RDB$INDEX_NAME = inds.RDB$INDEX_NAME) ");
1500 OUString sAppend
= "WHERE constr.RDB$RELATION_NAME = '%' ";
1501 aQueryBuf
.append(sAppend
.replaceAll("%", sTable
));
1503 aQueryBuf
.append("AND constr.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
1504 "ORDER BY inds.RDB$FIELD_NAME");
1506 OUString sQuery
= aQueryBuf
.makeStringAndClear();
1508 uno::Reference
< XStatement
> xStatement
= m_pConnection
->createStatement();
1509 uno::Reference
< XResultSet
> xRs
= xStatement
->executeQuery(sQuery
);
1510 uno::Reference
< XRow
> xRow( xRs
, UNO_QUERY_THROW
);
1512 ODatabaseMetaDataResultSet::ORows aResults
;
1513 ODatabaseMetaDataResultSet::ORow
aCurrentRow(7);
1515 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1516 aCurrentRow
[1] = new ORowSetValueDecorator(); // Catalog - can be null
1517 aCurrentRow
[2] = new ORowSetValueDecorator(); // Schema - can be null
1522 if (xRs
->getRow() == 1) // Table name doesn't change, so only retrieve once
1524 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1527 aCurrentRow
[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(2)));
1528 // 5. KEY_SEQ (which key in the sequence)
1529 aCurrentRow
[5] = new ORowSetValueDecorator(xRow
->getShort(3));
1530 // 6. Primary Key Name
1531 aCurrentRow
[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(4)));
1533 aResults
.push_back(aCurrentRow
);
1535 ODatabaseMetaDataResultSet
* pResultSet
= new
1536 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys
);
1537 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1538 pResultSet
->setRows( aResults
);
1543 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getIndexInfo(
1544 const Any
& /*aCatalog*/,
1545 const OUString
& /*sSchema*/,
1546 const OUString
& sTable
,
1548 sal_Bool bIsApproximate
)
1549 throw(SQLException
, RuntimeException
, std::exception
)
1551 // Apparently this method can also return a "tableIndexStatistic"
1552 // However this is only mentioned in XDatabaseMetaData.idl (whose comments
1553 // are duplicated in the postgresql driver), and is otherwise undocumented.
1554 SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
1555 "Table: " << sTable
);
1557 OUStringBuffer
aQueryBuf("SELECT "
1558 "indices.RDB$RELATION_NAME, " // 1. Table Name
1559 "index_segments.RDB$FIELD_NAME, " // 2. Column Name
1560 "index_segments.RDB$FIELD_POSITION, " // 3. Sequence Number
1561 "indices.RDB$INDEX_NAME, " // 4. Index name
1562 "indices.RDB$UNIQUE_FLAG, " // 5. Unique Flag
1563 "indices.RDB$INDEX_TYPE " // 6. Index Type
1564 "FROM RDB$INDICES indices "
1565 "JOIN RDB$INDEX_SEGMENTS index_segments "
1566 "on (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) "
1567 "WHERE indices.RDB$RELATION_NAME = '" + sTable
+ "' "
1568 "AND (indices.RDB$SYSTEM_FLAG = 0) ");
1569 // Not sure whether we should exclude system indices, but otoh. we never
1570 // actually deal with system tables (system indices only apply to system
1571 // tables) within the GUI.
1573 // Only filter if true (according to the docs), i.e.:
1574 // If false we return all indices, if true we return only unique indices
1576 aQueryBuf
.append("AND (indices.RDB$UNIQUE_FLAG = 1) ");
1578 // TODO: what is bIsApproximate?
1579 (void) bIsApproximate
;
1581 OUString sQuery
= aQueryBuf
.makeStringAndClear();
1583 uno::Reference
< XStatement
> xStatement
= m_pConnection
->createStatement();
1584 uno::Reference
< XResultSet
> xRs
= xStatement
->executeQuery(sQuery
);
1585 uno::Reference
< XRow
> xRow( xRs
, UNO_QUERY_THROW
);
1587 ODatabaseMetaDataResultSet::ORows aResults
;
1588 ODatabaseMetaDataResultSet::ORow
aCurrentRow(14);
1590 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1591 aCurrentRow
[1] = new ORowSetValueDecorator(); // Catalog - can be null
1592 aCurrentRow
[2] = new ORowSetValueDecorator(); // Schema - can be null
1593 aCurrentRow
[5] = new ORowSetValueDecorator(); // Index Catalog -- can be null
1594 // According to wikipedia firebird uses clustered indices.
1595 // The documentation does not specifically seem to specify this.
1596 aCurrentRow
[7] = new ORowSetValueDecorator(IndexType::CLUSTERED
); // 7. INDEX TYPE
1597 aCurrentRow
[13] = new ORowSetValueDecorator(); // Filter Condition -- can be null
1602 if (xRs
->getRow() == 1) // Table name doesn't change, so only retrieve once
1604 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1607 // 4. NON_UNIQUE -- i.e. specifically negate here.
1608 aCurrentRow
[4] = new ORowSetValueDecorator(!xRow
->getBoolean(5));
1610 aCurrentRow
[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(4)));
1612 // 8. ORDINAL POSITION
1613 aCurrentRow
[8] = new ORowSetValueDecorator(xRow
->getShort(3));
1615 aCurrentRow
[9] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(2)));
1616 // 10. ASC(ending)/DESC(ending)
1617 if (xRow
->getShort(6) == 1)
1618 aCurrentRow
[10] = new ORowSetValueDecorator(OUString("D"));
1620 aCurrentRow
[10] = new ORowSetValueDecorator(OUString("A"));
1621 // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
1623 aCurrentRow
[11] = new ORowSetValueDecorator((sal_Int32
)0); // TODO: determine how to do this
1625 aCurrentRow
[12] = new ORowSetValueDecorator((sal_Int32
)0); // TODO: determine how to do this
1627 aResults
.push_back(aCurrentRow
);
1629 ODatabaseMetaDataResultSet
* pResultSet
= new
1630 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys
);
1631 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1632 pResultSet
->setRows( aResults
);
1637 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getBestRowIdentifier(
1638 const Any
& catalog
, const OUString
& schema
, const OUString
& table
, sal_Int32 scope
,
1639 sal_Bool nullable
) throw(SQLException
, RuntimeException
, std::exception
)
1646 OSL_FAIL("Not implemented yet!");
1648 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eBestRowIdentifier
);
1651 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTablePrivileges(
1652 const Any
& /*aCatalog*/,
1653 const OUString
& /*sSchemaPattern*/,
1654 const OUString
& sTableNamePattern
)
1655 throw(SQLException
, RuntimeException
, std::exception
)
1657 SAL_INFO("connectivity.firebird", "getTablePrivileges() with "
1658 "TableNamePattern: " << sTableNamePattern
);
1660 ODatabaseMetaDataResultSet
* pResultSet
= new
1661 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTablePrivileges
);
1662 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1663 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1665 // TODO: column specific privileges are included, we may need
1666 // to have WHERE RDB$FIELD_NAME = NULL or similar.
1667 static const OUString
wld("%");
1668 OUStringBuffer
queryBuf(
1670 "priv.RDB$RELATION_NAME, " // 1
1671 "priv.RDB$GRANTOR," // 2
1672 "priv.RDB$USER, " // 3 Grantee
1673 "priv.RDB$PRIVILEGE, " // 4
1674 "priv.RDB$GRANT_OPTION " // 5 is Grantable
1675 "FROM RDB$USER_PRIVILEGES priv ");
1677 if (!sTableNamePattern
.isEmpty())
1680 if (sTableNamePattern
.match(wld
))
1681 sAppend
= "WHERE priv.RDB$RELATION_NAME LIKE '%' ";
1683 sAppend
= "WHERE priv.RDB$RELATION_NAME = '%' ";
1685 queryBuf
.append(sAppend
.replaceAll(wld
, sTableNamePattern
));
1687 queryBuf
.append(" ORDER BY priv.RDB$RELATION_TYPE, "
1688 "priv.RDB$RELATION_NAME, "
1689 "priv.RDB$PRIVILEGE");
1691 OUString query
= queryBuf
.makeStringAndClear();
1693 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1694 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1695 ODatabaseMetaDataResultSet::ORows aResults
;
1697 ODatabaseMetaDataResultSet::ORow
aRow(8);
1698 aRow
[0] = new ORowSetValueDecorator(); // Unused
1699 aRow
[1] = new ORowSetValueDecorator(); // TABLE_CAT unsupported
1700 aRow
[2] = new ORowSetValueDecorator(); // TABLE_SCHEM unussported.
1705 aRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1706 aRow
[4] = new ORowSetValueDecorator(xRow
->getString(2)); // 4. GRANTOR
1707 aRow
[5] = new ORowSetValueDecorator(xRow
->getString(3)); // 5. GRANTEE
1708 aRow
[6] = new ORowSetValueDecorator(xRow
->getString(4)); // 6. Privilege
1709 aRow
[7] = new ORowSetValueDecorator(xRow
->getBoolean(5)); // 7. Is Grantable
1711 aResults
.push_back(aRow
);
1714 pResultSet
->setRows( aResults
);
1719 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getCrossReference(
1720 const Any
& primaryCatalog
, const OUString
& primarySchema
,
1721 const OUString
& primaryTable
, const Any
& foreignCatalog
,
1722 const OUString
& foreignSchema
, const OUString
& foreignTable
) throw(SQLException
, RuntimeException
, std::exception
)
1724 (void) primaryCatalog
;
1725 (void) primarySchema
;
1726 (void) primaryTable
;
1727 (void) foreignCatalog
;
1728 (void) foreignSchema
;
1729 (void) foreignTable
;
1730 OSL_FAIL("Not implemented yet!");
1732 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCrossReference
);
1735 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getUDTs( const Any
& catalog
, const OUString
& schemaPattern
, const OUString
& typeNamePattern
, const Sequence
< sal_Int32
>& types
) throw(SQLException
, RuntimeException
, std::exception
)
1738 (void) schemaPattern
;
1739 (void) typeNamePattern
;
1741 OSL_FAIL("Not implemented yet!");
1743 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs
);
1749 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */