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
;
37 using namespace com::sun::star
;
38 using namespace com::sun::star::uno
;
39 using namespace com::sun::star::lang
;
40 using namespace com::sun::star::beans
;
41 using namespace com::sun::star::sdbc
;
43 ODatabaseMetaData::ODatabaseMetaData(Connection
* _pCon
)
44 : m_pConnection(_pCon
)
46 SAL_WARN_IF(!m_pConnection
.is(), "connectivity.firebird",
47 "ODatabaseMetaData::ODatabaseMetaData: No connection set!");
50 ODatabaseMetaData::~ODatabaseMetaData()
54 //----- Catalog Info -- UNSUPPORTED -------------------------------------------
55 OUString SAL_CALL
ODatabaseMetaData::getCatalogSeparator() throw(SQLException
, RuntimeException
, std::exception
)
60 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxCatalogNameLength() throw(SQLException
, RuntimeException
, std::exception
)
65 OUString SAL_CALL
ODatabaseMetaData::getCatalogTerm() throw(SQLException
, RuntimeException
, std::exception
)
70 sal_Bool SAL_CALL
ODatabaseMetaData::isCatalogAtStart() throw(SQLException
, RuntimeException
, std::exception
)
75 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInTableDefinitions() throw(SQLException
, RuntimeException
, std::exception
)
80 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInIndexDefinitions() throw(SQLException
, RuntimeException
, std::exception
)
85 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInDataManipulation( ) throw(SQLException
, RuntimeException
, std::exception
)
90 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getCatalogs() throw(SQLException
, RuntimeException
, std::exception
)
92 OSL_FAIL("Not implemented yet!");
94 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCatalogs
);
97 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInProcedureCalls() throw(SQLException
, RuntimeException
, std::exception
)
102 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions() throw(SQLException
, RuntimeException
, std::exception
)
107 //----- Schema Info -- UNSUPPORTED --------------------------------------------
108 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInProcedureCalls()
109 throw(SQLException
, RuntimeException
, std::exception
)
114 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
115 throw(SQLException
, RuntimeException
, std::exception
)
120 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInDataManipulation()
121 throw(SQLException
, RuntimeException
, std::exception
)
126 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInIndexDefinitions()
127 throw(SQLException
, RuntimeException
, std::exception
)
132 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSchemasInTableDefinitions()
133 throw(SQLException
, RuntimeException
, std::exception
)
138 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxSchemaNameLength()
139 throw(SQLException
, RuntimeException
, std::exception
)
144 OUString SAL_CALL
ODatabaseMetaData::getSchemaTerm()
145 throw(SQLException
, RuntimeException
, std::exception
)
150 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getSchemas()
151 throw(SQLException
, RuntimeException
, std::exception
)
153 OSL_FAIL("Not implemented yet!");
155 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eSchemas
);
158 //----- Max Sizes/Lengths -----------------------------------------------------
159 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxBinaryLiteralLength() throw(SQLException
, RuntimeException
, std::exception
)
164 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxRowSize() throw(SQLException
, RuntimeException
, std::exception
)
169 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxCharLiteralLength() throw(SQLException
, RuntimeException
, std::exception
)
174 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnNameLength() throw(SQLException
, RuntimeException
, std::exception
)
179 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInIndex() throw(SQLException
, RuntimeException
, std::exception
)
182 // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
186 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxCursorNameLength() throw(SQLException
, RuntimeException
, std::exception
)
191 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxConnections() throw(SQLException
, RuntimeException
, std::exception
)
193 return 100; // Arbitrary
196 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInTable() throw(SQLException
, RuntimeException
, std::exception
)
198 // May however be smaller.
199 // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
203 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxStatementLength() throw(SQLException
, RuntimeException
, std::exception
)
208 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxTableNameLength() throw(SQLException
, RuntimeException
, std::exception
)
213 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxTablesInSelect( ) throw(SQLException
, RuntimeException
, std::exception
)
215 sal_Int32 nValue
= 0; // 0 means no limit
220 sal_Bool SAL_CALL
ODatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw(SQLException
, RuntimeException
, std::exception
)
225 // ---- Identifiers -----------------------------------------------------------
226 // Only quoted identifiers are case sensitive, unquoted are case insensitive
227 OUString SAL_CALL
ODatabaseMetaData::getIdentifierQuoteString()
228 throw(SQLException
, RuntimeException
, std::exception
)
234 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw(SQLException
, RuntimeException
, std::exception
)
239 sal_Bool SAL_CALL
ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
240 throw(SQLException
, RuntimeException
, std::exception
)
245 sal_Bool SAL_CALL
ODatabaseMetaData::storesMixedCaseQuotedIdentifiers()
246 throw(SQLException
, RuntimeException
, std::exception
)
248 // TODO: confirm this -- the documentation is highly ambiguous
249 // However it seems this should be true as quoted identifiers ARE
250 // stored mixed case.
254 sal_Bool SAL_CALL
ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
255 throw(SQLException
, RuntimeException
, std::exception
)
260 // ---- Unquoted Identifiers -------------------------------------------------
261 // All unquoted identifiers are stored upper case.
262 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMixedCaseIdentifiers()
263 throw(SQLException
, RuntimeException
, std::exception
)
268 sal_Bool SAL_CALL
ODatabaseMetaData::storesLowerCaseIdentifiers()
269 throw(SQLException
, RuntimeException
, std::exception
)
274 sal_Bool SAL_CALL
ODatabaseMetaData::storesMixedCaseIdentifiers()
275 throw(SQLException
, RuntimeException
, std::exception
)
280 sal_Bool SAL_CALL
ODatabaseMetaData::storesUpperCaseIdentifiers()
281 throw(SQLException
, RuntimeException
, std::exception
)
286 // ---- SQL Feature Support ---------------------------------------------------
287 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCoreSQLGrammar()
288 throw(SQLException
, RuntimeException
, std::exception
)
293 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMinimumSQLGrammar()
294 throw(SQLException
, RuntimeException
, std::exception
)
299 sal_Bool SAL_CALL
ODatabaseMetaData::supportsAlterTableWithAddColumn()
300 throw(SQLException
, RuntimeException
, std::exception
)
305 sal_Bool SAL_CALL
ODatabaseMetaData::supportsAlterTableWithDropColumn()
306 throw(SQLException
, RuntimeException
, std::exception
)
311 sal_Bool SAL_CALL
ODatabaseMetaData::supportsPositionedDelete()
312 throw(SQLException
, RuntimeException
, std::exception
)
317 sal_Bool SAL_CALL
ODatabaseMetaData::supportsPositionedUpdate()
318 throw(SQLException
, RuntimeException
, std::exception
)
323 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOuterJoins()
324 throw(SQLException
, RuntimeException
, std::exception
)
329 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSelectForUpdate()
330 throw(SQLException
, RuntimeException
, std::exception
)
335 sal_Bool SAL_CALL
ODatabaseMetaData::allTablesAreSelectable()
336 throw(SQLException
, RuntimeException
, std::exception
)
338 // TODO: true if embedded, but unsure about remote server
342 sal_Bool SAL_CALL
ODatabaseMetaData::supportsConvert(sal_Int32 fromType
,
344 throw(SQLException
, RuntimeException
, std::exception
)
351 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTypeConversion()
352 throw(SQLException
, RuntimeException
, std::exception
)
357 sal_Bool SAL_CALL
ODatabaseMetaData::supportsColumnAliasing()
358 throw(SQLException
, RuntimeException
, std::exception
)
363 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTableCorrelationNames()
364 throw(SQLException
, RuntimeException
, std::exception
)
369 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxIndexLength( ) throw(SQLException
, RuntimeException
, std::exception
)
371 sal_Int32 nValue
= 0; // 0 means no limit
375 sal_Bool SAL_CALL
ODatabaseMetaData::supportsNonNullableColumns( ) throw(SQLException
, RuntimeException
, std::exception
)
380 OUString SAL_CALL
ODatabaseMetaData::getExtraNameCharacters( ) throw(SQLException
, RuntimeException
, std::exception
)
386 sal_Bool SAL_CALL
ODatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw(SQLException
, RuntimeException
, std::exception
)
390 // ---- Data definition stuff -------------------------------------------------
391 sal_Bool SAL_CALL
ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
392 throw(SQLException
, RuntimeException
, std::exception
)
397 sal_Bool SAL_CALL
ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
398 throw(SQLException
, RuntimeException
, std::exception
)
403 sal_Bool SAL_CALL
ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
404 throw(SQLException
, RuntimeException
, std::exception
)
409 sal_Bool SAL_CALL
ODatabaseMetaData::
410 supportsDataDefinitionAndDataManipulationTransactions()
411 throw(SQLException
, RuntimeException
, std::exception
)
415 //----- Transaction Support --------------------------------------------------
416 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTransactions()
417 throw(SQLException
, RuntimeException
, std::exception
)
422 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
423 throw(SQLException
, RuntimeException
, std::exception
)
428 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
429 throw(SQLException
, RuntimeException
, std::exception
)
434 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
435 throw(SQLException
, RuntimeException
, std::exception
)
440 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
441 throw(SQLException
, RuntimeException
, std::exception
)
446 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMultipleTransactions()
447 throw(SQLException
, RuntimeException
, std::exception
)
452 sal_Bool SAL_CALL
ODatabaseMetaData::supportsTransactionIsolationLevel(
454 throw(SQLException
, RuntimeException
, std::exception
)
456 return aLevel
== TransactionIsolation::READ_UNCOMMITTED
457 || aLevel
== TransactionIsolation::READ_COMMITTED
458 || aLevel
== TransactionIsolation::REPEATABLE_READ
459 || aLevel
== TransactionIsolation::SERIALIZABLE
;
462 sal_Int32 SAL_CALL
ODatabaseMetaData::getDefaultTransactionIsolation()
463 throw(SQLException
, RuntimeException
, std::exception
)
465 return TransactionIsolation::REPEATABLE_READ
;
469 sal_Bool SAL_CALL
ODatabaseMetaData::supportsANSI92FullSQL( ) throw(SQLException
, RuntimeException
, std::exception
)
474 sal_Bool SAL_CALL
ODatabaseMetaData::supportsANSI92EntryLevelSQL( ) throw(SQLException
, RuntimeException
, std::exception
)
476 return sal_True
; // should be supported at least
479 sal_Bool SAL_CALL
ODatabaseMetaData::supportsIntegrityEnhancementFacility( ) throw(SQLException
, RuntimeException
, std::exception
)
484 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxStatements( ) throw(SQLException
, RuntimeException
, std::exception
)
486 sal_Int32 nValue
= 0; // 0 means no limit
490 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxProcedureNameLength( ) throw(SQLException
, RuntimeException
, std::exception
)
492 sal_Int32 nValue
= 31; // TODO: confirm
496 sal_Bool SAL_CALL
ODatabaseMetaData::allProceduresAreCallable( ) throw(SQLException
, RuntimeException
, std::exception
)
501 sal_Bool SAL_CALL
ODatabaseMetaData::supportsStoredProcedures( ) throw(SQLException
, RuntimeException
, std::exception
)
506 sal_Bool SAL_CALL
ODatabaseMetaData::isReadOnly( ) throw(SQLException
, RuntimeException
, std::exception
)
508 return m_pConnection
->isReadOnly();
511 sal_Bool SAL_CALL
ODatabaseMetaData::usesLocalFiles( ) throw(SQLException
, RuntimeException
, std::exception
)
513 return m_pConnection
->isEmbedded();
516 sal_Bool SAL_CALL
ODatabaseMetaData::usesLocalFilePerTable( ) throw(SQLException
, RuntimeException
, std::exception
)
521 sal_Bool SAL_CALL
ODatabaseMetaData::nullPlusNonNullIsNull( ) throw(SQLException
, RuntimeException
, std::exception
)
526 sal_Bool SAL_CALL
ODatabaseMetaData::supportsExpressionsInOrderBy( ) throw(SQLException
, RuntimeException
, std::exception
)
531 sal_Bool SAL_CALL
ODatabaseMetaData::supportsGroupBy( ) throw(SQLException
, RuntimeException
, std::exception
)
536 sal_Bool SAL_CALL
ODatabaseMetaData::supportsGroupByBeyondSelect( ) throw(SQLException
, RuntimeException
, std::exception
)
542 sal_Bool SAL_CALL
ODatabaseMetaData::supportsGroupByUnrelated( ) throw(SQLException
, RuntimeException
, std::exception
)
549 sal_Bool SAL_CALL
ODatabaseMetaData::supportsMultipleResultSets( ) throw(SQLException
, RuntimeException
, std::exception
)
554 sal_Bool SAL_CALL
ODatabaseMetaData::supportsLikeEscapeClause( ) throw(SQLException
, RuntimeException
, std::exception
)
559 sal_Bool SAL_CALL
ODatabaseMetaData::supportsOrderByUnrelated( ) throw(SQLException
, RuntimeException
, std::exception
)
564 sal_Bool SAL_CALL
ODatabaseMetaData::supportsUnion( ) throw(SQLException
, RuntimeException
, std::exception
)
569 sal_Bool SAL_CALL
ODatabaseMetaData::supportsUnionAll( ) throw(SQLException
, RuntimeException
, std::exception
)
574 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedAtEnd( ) throw(SQLException
, RuntimeException
, std::exception
)
579 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedAtStart( ) throw(SQLException
, RuntimeException
, std::exception
)
584 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedHigh( ) throw(SQLException
, RuntimeException
, std::exception
)
589 sal_Bool SAL_CALL
ODatabaseMetaData::nullsAreSortedLow( ) throw(SQLException
, RuntimeException
, std::exception
)
594 sal_Bool SAL_CALL
ODatabaseMetaData::supportsCorrelatedSubqueries( ) throw(SQLException
, RuntimeException
, std::exception
)
599 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInComparisons( ) throw(SQLException
, RuntimeException
, std::exception
)
604 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInExists( ) throw(SQLException
, RuntimeException
, std::exception
)
609 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInIns( ) throw(SQLException
, RuntimeException
, std::exception
)
614 sal_Bool SAL_CALL
ODatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw(SQLException
, RuntimeException
, std::exception
)
619 sal_Bool SAL_CALL
ODatabaseMetaData::supportsANSI92IntermediateSQL( ) throw(SQLException
, RuntimeException
, std::exception
)
624 OUString SAL_CALL
ODatabaseMetaData::getURL() throw(SQLException
, RuntimeException
, std::exception
)
626 return m_pConnection
->getConnectionURL();
629 OUString SAL_CALL
ODatabaseMetaData::getUserName( ) throw(SQLException
, RuntimeException
, std::exception
)
635 OUString SAL_CALL
ODatabaseMetaData::getDriverName( ) throw(SQLException
, RuntimeException
, std::exception
)
641 OUString SAL_CALL
ODatabaseMetaData::getDriverVersion() throw(SQLException
, RuntimeException
, std::exception
)
647 OUString SAL_CALL
ODatabaseMetaData::getDatabaseProductVersion( ) throw(SQLException
, RuntimeException
, std::exception
)
653 OUString SAL_CALL
ODatabaseMetaData::getDatabaseProductName( ) throw(SQLException
, RuntimeException
, std::exception
)
659 OUString SAL_CALL
ODatabaseMetaData::getProcedureTerm( ) throw(SQLException
, RuntimeException
, std::exception
)
665 sal_Int32 SAL_CALL
ODatabaseMetaData::getDriverMajorVersion( ) throw(RuntimeException
, std::exception
)
670 sal_Int32 SAL_CALL
ODatabaseMetaData::getDriverMinorVersion( ) throw(RuntimeException
, std::exception
)
675 OUString SAL_CALL
ODatabaseMetaData::getSQLKeywords( ) throw(SQLException
, RuntimeException
, std::exception
)
681 OUString SAL_CALL
ODatabaseMetaData::getSearchStringEscape( ) throw(SQLException
, RuntimeException
, std::exception
)
687 OUString SAL_CALL
ODatabaseMetaData::getStringFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
692 OUString SAL_CALL
ODatabaseMetaData::getTimeDateFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
697 OUString SAL_CALL
ODatabaseMetaData::getSystemFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
702 OUString SAL_CALL
ODatabaseMetaData::getNumericFunctions( ) throw(SQLException
, RuntimeException
, std::exception
)
707 sal_Bool SAL_CALL
ODatabaseMetaData::supportsExtendedSQLGrammar( ) throw(SQLException
, RuntimeException
, std::exception
)
712 sal_Bool SAL_CALL
ODatabaseMetaData::supportsFullOuterJoins( ) throw(SQLException
, RuntimeException
, std::exception
)
717 sal_Bool SAL_CALL
ODatabaseMetaData::supportsLimitedOuterJoins( ) throw(SQLException
, RuntimeException
, std::exception
)
722 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInGroupBy( ) throw(SQLException
, RuntimeException
, std::exception
)
724 sal_Int32 nValue
= 0; // 0 means no limit
728 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInOrderBy( ) throw(SQLException
, RuntimeException
, std::exception
)
730 sal_Int32 nValue
= 0; // 0 means no limit
734 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxColumnsInSelect( ) throw(SQLException
, RuntimeException
, std::exception
)
736 sal_Int32 nValue
= 0; // 0 means no limit
740 sal_Int32 SAL_CALL
ODatabaseMetaData::getMaxUserNameLength( ) throw(SQLException
, RuntimeException
, std::exception
)
745 sal_Bool SAL_CALL
ODatabaseMetaData::supportsResultSetType(sal_Int32 setType
)
746 throw(SQLException
, RuntimeException
, std::exception
)
750 case ResultSetType::FORWARD_ONLY
:
757 sal_Bool SAL_CALL
ODatabaseMetaData::supportsResultSetConcurrency(
758 sal_Int32 aResultSetType
,
759 sal_Int32 aConcurrency
)
760 throw(SQLException
, RuntimeException
, std::exception
)
762 if (aResultSetType
== ResultSetType::FORWARD_ONLY
763 && aConcurrency
== ResultSetConcurrency::READ_ONLY
)
769 sal_Bool SAL_CALL
ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
775 sal_Bool SAL_CALL
ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
781 sal_Bool SAL_CALL
ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
787 sal_Bool SAL_CALL
ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
793 sal_Bool SAL_CALL
ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
799 sal_Bool SAL_CALL
ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
805 sal_Bool SAL_CALL
ODatabaseMetaData::updatesAreDetected( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
811 sal_Bool SAL_CALL
ODatabaseMetaData::deletesAreDetected( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
817 sal_Bool SAL_CALL
ODatabaseMetaData::insertsAreDetected( sal_Int32 setType
) throw(SQLException
, RuntimeException
, std::exception
)
823 sal_Bool SAL_CALL
ODatabaseMetaData::supportsBatchUpdates()
824 throw(SQLException
, RuntimeException
, std::exception
)
826 // No batch support in firebird
830 uno::Reference
< XConnection
> SAL_CALL
ODatabaseMetaData::getConnection()
831 throw(SQLException
, RuntimeException
, std::exception
)
833 return uno::Reference
<XConnection
>(m_pConnection
.get());
836 // here follow all methods which return a resultset
837 // the first methods is an example implementation how to use this resultset
838 // of course you could implement it on your and you should do this because
839 // the general way is more memory expensive
841 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTableTypes( ) throw(SQLException
, RuntimeException
, std::exception
)
843 OSL_FAIL("Not implemented yet!");
845 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTableTypes
);
848 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTypeInfo()
849 throw(SQLException
, RuntimeException
, std::exception
)
851 SAL_INFO("connectivity.firebird", "getTypeInfo()");
853 // this returns an empty resultset where the column-names are already set
854 // in special the metadata of the resultset already returns the right columns
855 ODatabaseMetaDataResultSet
* pResultSet
=
856 new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTypeInfo
);
857 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
858 static ODatabaseMetaDataResultSet::ORows aResults
;
862 ODatabaseMetaDataResultSet::ORow
aRow(19);
865 aRow
[4] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
866 aRow
[5] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
867 aRow
[7] = new ORowSetValueDecorator(sal_True
); // Nullable
868 aRow
[8] = new ORowSetValueDecorator(sal_True
); // Case sensitive
869 aRow
[10] = new ORowSetValueDecorator(sal_False
); // Is unsigned
870 // FIXED_PREC_SCALE: docs state "can it be a money value? " however
871 // in reality this causes Base to treat all numbers as money formatted
872 // by default which is wrong (and formatting as money value is still
873 // possible for all values).
874 aRow
[11] = new ORowSetValueDecorator(sal_False
);
875 // Localised Type Name -- TODO: implement (but can be null):
876 aRow
[13] = new ORowSetValueDecorator();
877 aRow
[16] = new ORowSetValueDecorator(); // Unused
878 aRow
[17] = new ORowSetValueDecorator(); // Unused
879 aRow
[18] = new ORowSetValueDecorator(sal_Int16(10));// Radix
882 aRow
[1] = new ORowSetValueDecorator(OUString("CHAR"));
883 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT
));
884 aRow
[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
885 aRow
[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
886 aRow
[9] = new ORowSetValueDecorator(
887 sal_Int16(ColumnSearch::FULL
)); // Searchable
888 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
889 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
890 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
891 aResults
.push_back(aRow
);
894 aRow
[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
895 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING
));
896 aRow
[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
897 aRow
[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
898 aRow
[9] = new ORowSetValueDecorator(
899 sal_Int16(ColumnSearch::FULL
)); // Searchable
900 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
901 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
902 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
903 aResults
.push_back(aRow
);
905 // Integer Types common
907 aRow
[6] = new ORowSetValueDecorator(); // Create Params
908 aRow
[9] = new ORowSetValueDecorator(
909 sal_Int16(ColumnSearch::FULL
)); // Searchable
910 aRow
[12] = new ORowSetValueDecorator(sal_True
); // Autoincrement
911 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
912 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
915 aRow
[1] = new ORowSetValueDecorator(OUString("SMALLINT"));
916 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT
));
917 aRow
[3] = new ORowSetValueDecorator(sal_Int16(5)); // Prevision
918 aResults
.push_back(aRow
);
920 aRow
[1] = new ORowSetValueDecorator(OUString("INTEGER"));
921 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG
));
922 aRow
[3] = new ORowSetValueDecorator(sal_Int16(10)); // Precision
923 aResults
.push_back(aRow
);
925 aRow
[1] = new ORowSetValueDecorator(OUString("BIGINT"));
926 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64
));
927 aRow
[3] = new ORowSetValueDecorator(sal_Int16(20)); // Precision
928 aResults
.push_back(aRow
);
930 // Decimal Types common
932 aRow
[6] = new ORowSetValueDecorator(); // Create Params
933 aRow
[9] = new ORowSetValueDecorator(
934 sal_Int16(ColumnSearch::FULL
)); // Searchable
935 aRow
[12] = new ORowSetValueDecorator(sal_True
); // Autoincrement
938 aRow
[1] = new ORowSetValueDecorator(OUString("FLOAT"));
939 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT
));
940 aRow
[3] = new ORowSetValueDecorator(sal_Int16(7)); // Precision
941 aRow
[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
942 aRow
[15] = new ORowSetValueDecorator(sal_Int16(7)); // Max scale
943 aResults
.push_back(aRow
);
945 aRow
[1] = new ORowSetValueDecorator(OUString("DOUBLE PRECISION"));
946 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE
));
947 aRow
[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
948 aRow
[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
949 aRow
[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
950 aResults
.push_back(aRow
);
952 // aRow[1] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(SQL_D_FLOAT));
953 // aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_D_FLOAT));
954 // aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
955 // aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
956 // aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
957 // aResults.push_back(aRow);
958 // TODO: no idea whether D_FLOAT corresponds to an sql type
962 aRow
[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
963 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP
));
964 aRow
[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
965 aRow
[6] = new ORowSetValueDecorator(); // Create Params
966 aRow
[9] = new ORowSetValueDecorator(
967 sal_Int16(ColumnSearch::FULL
)); // Searchable
968 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
969 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
970 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
971 aResults
.push_back(aRow
);
975 aRow
[1] = new ORowSetValueDecorator(OUString("TIME"));
976 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME
));
977 aRow
[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
978 aRow
[6] = new ORowSetValueDecorator(); // Create Params
979 aRow
[9] = new ORowSetValueDecorator(
980 sal_Int16(ColumnSearch::FULL
)); // Searchable
981 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
982 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
983 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
984 aResults
.push_back(aRow
);
988 aRow
[1] = new ORowSetValueDecorator(OUString("DATE"));
989 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE
));
990 aRow
[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
991 aRow
[6] = new ORowSetValueDecorator(); // Create Params
992 aRow
[9] = new ORowSetValueDecorator(
993 sal_Int16(ColumnSearch::FULL
)); // Searchable
994 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
995 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
996 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
997 aResults
.push_back(aRow
);
1001 aRow
[1] = new ORowSetValueDecorator(OUString("BLOB"));
1002 aRow
[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB
));
1003 aRow
[3] = new ORowSetValueDecorator(sal_Int32(0)); // Prevision = max length
1004 aRow
[6] = new ORowSetValueDecorator(); // Create Params
1005 aRow
[9] = new ORowSetValueDecorator(
1006 sal_Int16(ColumnSearch::NONE
)); // Searchable
1007 aRow
[12] = new ORowSetValueDecorator(sal_False
); // Autoincrement
1008 aRow
[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
1009 aRow
[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
1010 aResults
.push_back(aRow
);
1015 // case SQL_QUAD: // Is a "Blob ID" according to the docs
1017 pResultSet
->setRows(aResults
);
1021 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getColumnPrivileges(
1022 const Any
& /*aCatalog*/,
1023 const OUString
& /*sSchema*/,
1024 const OUString
& sTable
,
1025 const OUString
& sColumnNamePattern
)
1026 throw(SQLException
, RuntimeException
, std::exception
)
1028 SAL_INFO("connectivity.firebird", "getColumnPrivileges() with "
1030 << " & ColumnNamePattern: " << sColumnNamePattern
);
1032 ODatabaseMetaDataResultSet
* pResultSet
= new
1033 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumnPrivileges
);
1034 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1035 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1037 static const char wld
[] = "%";
1038 OUStringBuffer
queryBuf(
1040 "priv.RDB$RELATION_NAME, " // 1 Table name
1041 "priv.RDB$GRANTOR," // 2
1042 "priv.RDB$USER, " // 3 Grantee
1043 "priv.RDB$PRIVILEGE, " // 4
1044 "priv.RDB$GRANT_OPTION, " // 5 is Grantable
1045 "priv.RDB$FIELD_NAME " // 6 Column name
1046 "FROM RDB$USER_PRIVILEGES priv ");
1049 OUString sAppend
= "WHERE priv.RDB$RELATION_NAME = '%' ";
1050 queryBuf
.append(sAppend
.replaceAll("%", sTable
));
1052 if (!sColumnNamePattern
.isEmpty())
1055 if (sColumnNamePattern
.match(wld
))
1056 sAppend
= "AND priv.RDB$FIELD_NAME LIKE '%' ";
1058 sAppend
= "AND priv.RDB$FIELD_NAME = '%' ";
1060 queryBuf
.append(sAppend
.replaceAll(wld
, sColumnNamePattern
));
1063 queryBuf
.append(" ORDER BY priv.RDB$FIELD, "
1064 "priv.RDB$PRIVILEGE");
1066 OUString query
= queryBuf
.makeStringAndClear();
1068 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1069 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1070 ODatabaseMetaDataResultSet::ORows aResults
;
1072 ODatabaseMetaDataResultSet::ORow
aCurrentRow(8);
1073 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused
1074 aCurrentRow
[1] = new ORowSetValueDecorator(); // 1. TABLE_CAT Unsupported
1075 aCurrentRow
[2] = new ORowSetValueDecorator(); // 1. TABLE_SCHEM Unsupported
1080 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1082 aCurrentRow
[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(6)));
1083 aCurrentRow
[5] = new ORowSetValueDecorator(xRow
->getString(2)); // 5. GRANTOR
1084 aCurrentRow
[6] = new ORowSetValueDecorator(xRow
->getString(3)); // 6. GRANTEE
1085 aCurrentRow
[7] = new ORowSetValueDecorator(xRow
->getString(4)); // 7. Privilege
1086 aCurrentRow
[7] = new ORowSetValueDecorator(xRow
->getBoolean(5)); // 8. Grantable
1088 aResults
.push_back(aCurrentRow
);
1091 pResultSet
->setRows( aResults
);
1096 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getColumns(
1097 const Any
& /*catalog*/,
1098 const OUString
& /*schemaPattern*/,
1099 const OUString
& tableNamePattern
,
1100 const OUString
& columnNamePattern
)
1101 throw(SQLException
, RuntimeException
, std::exception
)
1103 SAL_INFO("connectivity.firebird", "getColumns() with "
1104 "TableNamePattern: " << tableNamePattern
<<
1105 " & ColumnNamePattern: " << columnNamePattern
);
1107 OUStringBuffer
queryBuf("SELECT "
1108 "relfields.RDB$RELATION_NAME, " // 1
1109 "relfields.RDB$FIELD_NAME, " // 2
1110 "relfields.RDB$DESCRIPTION," // 3
1111 "relfields.RDB$DEFAULT_VALUE, " // 4
1112 "relfields.RDB$FIELD_POSITION, "// 5
1113 "fields.RDB$FIELD_TYPE, " // 6
1114 "fields.RDB$FIELD_LENGTH, " // 7
1115 "fields.RDB$FIELD_PRECISION, " // 8
1116 // Specifically use relfields null flag -- the one in fields is used
1117 // for domains, whether a specific field is nullable is set in relfields,
1118 // this is also the one we manually fiddle when changin NULL/NOT NULL
1120 "relfields.RDB$NULL_FLAG " // 9
1121 "FROM RDB$RELATION_FIELDS relfields "
1122 "JOIN RDB$FIELDS fields "
1123 "on (fields.RDB$FIELD_NAME = relfields.RDB$FIELD_SOURCE) "
1126 if (!tableNamePattern
.isEmpty())
1129 if (tableNamePattern
.match("%"))
1130 sAppend
= "AND relfields.RDB$RELATION_NAME LIKE '%' ";
1132 sAppend
= "AND relfields.RDB$RELATION_NAME = '%' ";
1134 queryBuf
.append(sAppend
.replaceAll("%", tableNamePattern
));
1137 if (!columnNamePattern
.isEmpty())
1140 if (columnNamePattern
.match("%"))
1141 sAppend
= "AND relfields.RDB$FIELD_NAME LIKE '%' ";
1143 sAppend
= "AND relfields.RDB$FIELD_NAME = '%' ";
1145 queryBuf
.append(sAppend
.replaceAll("%", columnNamePattern
));
1148 OUString query
= queryBuf
.makeStringAndClear();
1150 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1151 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1152 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1154 ODatabaseMetaDataResultSet::ORows aResults
;
1155 ODatabaseMetaDataResultSet::ORow
aCurrentRow(19);
1157 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1158 aCurrentRow
[1] = new ORowSetValueDecorator(); // Catalog - can be null
1159 aCurrentRow
[2] = new ORowSetValueDecorator(); // Schema - can be null
1160 aCurrentRow
[8] = new ORowSetValueDecorator(); // Unused
1161 aCurrentRow
[10] = new ORowSetValueDecorator(sal_Int32(10)); // Radix: fixed in FB
1162 aCurrentRow
[14] = new ORowSetValueDecorator(); // Unused
1163 aCurrentRow
[15] = new ORowSetValueDecorator(); // Unused
1168 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1170 aCurrentRow
[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(2)));
1172 short aType
= getFBTypeFromBlrType(xRow
->getShort(6));
1173 aCurrentRow
[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType
));
1174 // 6. Typename (SQL_*)
1175 aCurrentRow
[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType
));
1179 sal_Int32 aColumnSize
= 0;
1184 aColumnSize
= xRow
->getShort(7);
1193 aColumnSize
= xRow
->getShort(8);
1204 aCurrentRow
[7] = new ORowSetValueDecorator(aColumnSize
);
1207 // 9. Decimal Digits
1209 aCurrentRow
[9] = new ORowSetValueDecorator(sal_Int32(0));
1212 if (xRow
->getShort(9))
1214 aCurrentRow
[11] = new ORowSetValueDecorator(ColumnValue::NO_NULLS
);
1218 aCurrentRow
[11] = new ORowSetValueDecorator(ColumnValue::NULLABLE
);
1220 // 12. Comments -- may be omitted
1222 OUString aDescription
;
1223 uno::Reference
< XBlob
> xDescriptionBlob
= xRow
->getBlob(3);
1224 if (xDescriptionBlob
.is())
1226 sal_Int32 aBlobLength
= (sal_Int32
) xDescriptionBlob
->length();
1227 aDescription
= OUString(reinterpret_cast<char*>(xDescriptionBlob
->getBytes(0, aBlobLength
).getArray()),
1229 RTL_TEXTENCODING_UTF8
);
1231 aCurrentRow
[12] = new ORowSetValueDecorator(aDescription
);
1233 // 13. Default -- may be omitted.
1235 uno::Reference
< XBlob
> xDefaultValueBlob
= xRow
->getBlob(4);
1236 if (xDefaultValueBlob
.is())
1240 aCurrentRow
[13] = new ORowSetValueDecorator();
1243 // 16. Bytes in Column for char
1244 if (aType
== SQL_TEXT
)
1246 aCurrentRow
[16] = new ORowSetValueDecorator(xRow
->getShort(7));
1248 else if (aType
== SQL_VARYING
)
1250 aCurrentRow
[16] = new ORowSetValueDecorator(sal_Int32(32767));
1254 aCurrentRow
[16] = new ORowSetValueDecorator(sal_Int32(0));
1256 // 17. Index of column
1258 short nColumnNumber
= xRow
->getShort(5);
1259 // Firebird stores column numbers beginning with 0 internally
1260 // SDBC expects column numbering to begin with 1.
1261 aCurrentRow
[17] = new ORowSetValueDecorator(sal_Int32(nColumnNumber
+ 1));
1264 if (xRow
->getShort(9))
1266 aCurrentRow
[18] = new ORowSetValueDecorator(OUString("NO"));
1270 aCurrentRow
[18] = new ORowSetValueDecorator(OUString("YES"));
1273 aResults
.push_back(aCurrentRow
);
1275 ODatabaseMetaDataResultSet
* pResultSet
= new
1276 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumns
);
1277 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1278 pResultSet
->setRows( aResults
);
1283 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTables(
1284 const Any
& /*catalog*/,
1285 const OUString
& /*schemaPattern*/,
1286 const OUString
& tableNamePattern
,
1287 const Sequence
< OUString
>& types
)
1288 throw(SQLException
, RuntimeException
, std::exception
)
1290 SAL_INFO("connectivity.firebird", "getTables() with "
1291 "TableNamePattern: " << tableNamePattern
);
1293 ODatabaseMetaDataResultSet
* pResultSet
= new
1294 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables
);
1295 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1296 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1298 static const char wld
[] = "%";
1299 OUStringBuffer
queryBuf(
1301 "RDB$RELATION_NAME, "
1303 "RDB$RELATION_TYPE, "
1306 "FROM RDB$RELATIONS "
1309 // TODO: GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, SYNONYM
1310 if ((types
.getLength() == 0) || (types
.getLength() == 1 && types
[0].match(wld
)))
1312 // All table types? I.e. includes system tables.
1313 queryBuf
.append("(RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1) ");
1317 queryBuf
.append("( (0 = 1) ");
1318 for (int i
= 0; i
< types
.getLength(); i
++)
1320 if (types
[i
] == "SYSTEM TABLE")
1321 queryBuf
.append("OR (RDB$SYSTEM_FLAG = 1 AND RDB$VIEW_BLR IS NULL) ");
1322 else if (types
[i
] == "TABLE")
1323 queryBuf
.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NULL) ");
1324 else if (types
[i
] == "VIEW")
1325 queryBuf
.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NOT NULL) ");
1327 throw SQLException(); // TODO: implement other types, see above.
1329 queryBuf
.append(") ");
1332 if (!tableNamePattern
.isEmpty())
1335 if (tableNamePattern
.match(wld
))
1336 sAppend
= "AND RDB$RELATION_NAME LIKE '%' ";
1338 sAppend
= "AND RDB$RELATION_NAME = '%' ";
1340 queryBuf
.append(sAppend
.replaceAll(wld
, tableNamePattern
));
1343 queryBuf
.append(" ORDER BY RDB$RELATION_TYPE, RDB$RELATION_NAME");
1345 OUString query
= queryBuf
.makeStringAndClear();
1347 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1348 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1349 ODatabaseMetaDataResultSet::ORows aResults
;
1351 ODatabaseMetaDataResultSet::ORow
aCurrentRow(6);
1352 aCurrentRow
[0] = new ORowSetValueDecorator(); // 0. Unused
1353 aCurrentRow
[1] = new ORowSetValueDecorator(); // 1. Table_Cat Unsupported
1354 aCurrentRow
[2] = new ORowSetValueDecorator(); // 2. Table_Schem Unsupported
1359 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1362 // TODO: check this as the docs are a bit unclear.
1363 sal_Int16 nSystemFlag
= xRow
->getShort(2);
1364 sal_Int16 nTableType
= xRow
->getShort(3);
1365 xRow
->getBlob(5); // We have to retrieve a column to verify it is null.
1366 bool aIsView
= !xRow
->wasNull();
1367 OUString sTableType
;
1369 if (nSystemFlag
== 1)
1371 sTableType
= "SYSTEM TABLE";
1375 sTableType
= "VIEW";
1379 if (nTableType
== 0)
1380 sTableType
= "TABLE";
1383 aCurrentRow
[4] = new ORowSetValueDecorator(sTableType
);
1387 uno::Reference
< XBlob
> xBlob
= xRow
->getBlob(4);
1388 OUString sDescription
;
1392 // TODO: we should actually be using CLOB here instead.
1393 // However we haven't implemented CLOB yet, so use BLOB.
1394 sal_Int32 aBlobLength
= (sal_Int32
) xBlob
->length();
1395 sDescription
= OUString(reinterpret_cast<char*>(xBlob
->getBytes(0, aBlobLength
).getArray()),
1397 RTL_TEXTENCODING_UTF8
);
1400 aCurrentRow
[5] = new ORowSetValueDecorator(sDescription
);
1403 aResults
.push_back(aCurrentRow
);
1406 pResultSet
->setRows( aResults
);
1411 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getProcedureColumns(
1412 const Any
& catalog
, const OUString
& schemaPattern
,
1413 const OUString
& procedureNamePattern
, const OUString
& columnNamePattern
) throw(SQLException
, RuntimeException
, std::exception
)
1415 SAL_WARN("connectivity.firebird", "Not yet implemented");
1417 (void) schemaPattern
;
1418 (void) procedureNamePattern
;
1419 (void) columnNamePattern
;
1420 OSL_FAIL("Not implemented yet!");
1422 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedureColumns
);
1425 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getProcedures(
1426 const Any
& catalog
, const OUString
& schemaPattern
,
1427 const OUString
& procedureNamePattern
) throw(SQLException
, RuntimeException
, std::exception
)
1429 SAL_WARN("connectivity.firebird", "Not yet implemented");
1431 (void) schemaPattern
;
1432 (void) procedureNamePattern
;
1433 OSL_FAIL("Not implemented yet!");
1435 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedures
);
1438 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getVersionColumns(
1439 const Any
& catalog
, const OUString
& schema
, const OUString
& table
) throw(SQLException
, RuntimeException
, std::exception
)
1441 SAL_WARN("connectivity.firebird", "Not yet implemented");
1445 OSL_FAIL("Not implemented yet!");
1447 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eVersionColumns
);
1450 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getExportedKeys(
1451 const Any
& catalog
, const OUString
& schema
, const OUString
& table
) throw(SQLException
, RuntimeException
, std::exception
)
1453 // List the columns in a table which are foreign keys. This is actually
1454 // never used anywhere in the LO codebase currently. Retrieval from firebird
1455 // requires using a 5-table join.
1456 SAL_WARN("connectivity.firebird", "Not yet implemented");
1460 OSL_FAIL("Not implemented yet!");
1462 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eExportedKeys
);
1465 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getImportedKeys(
1466 const Any
& catalog
, const OUString
& schema
, const OUString
& table
) throw(SQLException
, RuntimeException
, std::exception
)
1468 // List the columns in a table (which must be primary key, or possibly just
1469 // unique) that are referred to in other foreign keys. Will have a similar
1470 // 5-table or so join as in getExportedKeys.
1471 SAL_WARN("connectivity.firebird", "Not yet implemented");
1475 OSL_FAIL("Not implemented yet!");
1477 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eImportedKeys
);
1480 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getPrimaryKeys(
1481 const Any
& /*aCatalog*/,
1482 const OUString
& /*sSchema*/,
1483 const OUString
& sTable
)
1484 throw(SQLException
, RuntimeException
, std::exception
)
1486 SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
1487 "Table: " << sTable
);
1489 OUStringBuffer
aQueryBuf("SELECT "
1490 "constr.RDB$RELATION_NAME, " // 1. Table Name
1491 "inds.RDB$FIELD_NAME, " // 2. Column Name
1492 "inds.RDB$FIELD_POSITION, " // 3. Sequence Number
1493 "constr.RDB$CONSTRAINT_NAME " // 4 Constraint name
1494 "FROM RDB$RELATION_CONSTRAINTS constr "
1495 "JOIN RDB$INDEX_SEGMENTS inds "
1496 "on (constr.RDB$INDEX_NAME = inds.RDB$INDEX_NAME) ");
1498 OUString sAppend
= "WHERE constr.RDB$RELATION_NAME = '%' ";
1499 aQueryBuf
.append(sAppend
.replaceAll("%", sTable
));
1501 aQueryBuf
.append("AND constr.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
1502 "ORDER BY inds.RDB$FIELD_NAME");
1504 OUString sQuery
= aQueryBuf
.makeStringAndClear();
1506 uno::Reference
< XStatement
> xStatement
= m_pConnection
->createStatement();
1507 uno::Reference
< XResultSet
> xRs
= xStatement
->executeQuery(sQuery
);
1508 uno::Reference
< XRow
> xRow( xRs
, UNO_QUERY_THROW
);
1510 ODatabaseMetaDataResultSet::ORows aResults
;
1511 ODatabaseMetaDataResultSet::ORow
aCurrentRow(7);
1513 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1514 aCurrentRow
[1] = new ORowSetValueDecorator(); // Catalog - can be null
1515 aCurrentRow
[2] = new ORowSetValueDecorator(); // Schema - can be null
1520 if (xRs
->getRow() == 1) // Table name doesn't change, so only retrieve once
1522 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1525 aCurrentRow
[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(2)));
1526 // 5. KEY_SEQ (which key in the sequence)
1527 aCurrentRow
[5] = new ORowSetValueDecorator(xRow
->getShort(3));
1528 // 6. Primary Key Name
1529 aCurrentRow
[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(4)));
1531 aResults
.push_back(aCurrentRow
);
1533 ODatabaseMetaDataResultSet
* pResultSet
= new
1534 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys
);
1535 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1536 pResultSet
->setRows( aResults
);
1541 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getIndexInfo(
1542 const Any
& /*aCatalog*/,
1543 const OUString
& /*sSchema*/,
1544 const OUString
& sTable
,
1546 sal_Bool bIsApproximate
)
1547 throw(SQLException
, RuntimeException
, std::exception
)
1549 // Apparently this method can also return a "tableIndexStatistic"
1550 // However this is only mentioned in XDatabaseMetaData.idl (whose comments
1551 // are duplicated in the postgresql driver), and is otherwise undocumented.
1552 SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
1553 "Table: " << sTable
);
1555 OUStringBuffer
aQueryBuf("SELECT "
1556 "indices.RDB$RELATION_NAME, " // 1. Table Name
1557 "index_segments.RDB$FIELD_NAME, " // 2. Column Name
1558 "index_segments.RDB$FIELD_POSITION, " // 3. Sequence Number
1559 "indices.RDB$INDEX_NAME, " // 4. Index name
1560 "indices.RDB$UNIQUE_FLAG, " // 5. Unique Flag
1561 "indices.RDB$INDEX_TYPE " // 6. Index Type
1562 "FROM RDB$INDICES indices "
1563 "JOIN RDB$INDEX_SEGMENTS index_segments "
1564 "on (indices.RDB$INDEX_NAME = index_segments.RDB$INDEX_NAME) "
1565 "WHERE indices.RDB$RELATION_NAME = '" + sTable
+ "' "
1566 "AND (indices.RDB$SYSTEM_FLAG = 0) ");
1567 // Not sure whether we should exclude system indices, but otoh. we never
1568 // actually deal with system tables (system indices only apply to system
1569 // tables) within the GUI.
1571 // Only filter if true (according to the docs), i.e.:
1572 // If false we return all indices, if true we return only unique indices
1574 aQueryBuf
.append("AND (indices.RDB$UNIQUE_FLAG = 1) ");
1576 // TODO: what is bIsApproximate?
1577 (void) bIsApproximate
;
1579 OUString sQuery
= aQueryBuf
.makeStringAndClear();
1581 uno::Reference
< XStatement
> xStatement
= m_pConnection
->createStatement();
1582 uno::Reference
< XResultSet
> xRs
= xStatement
->executeQuery(sQuery
);
1583 uno::Reference
< XRow
> xRow( xRs
, UNO_QUERY_THROW
);
1585 ODatabaseMetaDataResultSet::ORows aResults
;
1586 ODatabaseMetaDataResultSet::ORow
aCurrentRow(14);
1588 aCurrentRow
[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
1589 aCurrentRow
[1] = new ORowSetValueDecorator(); // Catalog - can be null
1590 aCurrentRow
[2] = new ORowSetValueDecorator(); // Schema - can be null
1591 aCurrentRow
[5] = new ORowSetValueDecorator(); // Index Catalog -- can be null
1592 // According to wikipedia firebird uses clustered indices.
1593 // The documentation does not specifically seem to specify this.
1594 aCurrentRow
[7] = new ORowSetValueDecorator(IndexType::CLUSTERED
); // 7. INDEX TYPE
1595 aCurrentRow
[13] = new ORowSetValueDecorator(); // Filter Condition -- can be null
1600 if (xRs
->getRow() == 1) // Table name doesn't change, so only retrieve once
1602 aCurrentRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1605 // 4. NON_UNIQUE -- i.e. specifically negate here.
1606 aCurrentRow
[4] = new ORowSetValueDecorator(!xRow
->getBoolean(5));
1608 aCurrentRow
[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(4)));
1610 // 8. ORDINAL POSITION
1611 aCurrentRow
[8] = new ORowSetValueDecorator(xRow
->getShort(3));
1613 aCurrentRow
[9] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(2)));
1614 // 10. ASC(ending)/DESC(ending)
1615 if (xRow
->getShort(6) == 1)
1616 aCurrentRow
[10] = new ORowSetValueDecorator(OUString("D"));
1618 aCurrentRow
[10] = new ORowSetValueDecorator(OUString("A"));
1619 // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
1621 aCurrentRow
[11] = new ORowSetValueDecorator((sal_Int32
)0); // TODO: determine how to do this
1623 aCurrentRow
[12] = new ORowSetValueDecorator((sal_Int32
)0); // TODO: determine how to do this
1625 aResults
.push_back(aCurrentRow
);
1627 ODatabaseMetaDataResultSet
* pResultSet
= new
1628 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys
);
1629 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1630 pResultSet
->setRows( aResults
);
1635 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getBestRowIdentifier(
1636 const Any
& catalog
, const OUString
& schema
, const OUString
& table
, sal_Int32 scope
,
1637 sal_Bool nullable
) throw(SQLException
, RuntimeException
, std::exception
)
1644 OSL_FAIL("Not implemented yet!");
1646 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eBestRowIdentifier
);
1649 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getTablePrivileges(
1650 const Any
& /*aCatalog*/,
1651 const OUString
& /*sSchemaPattern*/,
1652 const OUString
& sTableNamePattern
)
1653 throw(SQLException
, RuntimeException
, std::exception
)
1655 SAL_INFO("connectivity.firebird", "getTablePrivileges() with "
1656 "TableNamePattern: " << sTableNamePattern
);
1658 ODatabaseMetaDataResultSet
* pResultSet
= new
1659 ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTablePrivileges
);
1660 uno::Reference
< XResultSet
> xResultSet
= pResultSet
;
1661 uno::Reference
< XStatement
> statement
= m_pConnection
->createStatement();
1663 // TODO: column specific privileges are included, we may need
1664 // to have WHERE RDB$FIELD_NAME = NULL or similar.
1665 static const char wld
[] = "%";
1666 OUStringBuffer
queryBuf(
1668 "priv.RDB$RELATION_NAME, " // 1
1669 "priv.RDB$GRANTOR," // 2
1670 "priv.RDB$USER, " // 3 Grantee
1671 "priv.RDB$PRIVILEGE, " // 4
1672 "priv.RDB$GRANT_OPTION " // 5 is Grantable
1673 "FROM RDB$USER_PRIVILEGES priv ");
1675 if (!sTableNamePattern
.isEmpty())
1678 if (sTableNamePattern
.match(wld
))
1679 sAppend
= "WHERE priv.RDB$RELATION_NAME LIKE '%' ";
1681 sAppend
= "WHERE priv.RDB$RELATION_NAME = '%' ";
1683 queryBuf
.append(sAppend
.replaceAll(wld
, sTableNamePattern
));
1685 queryBuf
.append(" ORDER BY priv.RDB$RELATION_TYPE, "
1686 "priv.RDB$RELATION_NAME, "
1687 "priv.RDB$PRIVILEGE");
1689 OUString query
= queryBuf
.makeStringAndClear();
1691 uno::Reference
< XResultSet
> rs
= statement
->executeQuery(query
.getStr());
1692 uno::Reference
< XRow
> xRow( rs
, UNO_QUERY_THROW
);
1693 ODatabaseMetaDataResultSet::ORows aResults
;
1695 ODatabaseMetaDataResultSet::ORow
aRow(8);
1696 aRow
[0] = new ORowSetValueDecorator(); // Unused
1697 aRow
[1] = new ORowSetValueDecorator(); // TABLE_CAT unsupported
1698 aRow
[2] = new ORowSetValueDecorator(); // TABLE_SCHEM unussported.
1703 aRow
[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow
->getString(1)));
1704 aRow
[4] = new ORowSetValueDecorator(xRow
->getString(2)); // 4. GRANTOR
1705 aRow
[5] = new ORowSetValueDecorator(xRow
->getString(3)); // 5. GRANTEE
1706 aRow
[6] = new ORowSetValueDecorator(xRow
->getString(4)); // 6. Privilege
1707 aRow
[7] = new ORowSetValueDecorator(xRow
->getBoolean(5)); // 7. Is Grantable
1709 aResults
.push_back(aRow
);
1712 pResultSet
->setRows( aResults
);
1717 uno::Reference
< XResultSet
> SAL_CALL
ODatabaseMetaData::getCrossReference(
1718 const Any
& primaryCatalog
, const OUString
& primarySchema
,
1719 const OUString
& primaryTable
, const Any
& foreignCatalog
,
1720 const OUString
& foreignSchema
, const OUString
& foreignTable
) throw(SQLException
, RuntimeException
, std::exception
)
1722 (void) primaryCatalog
;
1723 (void) primarySchema
;
1724 (void) primaryTable
;
1725 (void) foreignCatalog
;
1726 (void) foreignSchema
;
1727 (void) foreignTable
;
1728 OSL_FAIL("Not implemented yet!");
1730 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCrossReference
);
1733 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
)
1736 (void) schemaPattern
;
1737 (void) typeNamePattern
;
1739 OSL_FAIL("Not implemented yet!");
1741 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs
);
1747 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */