update emoji autocorrect entries from po-files
[LibreOffice.git] / connectivity / source / drivers / firebird / DatabaseMetaData.cxx
blob03bdae0e996edae3aab9611784046140c9b15929
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;
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)
57 return OUString();
60 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCatalogNameLength() throw(SQLException, RuntimeException, std::exception)
62 return -1;
65 OUString SAL_CALL ODatabaseMetaData::getCatalogTerm() throw(SQLException, RuntimeException, std::exception)
67 return OUString();
70 sal_Bool SAL_CALL ODatabaseMetaData::isCatalogAtStart() throw(SQLException, RuntimeException, std::exception)
72 return sal_False;
75 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInTableDefinitions() throw(SQLException, RuntimeException, std::exception)
77 return sal_False;
80 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInIndexDefinitions() throw(SQLException, RuntimeException, std::exception)
82 return sal_False;
85 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInDataManipulation( ) throw(SQLException, RuntimeException, std::exception)
87 return sal_False;
90 uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs() throw(SQLException, RuntimeException, std::exception)
92 OSL_FAIL("Not implemented yet!");
93 // TODO implement
94 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCatalogs);
97 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInProcedureCalls() throw(SQLException, RuntimeException, std::exception)
99 return sal_False;
102 sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions() throw(SQLException, RuntimeException, std::exception)
104 return sal_False;
107 //----- Schema Info -- UNSUPPORTED --------------------------------------------
108 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInProcedureCalls()
109 throw(SQLException, RuntimeException, std::exception)
111 return sal_False;
114 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
115 throw(SQLException, RuntimeException, std::exception)
117 return sal_False;
120 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInDataManipulation()
121 throw(SQLException, RuntimeException, std::exception)
123 return sal_False;
126 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInIndexDefinitions()
127 throw(SQLException, RuntimeException, std::exception)
129 return sal_False;
132 sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInTableDefinitions()
133 throw(SQLException, RuntimeException, std::exception)
135 return sal_False;
138 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxSchemaNameLength()
139 throw(SQLException, RuntimeException, std::exception)
141 return -1;
144 OUString SAL_CALL ODatabaseMetaData::getSchemaTerm()
145 throw(SQLException, RuntimeException, std::exception)
147 return OUString();
150 uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas()
151 throw(SQLException, RuntimeException, std::exception)
153 OSL_FAIL("Not implemented yet!");
154 // TODO implement
155 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eSchemas);
158 //----- Max Sizes/Lengths -----------------------------------------------------
159 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxBinaryLiteralLength() throw(SQLException, RuntimeException, std::exception)
161 return 32767;
164 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxRowSize() throw(SQLException, RuntimeException, std::exception)
166 return 32767;
169 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCharLiteralLength() throw(SQLException, RuntimeException, std::exception)
171 return 32767;
174 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnNameLength() throw(SQLException, RuntimeException, std::exception)
176 return 31;
179 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInIndex() throw(SQLException, RuntimeException, std::exception)
181 // TODO: No idea.
182 // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
183 return 16;
186 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCursorNameLength() throw(SQLException, RuntimeException, std::exception)
188 return 32;
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/
200 return 32767;
203 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatementLength() throw(SQLException, RuntimeException, std::exception)
205 return 32767;
208 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTableNameLength() throw(SQLException, RuntimeException, std::exception)
210 return 31;
213 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTablesInSelect( ) throw(SQLException, RuntimeException, std::exception)
215 sal_Int32 nValue = 0; // 0 means no limit
216 return nValue;
220 sal_Bool SAL_CALL ODatabaseMetaData::doesMaxRowSizeIncludeBlobs( ) throw(SQLException, RuntimeException, std::exception)
222 return sal_False;
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)
230 OUString aVal('"');
231 return aVal;
234 sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers( ) throw(SQLException, RuntimeException, std::exception)
236 return sal_True;
239 sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
240 throw(SQLException, RuntimeException, std::exception)
242 return sal_False;
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.
251 return sal_True;
254 sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
255 throw(SQLException, RuntimeException, std::exception)
257 return sal_False;
260 // ---- Unquoted Identifiers -------------------------------------------------
261 // All unquoted identifiers are stored upper case.
262 sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseIdentifiers()
263 throw(SQLException, RuntimeException, std::exception)
265 return sal_False;
268 sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseIdentifiers()
269 throw(SQLException, RuntimeException, std::exception)
271 return sal_False;
274 sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseIdentifiers()
275 throw(SQLException, RuntimeException, std::exception)
277 return sal_False;
280 sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseIdentifiers()
281 throw(SQLException, RuntimeException, std::exception)
283 return sal_True;
286 // ---- SQL Feature Support ---------------------------------------------------
287 sal_Bool SAL_CALL ODatabaseMetaData::supportsCoreSQLGrammar()
288 throw(SQLException, RuntimeException, std::exception)
290 return sal_True;
293 sal_Bool SAL_CALL ODatabaseMetaData::supportsMinimumSQLGrammar()
294 throw(SQLException, RuntimeException, std::exception)
296 return sal_True;
299 sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithAddColumn()
300 throw(SQLException, RuntimeException, std::exception)
302 return sal_True;
305 sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithDropColumn()
306 throw(SQLException, RuntimeException, std::exception)
308 return sal_True;
311 sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedDelete()
312 throw(SQLException, RuntimeException, std::exception)
314 return sal_True;
317 sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedUpdate()
318 throw(SQLException, RuntimeException, std::exception)
320 return sal_True;
323 sal_Bool SAL_CALL ODatabaseMetaData::supportsOuterJoins()
324 throw(SQLException, RuntimeException, std::exception)
326 return sal_True;
329 sal_Bool SAL_CALL ODatabaseMetaData::supportsSelectForUpdate()
330 throw(SQLException, RuntimeException, std::exception)
332 return sal_True;
335 sal_Bool SAL_CALL ODatabaseMetaData::allTablesAreSelectable()
336 throw(SQLException, RuntimeException, std::exception)
338 // TODO: true if embedded, but unsure about remote server
339 return sal_True;
342 sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert(sal_Int32 fromType,
343 sal_Int32 toType)
344 throw(SQLException, RuntimeException, std::exception)
346 (void) fromType;
347 (void) toType;
348 return sal_False;
351 sal_Bool SAL_CALL ODatabaseMetaData::supportsTypeConversion()
352 throw(SQLException, RuntimeException, std::exception)
354 return sal_False;
357 sal_Bool SAL_CALL ODatabaseMetaData::supportsColumnAliasing()
358 throw(SQLException, RuntimeException, std::exception)
360 return sal_True;
363 sal_Bool SAL_CALL ODatabaseMetaData::supportsTableCorrelationNames()
364 throw(SQLException, RuntimeException, std::exception)
366 return sal_True;
369 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxIndexLength( ) throw(SQLException, RuntimeException, std::exception)
371 sal_Int32 nValue = 0; // 0 means no limit
372 return nValue;
375 sal_Bool SAL_CALL ODatabaseMetaData::supportsNonNullableColumns( ) throw(SQLException, RuntimeException, std::exception)
377 return sal_True;
380 OUString SAL_CALL ODatabaseMetaData::getExtraNameCharacters( ) throw(SQLException, RuntimeException, std::exception)
382 OUString aVal;
383 return aVal;
386 sal_Bool SAL_CALL ODatabaseMetaData::supportsDifferentTableCorrelationNames( ) throw(SQLException, RuntimeException, std::exception)
388 return sal_False;
390 // ---- Data definition stuff -------------------------------------------------
391 sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
392 throw(SQLException, RuntimeException, std::exception)
394 return sal_False;
397 sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
398 throw(SQLException, RuntimeException, std::exception)
400 return sal_True;
403 sal_Bool SAL_CALL ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
404 throw(SQLException, RuntimeException, std::exception)
406 return sal_True;
409 sal_Bool SAL_CALL ODatabaseMetaData::
410 supportsDataDefinitionAndDataManipulationTransactions()
411 throw(SQLException, RuntimeException, std::exception)
413 return sal_False;
415 //----- Transaction Support --------------------------------------------------
416 sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactions()
417 throw(SQLException, RuntimeException, std::exception)
419 return sal_True;
422 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
423 throw(SQLException, RuntimeException, std::exception)
425 return sal_False;
428 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
429 throw(SQLException, RuntimeException, std::exception)
431 return sal_False;
434 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
435 throw(SQLException, RuntimeException, std::exception)
437 return sal_False;
440 sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
441 throw(SQLException, RuntimeException, std::exception)
443 return sal_False;
446 sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions()
447 throw(SQLException, RuntimeException, std::exception)
449 return sal_True;
452 sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel(
453 sal_Int32 aLevel)
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)
471 return sal_False;
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)
481 return sal_False;
484 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatements( ) throw(SQLException, RuntimeException, std::exception)
486 sal_Int32 nValue = 0; // 0 means no limit
487 return nValue;
490 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxProcedureNameLength( ) throw(SQLException, RuntimeException, std::exception)
492 sal_Int32 nValue = 31; // TODO: confirm
493 return nValue;
496 sal_Bool SAL_CALL ODatabaseMetaData::allProceduresAreCallable( ) throw(SQLException, RuntimeException, std::exception)
498 return sal_False;
501 sal_Bool SAL_CALL ODatabaseMetaData::supportsStoredProcedures( ) throw(SQLException, RuntimeException, std::exception)
503 return sal_True;
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)
518 return sal_False;
521 sal_Bool SAL_CALL ODatabaseMetaData::nullPlusNonNullIsNull( ) throw(SQLException, RuntimeException, std::exception)
523 return sal_False;
526 sal_Bool SAL_CALL ODatabaseMetaData::supportsExpressionsInOrderBy( ) throw(SQLException, RuntimeException, std::exception)
528 return sal_False;
531 sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupBy( ) throw(SQLException, RuntimeException, std::exception)
533 return sal_True;
536 sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByBeyondSelect( ) throw(SQLException, RuntimeException, std::exception)
538 // Unsure
539 return sal_True;
542 sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated( ) throw(SQLException, RuntimeException, std::exception)
544 // Unsure
545 return sal_False;
549 sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets( ) throw(SQLException, RuntimeException, std::exception)
551 return sal_False;
554 sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause( ) throw(SQLException, RuntimeException, std::exception)
556 return sal_False;
559 sal_Bool SAL_CALL ODatabaseMetaData::supportsOrderByUnrelated( ) throw(SQLException, RuntimeException, std::exception)
561 return sal_False;
564 sal_Bool SAL_CALL ODatabaseMetaData::supportsUnion( ) throw(SQLException, RuntimeException, std::exception)
566 return sal_True;
569 sal_Bool SAL_CALL ODatabaseMetaData::supportsUnionAll( ) throw(SQLException, RuntimeException, std::exception)
571 return sal_True;
574 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtEnd( ) throw(SQLException, RuntimeException, std::exception)
576 return sal_False;
579 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtStart( ) throw(SQLException, RuntimeException, std::exception)
581 return sal_False;
584 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedHigh( ) throw(SQLException, RuntimeException, std::exception)
586 return sal_False;
589 sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedLow( ) throw(SQLException, RuntimeException, std::exception)
591 return sal_False;
594 sal_Bool SAL_CALL ODatabaseMetaData::supportsCorrelatedSubqueries( ) throw(SQLException, RuntimeException, std::exception)
596 return sal_False;
599 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInComparisons( ) throw(SQLException, RuntimeException, std::exception)
601 return sal_False;
604 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInExists( ) throw(SQLException, RuntimeException, std::exception)
606 return sal_False;
609 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInIns( ) throw(SQLException, RuntimeException, std::exception)
611 return sal_False;
614 sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInQuantifieds( ) throw(SQLException, RuntimeException, std::exception)
616 return sal_False;
619 sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92IntermediateSQL( ) throw(SQLException, RuntimeException, std::exception)
621 return sal_False;
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)
631 OUString aValue;
632 return aValue;
635 OUString SAL_CALL ODatabaseMetaData::getDriverName( ) throw(SQLException, RuntimeException, std::exception)
637 OUString aValue;
638 return aValue;
641 OUString SAL_CALL ODatabaseMetaData::getDriverVersion() throw(SQLException, RuntimeException, std::exception)
643 OUString aValue;
644 return aValue;
647 OUString SAL_CALL ODatabaseMetaData::getDatabaseProductVersion( ) throw(SQLException, RuntimeException, std::exception)
649 OUString aValue;
650 return aValue;
653 OUString SAL_CALL ODatabaseMetaData::getDatabaseProductName( ) throw(SQLException, RuntimeException, std::exception)
655 OUString aValue;
656 return aValue;
659 OUString SAL_CALL ODatabaseMetaData::getProcedureTerm( ) throw(SQLException, RuntimeException, std::exception)
661 OUString aValue;
662 return aValue;
665 sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMajorVersion( ) throw(RuntimeException, std::exception)
667 return 1;
670 sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMinorVersion( ) throw(RuntimeException, std::exception)
672 return 0;
675 OUString SAL_CALL ODatabaseMetaData::getSQLKeywords( ) throw(SQLException, RuntimeException, std::exception)
677 OUString aValue;
678 return aValue;
681 OUString SAL_CALL ODatabaseMetaData::getSearchStringEscape( ) throw(SQLException, RuntimeException, std::exception)
683 OUString aValue;
684 return aValue;
687 OUString SAL_CALL ODatabaseMetaData::getStringFunctions( ) throw(SQLException, RuntimeException, std::exception)
689 return OUString();
692 OUString SAL_CALL ODatabaseMetaData::getTimeDateFunctions( ) throw(SQLException, RuntimeException, std::exception)
694 return OUString();
697 OUString SAL_CALL ODatabaseMetaData::getSystemFunctions( ) throw(SQLException, RuntimeException, std::exception)
699 return OUString();
702 OUString SAL_CALL ODatabaseMetaData::getNumericFunctions( ) throw(SQLException, RuntimeException, std::exception)
704 return OUString();
707 sal_Bool SAL_CALL ODatabaseMetaData::supportsExtendedSQLGrammar( ) throw(SQLException, RuntimeException, std::exception)
709 return sal_False;
712 sal_Bool SAL_CALL ODatabaseMetaData::supportsFullOuterJoins( ) throw(SQLException, RuntimeException, std::exception)
714 return sal_False;
717 sal_Bool SAL_CALL ODatabaseMetaData::supportsLimitedOuterJoins( ) throw(SQLException, RuntimeException, std::exception)
719 return sal_False;
722 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInGroupBy( ) throw(SQLException, RuntimeException, std::exception)
724 sal_Int32 nValue = 0; // 0 means no limit
725 return nValue;
728 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInOrderBy( ) throw(SQLException, RuntimeException, std::exception)
730 sal_Int32 nValue = 0; // 0 means no limit
731 return nValue;
734 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInSelect( ) throw(SQLException, RuntimeException, std::exception)
736 sal_Int32 nValue = 0; // 0 means no limit
737 return nValue;
740 sal_Int32 SAL_CALL ODatabaseMetaData::getMaxUserNameLength( ) throw(SQLException, RuntimeException, std::exception)
742 return 31;
745 sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetType(sal_Int32 setType)
746 throw(SQLException, RuntimeException, std::exception)
748 switch (setType)
750 case ResultSetType::FORWARD_ONLY:
751 return sal_True;
752 default:
753 return sal_False;
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)
764 return sal_True;
765 else
766 return sal_False;
769 sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
771 (void) setType;
772 return sal_False;
775 sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
777 (void) setType;
778 return sal_False;
781 sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
783 (void) setType;
784 return sal_False;
787 sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
789 (void) setType;
790 return sal_False;
793 sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
795 (void) setType;
796 return sal_False;
799 sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
801 (void) setType;
802 return sal_False;
805 sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
807 (void) setType;
808 return sal_False;
811 sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
813 (void) setType;
814 return sal_False;
817 sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
819 (void) setType;
820 return sal_False;
823 sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates()
824 throw(SQLException, RuntimeException, std::exception)
826 // No batch support in firebird
827 return sal_False;
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!");
844 // TODO implement
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;
860 if(aResults.empty())
862 ODatabaseMetaDataResultSet::ORow aRow(19);
864 // Common data
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
881 // SQL_TEXT
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);
893 // SQL_VARYING
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
914 // SQL_SHORT
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);
919 // SQL_LONG
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);
924 // SQL_INT64
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
937 // SQL_FLOAT
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);
944 // SQL_DOUBLE
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);
951 // // SQL_D_FLOAT
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
960 // SQL_TIMESTAMP
961 // TODO: precision?
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);
973 // SQL_TYPE_TIME
974 // TODO: precision?
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);
986 // SQL_TYPE_DATE
987 // TODO: precision?
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);
999 // SQL_BLOB
1000 // TODO: precision?
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);
1012 // TODO: complete
1013 // case SQL_ARRAY:
1014 // case SQL_NULL:
1015 // case SQL_QUAD: // Is a "Blob ID" according to the docs
1017 pResultSet->setRows(aResults);
1018 return xResultSet;
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 "
1029 "Table: " << sTable
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(
1039 "SELECT "
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())
1054 OUString sAppend;
1055 if (sColumnNamePattern.match(wld))
1056 sAppend = "AND priv.RDB$FIELD_NAME LIKE '%' ";
1057 else
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
1077 while( rs->next() )
1079 // 3. TABLE_NAME
1080 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1081 // 4. COLUMN_NAME
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 );
1093 return xResultSet;
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
1119 // (see Table.cxx)
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) "
1124 "WHERE (1 = 1) ");
1126 if (!tableNamePattern.isEmpty())
1128 OUString sAppend;
1129 if (tableNamePattern.match("%"))
1130 sAppend = "AND relfields.RDB$RELATION_NAME LIKE '%' ";
1131 else
1132 sAppend = "AND relfields.RDB$RELATION_NAME = '%' ";
1134 queryBuf.append(sAppend.replaceAll("%", tableNamePattern));
1137 if (!columnNamePattern.isEmpty())
1139 OUString sAppend;
1140 if (columnNamePattern.match("%"))
1141 sAppend = "AND relfields.RDB$FIELD_NAME LIKE '%' ";
1142 else
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
1165 while( rs->next() )
1167 // 3. TABLE_NAME
1168 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1169 // 4. Column Name
1170 aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
1171 // 5. Datatype
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));
1177 // 7. Column Sizes
1179 sal_Int32 aColumnSize = 0;
1180 switch (aType)
1182 case SQL_TEXT:
1183 case SQL_VARYING:
1184 aColumnSize = xRow->getShort(7);
1185 break;
1186 case SQL_SHORT:
1187 case SQL_LONG:
1188 case SQL_FLOAT:
1189 case SQL_DOUBLE:
1190 case SQL_D_FLOAT:
1191 case SQL_INT64:
1192 case SQL_QUAD:
1193 aColumnSize = xRow->getShort(8);
1194 break;
1195 case SQL_TIMESTAMP:
1196 case SQL_BLOB:
1197 case SQL_ARRAY:
1198 case SQL_TYPE_TIME:
1199 case SQL_TYPE_DATE:
1200 case SQL_NULL:
1201 // TODO: implement.
1202 break;
1204 aCurrentRow[7] = new ORowSetValueDecorator(aColumnSize);
1207 // 9. Decimal Digits
1208 // TODO: implement
1209 aCurrentRow[9] = new ORowSetValueDecorator(sal_Int32(0));
1211 // 11. Nullable
1212 if (xRow->getShort(9))
1214 aCurrentRow[11] = new ORowSetValueDecorator(ColumnValue::NO_NULLS);
1216 else
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()),
1228 aBlobLength,
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())
1238 // TODO: Implement
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));
1252 else
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));
1263 // 18. Is nullable
1264 if (xRow->getShort(9))
1266 aCurrentRow[18] = new ORowSetValueDecorator(OUString("NO"));
1268 else
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 );
1280 return xResultSet;
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(
1300 "SELECT "
1301 "RDB$RELATION_NAME, "
1302 "RDB$SYSTEM_FLAG, "
1303 "RDB$RELATION_TYPE, "
1304 "RDB$DESCRIPTION, "
1305 "RDB$VIEW_BLR "
1306 "FROM RDB$RELATIONS "
1307 "WHERE ");
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) ");
1315 else
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) ");
1326 else
1327 throw SQLException(); // TODO: implement other types, see above.
1329 queryBuf.append(") ");
1332 if (!tableNamePattern.isEmpty())
1334 OUString sAppend;
1335 if (tableNamePattern.match(wld))
1336 sAppend = "AND RDB$RELATION_NAME LIKE '%' ";
1337 else
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
1356 while( rs->next() )
1358 // 3. TABLE_NAME
1359 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1360 // 4. TABLE_TYPE
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";
1373 else if (aIsView)
1375 sTableType = "VIEW";
1377 else
1379 if (nTableType == 0)
1380 sTableType = "TABLE";
1383 aCurrentRow[4] = new ORowSetValueDecorator(sTableType);
1385 // 5. REMARKS
1387 uno::Reference< XBlob > xBlob = xRow->getBlob(4);
1388 OUString sDescription;
1390 if (xBlob.is())
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()),
1396 aBlobLength,
1397 RTL_TEXTENCODING_UTF8);
1400 aCurrentRow[5] = new ORowSetValueDecorator(sDescription);
1403 aResults.push_back(aCurrentRow);
1406 pResultSet->setRows( aResults );
1408 return xResultSet;
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");
1416 (void) catalog;
1417 (void) schemaPattern;
1418 (void) procedureNamePattern;
1419 (void) columnNamePattern;
1420 OSL_FAIL("Not implemented yet!");
1421 // TODO implement
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");
1430 (void) catalog;
1431 (void) schemaPattern;
1432 (void) procedureNamePattern;
1433 OSL_FAIL("Not implemented yet!");
1434 // TODO implement
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");
1442 (void) catalog;
1443 (void) schema;
1444 (void) table;
1445 OSL_FAIL("Not implemented yet!");
1446 // TODO implement
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");
1457 (void) catalog;
1458 (void) schema;
1459 (void) table;
1460 OSL_FAIL("Not implemented yet!");
1461 // TODO implement
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");
1472 (void) catalog;
1473 (void) schema;
1474 (void) table;
1475 OSL_FAIL("Not implemented yet!");
1476 // TODO implement
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
1517 while(xRs->next())
1519 // 3. Table Name
1520 if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
1522 aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
1524 // 4. Column Name
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 );
1538 return xResultSet;
1541 uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo(
1542 const Any& /*aCatalog*/,
1543 const OUString& /*sSchema*/,
1544 const OUString& sTable,
1545 sal_Bool bIsUnique,
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
1573 if (bIsUnique)
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
1597 while(xRs->next())
1599 // 3. Table Name
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));
1607 // 6. INDEX NAME
1608 aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
1610 // 8. ORDINAL POSITION
1611 aCurrentRow[8] = new ORowSetValueDecorator(xRow->getShort(3));
1612 // 9. COLUMN NAME
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"));
1617 else
1618 aCurrentRow[10] = new ORowSetValueDecorator(OUString("A"));
1619 // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
1620 // 11. CARDINALITY
1621 aCurrentRow[11] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
1622 // 12. PAGES
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 );
1632 return xResultSet;
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)
1639 (void) catalog;
1640 (void) schema;
1641 (void) table;
1642 (void) scope;
1643 (void) nullable;
1644 OSL_FAIL("Not implemented yet!");
1645 // TODO implement
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(
1667 "SELECT "
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())
1677 OUString sAppend;
1678 if (sTableNamePattern.match(wld))
1679 sAppend = "WHERE priv.RDB$RELATION_NAME LIKE '%' ";
1680 else
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.
1700 while( rs->next() )
1702 // 3. TABLE_NAME
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 );
1714 return xResultSet;
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!");
1729 // TODO implement
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)
1735 (void) catalog;
1736 (void) schemaPattern;
1737 (void) typeNamePattern;
1738 (void) types;
1739 OSL_FAIL("Not implemented yet!");
1740 // TODO implement
1741 return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs);
1747 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */