Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / connectivity / source / drivers / firebird / DatabaseMetaData.cxx
blobbff558ce3e501c16424154c6d2fb01bd4678f204
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
21 #include "Util.hxx"
23 #include <ibase.h>
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)
59 return OUString();
62 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCatalogNameLength() throw(SQLException, RuntimeException, std::exception)
64 return -1;
67 OUString SAL_CALL ODatabaseMetaData::getCatalogTerm() throw(SQLException, RuntimeException, std::exception)
69 return OUString();
72 sal_Bool SAL_CALL ODatabaseMetaData::isCatalogAtStart() throw(SQLException, RuntimeException, std::exception)
74 return sal_False;
77 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInTableDefinitions() throw(SQLException, RuntimeException, std::exception)
79 return sal_False;
82 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInIndexDefinitions() throw(SQLException, RuntimeException, std::exception)
84 return sal_False;
87 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInDataManipulation( ) throw(SQLException, RuntimeException, std::exception)
89 return sal_False;
92 uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs() throw(SQLException, RuntimeException, std::exception)
94 OSL_FAIL("Not implemented yet!");
95 // TODO implement
96 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCatalogs);
99 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInProcedureCalls() throw(SQLException, RuntimeException, std::exception)
101 return sal_False;
104 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions() throw(SQLException, RuntimeException, std::exception)
106 return sal_False;
109 //----- Schema Info -- UNSUPPORTED --------------------------------------------
110 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInProcedureCalls()
111 throw(SQLException, RuntimeException, std::exception)
113 return sal_False;
116 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
117 throw(SQLException, RuntimeException, std::exception)
119 return sal_False;
122 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInDataManipulation()
123 throw(SQLException, RuntimeException, std::exception)
125 return sal_False;
128 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInIndexDefinitions()
129 throw(SQLException, RuntimeException, std::exception)
131 return sal_False;
134 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInTableDefinitions()
135 throw(SQLException, RuntimeException, std::exception)
137 return sal_False;
140 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxSchemaNameLength()
141 throw(SQLException, RuntimeException, std::exception)
143 return -1;
146 OUString SAL_CALL ODatabaseMetaData::getSchemaTerm()
147 throw(SQLException, RuntimeException, std::exception)
149 return OUString();
152 uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas()
153 throw(SQLException, RuntimeException, std::exception)
155 OSL_FAIL("Not implemented yet!");
156 // TODO implement
157 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eSchemas);
160 //----- Max Sizes/Lengths -----------------------------------------------------
161 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxBinaryLiteralLength() throw(SQLException, RuntimeException, std::exception)
163 return 32767;
166 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxRowSize() throw(SQLException, RuntimeException, std::exception)
168 return 32767;
171 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCharLiteralLength() throw(SQLException, RuntimeException, std::exception)
173 return 32767;
176 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnNameLength() throw(SQLException, RuntimeException, std::exception)
178 return 31;
181 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInIndex() throw(SQLException, RuntimeException, std::exception)
183 // TODO: No idea.
184 // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
185 return 16;
188 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCursorNameLength() throw(SQLException, RuntimeException, std::exception)
190 return 32;
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/
202 return 32767;
205 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatementLength() throw(SQLException, RuntimeException, std::exception)
207 return 32767;
210 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTableNameLength() throw(SQLException, RuntimeException, std::exception)
212 return 31;
215 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTablesInSelect( ) throw(SQLException, RuntimeException, std::exception)
217 sal_Int32 nValue = 0; // 0 means no limit
218 return nValue;
222 sal_Bool SAL_CALL ODatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw(SQLException, RuntimeException, std::exception)
224 return sal_False;
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)
232 OUString aVal('"');
233 return aVal;
236 sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw(SQLException, RuntimeException, std::exception)
238 return sal_True;
241 sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
242 throw(SQLException, RuntimeException, std::exception)
244 return sal_False;
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.
253 return sal_True;
256 sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
257 throw(SQLException, RuntimeException, std::exception)
259 return sal_False;
262 // ---- Unquoted Identifiers -------------------------------------------------
263 // All unquoted identifers are stored upper case.
264 sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseIdentifiers()
265 throw(SQLException, RuntimeException, std::exception)
267 return sal_False;
270 sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseIdentifiers()
271 throw(SQLException, RuntimeException, std::exception)
273 return sal_False;
276 sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseIdentifiers()
277 throw(SQLException, RuntimeException, std::exception)
279 return sal_False;
282 sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseIdentifiers()
283 throw(SQLException, RuntimeException, std::exception)
285 return sal_True;
288 // ---- SQL Feature Support ---------------------------------------------------
289 sal_Bool SAL_CALL ODatabaseMetaData::supportsCoreSQLGrammar()
290 throw(SQLException, RuntimeException, std::exception)
292 return sal_True;
295 sal_Bool SAL_CALL ODatabaseMetaData::supportsMinimumSQLGrammar()
296 throw(SQLException, RuntimeException, std::exception)
298 return sal_True;
301 sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithAddColumn()
302 throw(SQLException, RuntimeException, std::exception)
304 return sal_True;
307 sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithDropColumn()
308 throw(SQLException, RuntimeException, std::exception)
310 return sal_True;
313 sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedDelete()
314 throw(SQLException, RuntimeException, std::exception)
316 return sal_True;
319 sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedUpdate()
320 throw(SQLException, RuntimeException, std::exception)
322 return sal_True;
325 sal_Bool SAL_CALL ODatabaseMetaData::supportsOuterJoins()
326 throw(SQLException, RuntimeException, std::exception)
328 return sal_True;
331 sal_Bool SAL_CALL ODatabaseMetaData::supportsSelectForUpdate()
332 throw(SQLException, RuntimeException, std::exception)
334 return sal_True;
337 sal_Bool SAL_CALL ODatabaseMetaData::allTablesAreSelectable()
338 throw(SQLException, RuntimeException, std::exception)
340 // TODO: true if embedded, but unsure about remote server
341 return sal_True;
344 sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert(sal_Int32 fromType,
345 sal_Int32 toType)
346 throw(SQLException, RuntimeException, std::exception)
348 (void) fromType;
349 (void) toType;
350 return sal_False;
353 sal_Bool SAL_CALL ODatabaseMetaData::supportsTypeConversion()
354 throw(SQLException, RuntimeException, std::exception)
356 return sal_False;
359 sal_Bool SAL_CALL ODatabaseMetaData::supportsColumnAliasing()
360 throw(SQLException, RuntimeException, std::exception)
362 return sal_True;
365 sal_Bool SAL_CALL ODatabaseMetaData::supportsTableCorrelationNames()
366 throw(SQLException, RuntimeException, std::exception)
368 return sal_True;
371 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxIndexLength( ) throw(SQLException, RuntimeException, std::exception)
373 sal_Int32 nValue = 0; // 0 means no limit
374 return nValue;
377 sal_Bool SAL_CALL ODatabaseMetaData::supportsNonNullableColumns( ) throw(SQLException, RuntimeException, std::exception)
379 return sal_True;
382 OUString SAL_CALL ODatabaseMetaData::getExtraNameCharacters( ) throw(SQLException, RuntimeException, std::exception)
384 OUString aVal;
385 return aVal;
388 sal_Bool SAL_CALL ODatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw(SQLException, RuntimeException, std::exception)
390 return sal_False;
392 // ---- Data definition stuff -------------------------------------------------
393 sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
394 throw(SQLException, RuntimeException, std::exception)
396 return sal_False;
399 sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
400 throw(SQLException, RuntimeException, std::exception)
402 return sal_True;
405 sal_Bool SAL_CALL ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
406 throw(SQLException, RuntimeException, std::exception)
408 return sal_True;
411 sal_Bool SAL_CALL ODatabaseMetaData::
412 supportsDataDefinitionAndDataManipulationTransactions()
413 throw(SQLException, RuntimeException, std::exception)
415 return sal_False;
417 //----- Transaction Support --------------------------------------------------
418 sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactions()
419 throw(SQLException, RuntimeException, std::exception)
421 return sal_True;
424 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
425 throw(SQLException, RuntimeException, std::exception)
427 return sal_False;
430 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
431 throw(SQLException, RuntimeException, std::exception)
433 return sal_False;
436 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
437 throw(SQLException, RuntimeException, std::exception)
439 return sal_False;
442 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
443 throw(SQLException, RuntimeException, std::exception)
445 return sal_False;
448 sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions()
449 throw(SQLException, RuntimeException, std::exception)
451 return sal_True;
454 sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel(
455 sal_Int32 aLevel)
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)
473 return sal_False;
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)
483 return sal_False;
486 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatements( ) throw(SQLException, RuntimeException, std::exception)
488 sal_Int32 nValue = 0; // 0 means no limit
489 return nValue;
492 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxProcedureNameLength( ) throw(SQLException, RuntimeException, std::exception)
494 sal_Int32 nValue = 31; // TODO: confirm
495 return nValue;
498 sal_Bool SAL_CALL ODatabaseMetaData::allProceduresAreCallable( ) throw(SQLException, RuntimeException, std::exception)
500 return sal_False;
503 sal_Bool SAL_CALL ODatabaseMetaData::supportsStoredProcedures( ) throw(SQLException, RuntimeException, std::exception)
505 return sal_True;
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)
520 return sal_False;
523 sal_Bool SAL_CALL ODatabaseMetaData::nullPlusNonNullIsNull( ) throw(SQLException, RuntimeException, std::exception)
525 return sal_False;
528 sal_Bool SAL_CALL ODatabaseMetaData::supportsExpressionsInOrderBy( ) throw(SQLException, RuntimeException, std::exception)
530 return sal_False;
533 sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupBy( ) throw(SQLException, RuntimeException, std::exception)
535 return sal_True;
538 sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByBeyondSelect( ) throw(SQLException, RuntimeException, std::exception)
540 // Unsure
541 return sal_True;
544 sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated( ) throw(SQLException, RuntimeException, std::exception)
546 // Unsure
547 return sal_False;
551 sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets( ) throw(SQLException, RuntimeException, std::exception)
553 return sal_False;
556 sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause( ) throw(SQLException, RuntimeException, std::exception)
558 return sal_False;
561 sal_Bool SAL_CALL ODatabaseMetaData::supportsOrderByUnrelated( ) throw(SQLException, RuntimeException, std::exception)
563 return sal_False;
566 sal_Bool SAL_CALL ODatabaseMetaData::supportsUnion( ) throw(SQLException, RuntimeException, std::exception)
568 return sal_True;
571 sal_Bool SAL_CALL ODatabaseMetaData::supportsUnionAll( ) throw(SQLException, RuntimeException, std::exception)
573 return sal_True;
576 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtEnd( ) throw(SQLException, RuntimeException, std::exception)
578 return sal_False;
581 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtStart( ) throw(SQLException, RuntimeException, std::exception)
583 return sal_False;
586 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedHigh( ) throw(SQLException, RuntimeException, std::exception)
588 return sal_False;
591 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedLow( ) throw(SQLException, RuntimeException, std::exception)
593 return sal_False;
596 sal_Bool SAL_CALL ODatabaseMetaData::supportsCorrelatedSubqueries( ) throw(SQLException, RuntimeException, std::exception)
598 return sal_False;
601 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInComparisons( ) throw(SQLException, RuntimeException, std::exception)
603 return sal_False;
606 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInExists( ) throw(SQLException, RuntimeException, std::exception)
608 return sal_False;
611 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInIns( ) throw(SQLException, RuntimeException, std::exception)
613 return sal_False;
616 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw(SQLException, RuntimeException, std::exception)
618 return sal_False;
621 sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92IntermediateSQL( ) throw(SQLException, RuntimeException, std::exception)
623 return sal_False;
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)
633 OUString aValue;
634 return aValue;
637 OUString SAL_CALL ODatabaseMetaData::getDriverName( ) throw(SQLException, RuntimeException, std::exception)
639 OUString aValue;
640 return aValue;
643 OUString SAL_CALL ODatabaseMetaData::getDriverVersion() throw(SQLException, RuntimeException, std::exception)
645 OUString aValue;
646 return aValue;
649 OUString SAL_CALL ODatabaseMetaData::getDatabaseProductVersion( ) throw(SQLException, RuntimeException, std::exception)
651 OUString aValue;
652 return aValue;
655 OUString SAL_CALL ODatabaseMetaData::getDatabaseProductName( ) throw(SQLException, RuntimeException, std::exception)
657 OUString aValue;
658 return aValue;
661 OUString SAL_CALL ODatabaseMetaData::getProcedureTerm( ) throw(SQLException, RuntimeException, std::exception)
663 OUString aValue;
664 return aValue;
667 sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMajorVersion( ) throw(RuntimeException, std::exception)
669 return 1;
672 sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMinorVersion( ) throw(RuntimeException, std::exception)
674 return 0;
677 OUString SAL_CALL ODatabaseMetaData::getSQLKeywords( ) throw(SQLException, RuntimeException, std::exception)
679 OUString aValue;
680 return aValue;
683 OUString SAL_CALL ODatabaseMetaData::getSearchStringEscape( ) throw(SQLException, RuntimeException, std::exception)
685 OUString aValue;
686 return aValue;
689 OUString SAL_CALL ODatabaseMetaData::getStringFunctions( ) throw(SQLException, RuntimeException, std::exception)
691 return OUString();
694 OUString SAL_CALL ODatabaseMetaData::getTimeDateFunctions( ) throw(SQLException, RuntimeException, std::exception)
696 return OUString();
699 OUString SAL_CALL ODatabaseMetaData::getSystemFunctions( ) throw(SQLException, RuntimeException, std::exception)
701 return OUString();
704 OUString SAL_CALL ODatabaseMetaData::getNumericFunctions( ) throw(SQLException, RuntimeException, std::exception)
706 return OUString();
709 sal_Bool SAL_CALL ODatabaseMetaData::supportsExtendedSQLGrammar( ) throw(SQLException, RuntimeException, std::exception)
711 return sal_False;
714 sal_Bool SAL_CALL ODatabaseMetaData::supportsFullOuterJoins( ) throw(SQLException, RuntimeException, std::exception)
716 return sal_False;
719 sal_Bool SAL_CALL ODatabaseMetaData::supportsLimitedOuterJoins( ) throw(SQLException, RuntimeException, std::exception)
721 return sal_False;
724 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInGroupBy( ) throw(SQLException, RuntimeException, std::exception)
726 sal_Int32 nValue = 0; // 0 means no limit
727 return nValue;
730 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInOrderBy( ) throw(SQLException, RuntimeException, std::exception)
732 sal_Int32 nValue = 0; // 0 means no limit
733 return nValue;
736 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInSelect( ) throw(SQLException, RuntimeException, std::exception)
738 sal_Int32 nValue = 0; // 0 means no limit
739 return nValue;
742 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxUserNameLength( ) throw(SQLException, RuntimeException, std::exception)
744 return 31;
747 sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetType(sal_Int32 setType)
748 throw(SQLException, RuntimeException, std::exception)
750 switch (setType)
752 case ResultSetType::FORWARD_ONLY:
753 return sal_True;
754 default:
755 return sal_False;
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)
766 return sal_True;
767 else
768 return sal_False;
771 sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
773 (void) setType;
774 return sal_False;
777 sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
779 (void) setType;
780 return sal_False;
783 sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
785 (void) setType;
786 return sal_False;
789 sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
791 (void) setType;
792 return sal_False;
795 sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
797 (void) setType;
798 return sal_False;
801 sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
803 (void) setType;
804 return sal_False;
807 sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
809 (void) setType;
810 return sal_False;
813 sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
815 (void) setType;
816 return sal_False;
819 sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
821 (void) setType;
822 return sal_False;
825 sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates()
826 throw(SQLException, RuntimeException, std::exception)
828 // No batch support in firebird
829 return sal_False;
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!");
846 // TODO implement
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;
862 if(aResults.empty())
864 ODatabaseMetaDataResultSet::ORow aRow(19);
866 // Common data
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
883 // SQL_TEXT
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);
895 // SQL_VARYING
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
916 // SQL_SHORT
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);
921 // SQL_LONG
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);
926 // SQL_INT64
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
939 // SQL_FLOAT
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);
946 // SQL_DOUBLE
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);
953 // // SQL_D_FLOAT
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
962 // SQL_TIMESTAMP
963 // TODO: precision?
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);
975 // SQL_TYPE_TIME
976 // TODO: precision?
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);
988 // SQL_TYPE_DATE
989 // TODO: precision?
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);
1001 // SQL_BLOB
1002 // TODO: precision?
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);
1014 // TODO: complete
1015 // case SQL_ARRAY:
1016 // case SQL_NULL:
1017 // case SQL_QUAD: // Is a "Blob ID" according to the docs
1019 pResultSet->setRows(aResults);
1020 return xResultSet;
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 "
1031 "Table: " << sTable
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(
1041 "SELECT "
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())
1056 OUString sAppend;
1057 if (sColumnNamePattern.match(wld))
1058 sAppend = "AND priv.RDB$FIELD_NAME LIKE '%' ";
1059 else
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
1079 while( rs->next() )
1081 // 3. TABLE_NAME
1082 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1083 // 4. COLUMN_NAME
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 );
1095 return xResultSet;
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
1121 // (see Table.cxx)
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) "
1126 "WHERE (1 = 1) ");
1128 if (!tableNamePattern.isEmpty())
1130 OUString sAppend;
1131 if (tableNamePattern.match("%"))
1132 sAppend = "AND relfields.RDB$RELATION_NAME LIKE '%' ";
1133 else
1134 sAppend = "AND relfields.RDB$RELATION_NAME = '%' ";
1136 queryBuf.append(sAppend.replaceAll("%", tableNamePattern));
1139 if (!columnNamePattern.isEmpty())
1141 OUString sAppend;
1142 if (columnNamePattern.match("%"))
1143 sAppend = "AND relfields.RDB$FIELD_NAME LIKE '%' ";
1144 else
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
1167 while( rs->next() )
1169 // 3. TABLE_NAME
1170 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1171 // 4. Column Name
1172 aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
1173 // 5. Datatype
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));
1179 // 7. Column Sizes
1181 sal_Int32 aColumnSize = 0;
1182 switch (aType)
1184 case SQL_TEXT:
1185 case SQL_VARYING:
1186 aColumnSize = xRow->getShort(7);
1187 break;
1188 case SQL_SHORT:
1189 case SQL_LONG:
1190 case SQL_FLOAT:
1191 case SQL_DOUBLE:
1192 case SQL_D_FLOAT:
1193 case SQL_INT64:
1194 case SQL_QUAD:
1195 aColumnSize = xRow->getShort(8);
1196 break;
1197 case SQL_TIMESTAMP:
1198 case SQL_BLOB:
1199 case SQL_ARRAY:
1200 case SQL_TYPE_TIME:
1201 case SQL_TYPE_DATE:
1202 case SQL_NULL:
1203 // TODO: implement.
1204 break;
1206 aCurrentRow[7] = new ORowSetValueDecorator(aColumnSize);
1209 // 9. Decimal Digits
1210 // TODO: implement
1211 aCurrentRow[9] = new ORowSetValueDecorator(sal_Int32(0));
1213 // 11. Nullable
1214 if (xRow->getShort(9))
1216 aCurrentRow[11] = new ORowSetValueDecorator(ColumnValue::NO_NULLS);
1218 else
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(),
1230 aBlobLength,
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())
1240 // TODO: Implement
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));
1254 else
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));
1265 // 18. Is nullable
1266 if (xRow->getShort(9))
1268 aCurrentRow[18] = new ORowSetValueDecorator(OUString("NO"));
1270 else
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 );
1282 return xResultSet;
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(
1302 "SELECT "
1303 "RDB$RELATION_NAME, "
1304 "RDB$SYSTEM_FLAG, "
1305 "RDB$RELATION_TYPE, "
1306 "RDB$DESCRIPTION, "
1307 "RDB$VIEW_BLR "
1308 "FROM RDB$RELATIONS "
1309 "WHERE ");
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) ");
1317 else
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) ");
1328 else
1329 throw SQLException(); // TODO: implement other types, see above.
1331 queryBuf.append(") ");
1334 if (!tableNamePattern.isEmpty())
1336 OUString sAppend;
1337 if (tableNamePattern.match(wld))
1338 sAppend = "AND RDB$RELATION_NAME LIKE '%' ";
1339 else
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
1358 while( rs->next() )
1360 // 3. TABLE_NAME
1361 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1362 // 4. TABLE_TYPE
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";
1375 else if (aIsView)
1377 sTableType = "VIEW";
1379 else
1381 if (nTableType == 0)
1382 sTableType = "TABLE";
1385 aCurrentRow[4] = new ORowSetValueDecorator(sTableType);
1387 // 5. REMARKS
1389 uno::Reference< XBlob > xBlob = xRow->getBlob(4);
1390 OUString sDescription;
1392 if (xBlob.is())
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(),
1398 aBlobLength,
1399 RTL_TEXTENCODING_UTF8);
1402 aCurrentRow[5] = new ORowSetValueDecorator(sDescription);
1405 aResults.push_back(aCurrentRow);
1408 pResultSet->setRows( aResults );
1410 return xResultSet;
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");
1418 (void) catalog;
1419 (void) schemaPattern;
1420 (void) procedureNamePattern;
1421 (void) columnNamePattern;
1422 OSL_FAIL("Not implemented yet!");
1423 // TODO implement
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");
1432 (void) catalog;
1433 (void) schemaPattern;
1434 (void) procedureNamePattern;
1435 OSL_FAIL("Not implemented yet!");
1436 // TODO implement
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");
1444 (void) catalog;
1445 (void) schema;
1446 (void) table;
1447 OSL_FAIL("Not implemented yet!");
1448 // TODO implement
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");
1459 (void) catalog;
1460 (void) schema;
1461 (void) table;
1462 OSL_FAIL("Not implemented yet!");
1463 // TODO implement
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");
1474 (void) catalog;
1475 (void) schema;
1476 (void) table;
1477 OSL_FAIL("Not implemented yet!");
1478 // TODO implement
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
1519 while(xRs->next())
1521 // 3. Table Name
1522 if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
1524 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1526 // 4. Column Name
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 );
1540 return xResultSet;
1543 uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo(
1544 const Any& /*aCatalog*/,
1545 const OUString& /*sSchema*/,
1546 const OUString& sTable,
1547 sal_Bool bIsUnique,
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
1575 if (bIsUnique)
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
1599 while(xRs->next())
1601 // 3. Table Name
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));
1609 // 6. INDEX NAME
1610 aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
1612 // 8. ORDINAL POSITION
1613 aCurrentRow[8] = new ORowSetValueDecorator(xRow->getShort(3));
1614 // 9. COLUMN NAME
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"));
1619 else
1620 aCurrentRow[10] = new ORowSetValueDecorator(OUString("A"));
1621 // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
1622 // 11. CARDINALITY
1623 aCurrentRow[11] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
1624 // 12. PAGES
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 );
1634 return xResultSet;
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)
1641 (void) catalog;
1642 (void) schema;
1643 (void) table;
1644 (void) scope;
1645 (void) nullable;
1646 OSL_FAIL("Not implemented yet!");
1647 // TODO implement
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(
1669 "SELECT "
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())
1679 OUString sAppend;
1680 if (sTableNamePattern.match(wld))
1681 sAppend = "WHERE priv.RDB$RELATION_NAME LIKE '%' ";
1682 else
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.
1702 while( rs->next() )
1704 // 3. TABLE_NAME
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 );
1716 return xResultSet;
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!");
1731 // TODO implement
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)
1737 (void) catalog;
1738 (void) schemaPattern;
1739 (void) typeNamePattern;
1740 (void) types;
1741 OSL_FAIL("Not implemented yet!");
1742 // TODO implement
1743 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs);
1749 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */