LCOV - code coverage report
Current view: top level - connectivity/source/drivers/firebird - DatabaseMetaData.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 282 674 41.8 %
Date: 2014-11-03 Functions: 19 152 12.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "DatabaseMetaData.hxx"
      21             : #include "Util.hxx"
      22             : 
      23             : #include <ibase.h>
      24             : #include <rtl/ustrbuf.hxx>
      25             : #include <FDatabaseMetaDataResultSet.hxx>
      26             : 
      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>
      35             : 
      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;
      42             : 
      43           8 : ODatabaseMetaData::ODatabaseMetaData(Connection* _pCon)
      44           8 : : m_pConnection(_pCon)
      45             : {
      46             :     SAL_WARN_IF(!m_pConnection.is(), "connectivity.firebird",
      47             :             "ODatabaseMetaData::ODatabaseMetaData: No connection set!");
      48           8 : }
      49             : 
      50          16 : ODatabaseMetaData::~ODatabaseMetaData()
      51             : {
      52          16 : }
      53             : 
      54             : //----- Catalog Info -- UNSUPPORTED -------------------------------------------
      55          12 : OUString SAL_CALL ODatabaseMetaData::getCatalogSeparator() throw(SQLException, RuntimeException, std::exception)
      56             : {
      57          12 :     return OUString();
      58             : }
      59             : 
      60           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCatalogNameLength() throw(SQLException, RuntimeException, std::exception)
      61             : {
      62           0 :     return -1;
      63             : }
      64             : 
      65           0 : OUString SAL_CALL ODatabaseMetaData::getCatalogTerm() throw(SQLException, RuntimeException, std::exception)
      66             : {
      67           0 :     return OUString();
      68             : }
      69             : 
      70           0 : sal_Bool SAL_CALL ODatabaseMetaData::isCatalogAtStart() throw(SQLException, RuntimeException, std::exception)
      71             : {
      72           0 :     return sal_False;
      73             : }
      74             : 
      75           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInTableDefinitions() throw(SQLException, RuntimeException, std::exception)
      76             : {
      77           0 :     return sal_False;
      78             : }
      79             : 
      80           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInIndexDefinitions() throw(SQLException, RuntimeException, std::exception)
      81             : {
      82           0 :     return sal_False;
      83             : }
      84             : 
      85          16 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInDataManipulation(  ) throw(SQLException, RuntimeException, std::exception)
      86             : {
      87          16 :     return sal_False;
      88             : }
      89             : 
      90           0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs() throw(SQLException, RuntimeException, std::exception)
      91             : {
      92             :     OSL_FAIL("Not implemented yet!");
      93             :     // TODO implement
      94           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCatalogs);
      95             : }
      96             : 
      97           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInProcedureCalls() throw(SQLException, RuntimeException, std::exception)
      98             : {
      99           0 :     return sal_False;
     100             : }
     101             : 
     102           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCatalogsInPrivilegeDefinitions() throw(SQLException, RuntimeException, std::exception)
     103             : {
     104           0 :     return sal_False;
     105             : }
     106             : 
     107             : //----- Schema Info -- UNSUPPORTED --------------------------------------------
     108           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInProcedureCalls()
     109             :     throw(SQLException, RuntimeException, std::exception)
     110             : {
     111           0 :     return sal_False;
     112             : }
     113             : 
     114           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInPrivilegeDefinitions()
     115             :     throw(SQLException, RuntimeException, std::exception)
     116             : {
     117           0 :     return sal_False;
     118             : }
     119             : 
     120          16 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInDataManipulation()
     121             :     throw(SQLException, RuntimeException, std::exception)
     122             : {
     123          16 :     return sal_False;
     124             : }
     125             : 
     126           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInIndexDefinitions()
     127             :     throw(SQLException, RuntimeException, std::exception)
     128             : {
     129           0 :     return sal_False;
     130             : }
     131             : 
     132           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSchemasInTableDefinitions()
     133             :     throw(SQLException, RuntimeException, std::exception)
     134             : {
     135           0 :     return sal_False;
     136             : }
     137             : 
     138           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxSchemaNameLength()
     139             :     throw(SQLException, RuntimeException, std::exception)
     140             : {
     141           0 :     return -1;
     142             : }
     143             : 
     144           0 : OUString SAL_CALL ODatabaseMetaData::getSchemaTerm()
     145             :     throw(SQLException, RuntimeException, std::exception)
     146             : {
     147           0 :     return OUString();
     148             : }
     149             : 
     150           0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas()
     151             :     throw(SQLException, RuntimeException, std::exception)
     152             : {
     153             :     OSL_FAIL("Not implemented yet!");
     154             :     // TODO implement
     155           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eSchemas);
     156             : }
     157             : 
     158             : //----- Max Sizes/Lengths -----------------------------------------------------
     159           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxBinaryLiteralLength() throw(SQLException, RuntimeException, std::exception)
     160             : {
     161           0 :     return 32767;
     162             : }
     163             : 
     164           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxRowSize() throw(SQLException, RuntimeException, std::exception)
     165             : {
     166           0 :     return 32767;
     167             : }
     168             : 
     169           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCharLiteralLength() throw(SQLException, RuntimeException, std::exception)
     170             : {
     171           0 :     return 32767;
     172             : }
     173             : 
     174           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnNameLength() throw(SQLException, RuntimeException, std::exception)
     175             : {
     176           0 :     return 31;
     177             : }
     178             : 
     179           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInIndex() throw(SQLException, RuntimeException, std::exception)
     180             : {
     181             :     // TODO: No idea.
     182             :     // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
     183           0 :     return 16;
     184             : }
     185             : 
     186           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxCursorNameLength() throw(SQLException, RuntimeException, std::exception)
     187             : {
     188           0 :     return 32;
     189             : }
     190             : 
     191           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxConnections() throw(SQLException, RuntimeException, std::exception)
     192             : {
     193           0 :     return 100; // Arbitrary
     194             : }
     195             : 
     196           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInTable() throw(SQLException, RuntimeException, std::exception)
     197             : {
     198             :     // May however be smaller.
     199             :     // See: http://www.firebirdsql.org/en/firebird-technical-specifications/
     200           0 :     return 32767;
     201             : }
     202             : 
     203           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatementLength() throw(SQLException, RuntimeException, std::exception)
     204             : {
     205           0 :     return 32767;
     206             : }
     207             : 
     208           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTableNameLength() throw(SQLException, RuntimeException, std::exception)
     209             : {
     210           0 :     return 31;
     211             : }
     212             : 
     213          10 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxTablesInSelect(  ) throw(SQLException, RuntimeException, std::exception)
     214             : {
     215          10 :     sal_Int32 nValue = 0; // 0 means no limit
     216          10 :     return nValue;
     217             : }
     218             : 
     219             : 
     220           0 : sal_Bool SAL_CALL ODatabaseMetaData::doesMaxRowSizeIncludeBlobs(  ) throw(SQLException, RuntimeException, std::exception)
     221             : {
     222           0 :     return sal_False;
     223             : }
     224             : 
     225             : // ---- Identifiers -----------------------------------------------------------
     226             : // Only quoted identifiers are case sensitive, unquoted are case insensitive
     227          14 : OUString SAL_CALL ODatabaseMetaData::getIdentifierQuoteString()
     228             :     throw(SQLException, RuntimeException, std::exception)
     229             : {
     230          14 :     OUString aVal('"');
     231          14 :     return aVal;
     232             : }
     233             : 
     234          14 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseQuotedIdentifiers(  ) throw(SQLException, RuntimeException, std::exception)
     235             : {
     236          14 :     return sal_True;
     237             : }
     238             : 
     239           0 : sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseQuotedIdentifiers()
     240             :     throw(SQLException, RuntimeException, std::exception)
     241             : {
     242           0 :     return sal_False;
     243             : }
     244             : 
     245           0 : sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseQuotedIdentifiers()
     246             :     throw(SQLException, RuntimeException, std::exception)
     247             : {
     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           0 :     return sal_True;
     252             : }
     253             : 
     254           0 : sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseQuotedIdentifiers()
     255             :     throw(SQLException, RuntimeException, std::exception)
     256             : {
     257           0 :     return sal_False;
     258             : }
     259             : 
     260             : // ---- Unquoted Identifiers -------------------------------------------------
     261             : // All unquoted identifers are stored upper case.
     262           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMixedCaseIdentifiers()
     263             :     throw(SQLException, RuntimeException, std::exception)
     264             : {
     265           0 :     return sal_False;
     266             : }
     267             : 
     268           0 : sal_Bool SAL_CALL ODatabaseMetaData::storesLowerCaseIdentifiers()
     269             :     throw(SQLException, RuntimeException, std::exception)
     270             : {
     271           0 :     return sal_False;
     272             : }
     273             : 
     274           0 : sal_Bool SAL_CALL ODatabaseMetaData::storesMixedCaseIdentifiers()
     275             :     throw(SQLException, RuntimeException, std::exception)
     276             : {
     277           0 :     return sal_False;
     278             : }
     279             : 
     280           0 : sal_Bool SAL_CALL ODatabaseMetaData::storesUpperCaseIdentifiers()
     281             :     throw(SQLException, RuntimeException, std::exception)
     282             : {
     283           0 :     return sal_True;
     284             : }
     285             : 
     286             : // ---- SQL Feature Support ---------------------------------------------------
     287           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCoreSQLGrammar()
     288             :     throw(SQLException, RuntimeException, std::exception)
     289             : {
     290           0 :     return sal_True;
     291             : }
     292             : 
     293           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMinimumSQLGrammar()
     294             :     throw(SQLException, RuntimeException, std::exception)
     295             : {
     296           0 :     return sal_True;
     297             : }
     298             : 
     299           2 : sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithAddColumn()
     300             :     throw(SQLException, RuntimeException, std::exception)
     301             : {
     302           2 :     return sal_True;
     303             : }
     304             : 
     305           2 : sal_Bool SAL_CALL ODatabaseMetaData::supportsAlterTableWithDropColumn()
     306             :     throw(SQLException, RuntimeException, std::exception)
     307             : {
     308           2 :     return sal_True;
     309             : }
     310             : 
     311           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedDelete()
     312             :     throw(SQLException, RuntimeException, std::exception)
     313             : {
     314           0 :     return sal_True;
     315             : }
     316             : 
     317           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsPositionedUpdate()
     318             :     throw(SQLException, RuntimeException, std::exception)
     319             : {
     320           0 :     return sal_True;
     321             : }
     322             : 
     323           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOuterJoins()
     324             :     throw(SQLException, RuntimeException, std::exception)
     325             : {
     326           0 :     return sal_True;
     327             : }
     328             : 
     329           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSelectForUpdate()
     330             :     throw(SQLException, RuntimeException, std::exception)
     331             : {
     332           0 :     return sal_True;
     333             : }
     334             : 
     335           0 : sal_Bool SAL_CALL ODatabaseMetaData::allTablesAreSelectable()
     336             :     throw(SQLException, RuntimeException, std::exception)
     337             : {
     338             :     // TODO: true if embedded, but unsure about remote server
     339           0 :     return sal_True;
     340             : }
     341             : 
     342           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsConvert(sal_Int32 fromType,
     343             :                                                      sal_Int32 toType)
     344             :     throw(SQLException, RuntimeException, std::exception)
     345             : {
     346             :     (void) fromType;
     347             :     (void) toType;
     348           0 :     return sal_False;
     349             : }
     350             : 
     351           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTypeConversion()
     352             :     throw(SQLException, RuntimeException, std::exception)
     353             : {
     354           0 :     return sal_False;
     355             : }
     356             : 
     357           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsColumnAliasing()
     358             :     throw(SQLException, RuntimeException, std::exception)
     359             : {
     360           0 :     return sal_True;
     361             : }
     362             : 
     363           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTableCorrelationNames()
     364             :     throw(SQLException, RuntimeException, std::exception)
     365             : {
     366           0 :     return sal_True;
     367             : }
     368             : 
     369           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxIndexLength(  ) throw(SQLException, RuntimeException, std::exception)
     370             : {
     371           0 :     sal_Int32 nValue = 0; // 0 means no limit
     372           0 :     return nValue;
     373             : }
     374             : 
     375           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsNonNullableColumns(  ) throw(SQLException, RuntimeException, std::exception)
     376             : {
     377           0 :     return sal_True;
     378             : }
     379             : 
     380           0 : OUString SAL_CALL ODatabaseMetaData::getExtraNameCharacters(  ) throw(SQLException, RuntimeException, std::exception)
     381             : {
     382           0 :     OUString aVal;
     383           0 :     return aVal;
     384             : }
     385             : 
     386           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsDifferentTableCorrelationNames(  ) throw(SQLException, RuntimeException, std::exception)
     387             : {
     388           0 :     return sal_False;
     389             : }
     390             : // ---- Data definition stuff -------------------------------------------------
     391           0 : sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionIgnoredInTransactions()
     392             :     throw(SQLException, RuntimeException, std::exception)
     393             : {
     394           0 :     return sal_False;
     395             : }
     396             : 
     397           0 : sal_Bool SAL_CALL ODatabaseMetaData::dataDefinitionCausesTransactionCommit()
     398             :     throw(SQLException, RuntimeException, std::exception)
     399             : {
     400           0 :     return sal_True;
     401             : }
     402             : 
     403           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsDataManipulationTransactionsOnly()
     404             :     throw(SQLException, RuntimeException, std::exception)
     405             : {
     406           0 :     return sal_True;
     407             : }
     408             : 
     409           0 : sal_Bool SAL_CALL ODatabaseMetaData::
     410             :         supportsDataDefinitionAndDataManipulationTransactions()
     411             :     throw(SQLException, RuntimeException, std::exception)
     412             : {
     413           0 :     return sal_False;
     414             : }
     415             : //----- Transaction Support --------------------------------------------------
     416           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactions()
     417             :     throw(SQLException, RuntimeException, std::exception)
     418             : {
     419           0 :     return sal_True;
     420             : }
     421             : 
     422           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossRollback()
     423             :     throw(SQLException, RuntimeException, std::exception)
     424             : {
     425           0 :     return sal_False;
     426             : }
     427             : 
     428           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenStatementsAcrossCommit()
     429             :     throw(SQLException, RuntimeException, std::exception)
     430             : {
     431           0 :     return sal_False;
     432             : }
     433             : 
     434           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossCommit()
     435             :     throw(SQLException, RuntimeException, std::exception)
     436             : {
     437           0 :     return sal_False;
     438             : }
     439             : 
     440           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOpenCursorsAcrossRollback()
     441             :     throw(SQLException, RuntimeException, std::exception)
     442             : {
     443           0 :     return sal_False;
     444             : }
     445             : 
     446           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleTransactions()
     447             :     throw(SQLException, RuntimeException, std::exception)
     448             : {
     449           0 :     return sal_True;
     450             : }
     451             : 
     452           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsTransactionIsolationLevel(
     453             :         sal_Int32 aLevel)
     454             :     throw(SQLException, RuntimeException, std::exception)
     455             : {
     456             :     return  aLevel == TransactionIsolation::READ_UNCOMMITTED
     457           0 :            || aLevel == TransactionIsolation::READ_COMMITTED
     458           0 :            || aLevel == TransactionIsolation::REPEATABLE_READ
     459           0 :            || aLevel == TransactionIsolation::SERIALIZABLE;
     460             : }
     461             : 
     462           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getDefaultTransactionIsolation()
     463             :     throw(SQLException, RuntimeException, std::exception)
     464             : {
     465           0 :     return TransactionIsolation::REPEATABLE_READ;
     466             : }
     467             : 
     468             : 
     469           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92FullSQL(  ) throw(SQLException, RuntimeException, std::exception)
     470             : {
     471           0 :     return sal_False;
     472             : }
     473             : 
     474           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92EntryLevelSQL(  ) throw(SQLException, RuntimeException, std::exception)
     475             : {
     476           0 :     return sal_True; // should be supported at least
     477             : }
     478             : 
     479           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsIntegrityEnhancementFacility(  ) throw(SQLException, RuntimeException, std::exception)
     480             : {
     481           0 :     return sal_False;
     482             : }
     483             : 
     484           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxStatements(  ) throw(SQLException, RuntimeException, std::exception)
     485             : {
     486           0 :     sal_Int32 nValue = 0; // 0 means no limit
     487           0 :     return nValue;
     488             : }
     489             : 
     490           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxProcedureNameLength(  ) throw(SQLException, RuntimeException, std::exception)
     491             : {
     492           0 :     sal_Int32 nValue = 31; // TODO: confirm
     493           0 :     return nValue;
     494             : }
     495             : 
     496           0 : sal_Bool SAL_CALL ODatabaseMetaData::allProceduresAreCallable(  ) throw(SQLException, RuntimeException, std::exception)
     497             : {
     498           0 :     return sal_False;
     499             : }
     500             : 
     501           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsStoredProcedures(  ) throw(SQLException, RuntimeException, std::exception)
     502             : {
     503           0 :     return sal_True;
     504             : }
     505             : 
     506           0 : sal_Bool SAL_CALL ODatabaseMetaData::isReadOnly(  ) throw(SQLException, RuntimeException, std::exception)
     507             : {
     508           0 :     return m_pConnection->isReadOnly();
     509             : }
     510             : 
     511           0 : sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFiles(  ) throw(SQLException, RuntimeException, std::exception)
     512             : {
     513           0 :     return m_pConnection->isEmbedded();
     514             : }
     515             : 
     516           0 : sal_Bool SAL_CALL ODatabaseMetaData::usesLocalFilePerTable(  ) throw(SQLException, RuntimeException, std::exception)
     517             : {
     518           0 :     return sal_False;
     519             : }
     520             : 
     521           0 : sal_Bool SAL_CALL ODatabaseMetaData::nullPlusNonNullIsNull(  ) throw(SQLException, RuntimeException, std::exception)
     522             : {
     523           0 :     return sal_False;
     524             : }
     525             : 
     526           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsExpressionsInOrderBy(  ) throw(SQLException, RuntimeException, std::exception)
     527             : {
     528           0 :     return sal_False;
     529             : }
     530             : 
     531           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupBy(  ) throw(SQLException, RuntimeException, std::exception)
     532             : {
     533           0 :     return sal_True;
     534             : }
     535             : 
     536           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByBeyondSelect(  ) throw(SQLException, RuntimeException, std::exception)
     537             : {
     538             :     // Unsure
     539           0 :     return sal_True;
     540             : }
     541             : 
     542           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsGroupByUnrelated(  ) throw(SQLException, RuntimeException, std::exception)
     543             : {
     544             :     // Unsure
     545           0 :     return sal_False;
     546             : }
     547             : 
     548             : 
     549           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsMultipleResultSets(  ) throw(SQLException, RuntimeException, std::exception)
     550             : {
     551           0 :     return sal_False;
     552             : }
     553             : 
     554           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsLikeEscapeClause(  ) throw(SQLException, RuntimeException, std::exception)
     555             : {
     556           0 :     return sal_False;
     557             : }
     558             : 
     559           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsOrderByUnrelated(  ) throw(SQLException, RuntimeException, std::exception)
     560             : {
     561           0 :     return sal_False;
     562             : }
     563             : 
     564           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsUnion(  ) throw(SQLException, RuntimeException, std::exception)
     565             : {
     566           0 :     return sal_True;
     567             : }
     568             : 
     569           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsUnionAll(  ) throw(SQLException, RuntimeException, std::exception)
     570             : {
     571           0 :     return sal_True;
     572             : }
     573             : 
     574           0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtEnd(  ) throw(SQLException, RuntimeException, std::exception)
     575             : {
     576           0 :     return sal_False;
     577             : }
     578             : 
     579           0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedAtStart(  ) throw(SQLException, RuntimeException, std::exception)
     580             : {
     581           0 :     return sal_False;
     582             : }
     583             : 
     584           0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedHigh(  ) throw(SQLException, RuntimeException, std::exception)
     585             : {
     586           0 :     return sal_False;
     587             : }
     588             : 
     589           0 : sal_Bool SAL_CALL ODatabaseMetaData::nullsAreSortedLow(  ) throw(SQLException, RuntimeException, std::exception)
     590             : {
     591           0 :     return sal_False;
     592             : }
     593             : 
     594           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsCorrelatedSubqueries(  ) throw(SQLException, RuntimeException, std::exception)
     595             : {
     596           0 :     return sal_False;
     597             : }
     598             : 
     599           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInComparisons(  ) throw(SQLException, RuntimeException, std::exception)
     600             : {
     601           0 :     return sal_False;
     602             : }
     603             : 
     604           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInExists(  ) throw(SQLException, RuntimeException, std::exception)
     605             : {
     606           0 :     return sal_False;
     607             : }
     608             : 
     609           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInIns(  ) throw(SQLException, RuntimeException, std::exception)
     610             : {
     611           0 :     return sal_False;
     612             : }
     613             : 
     614           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsSubqueriesInQuantifieds(  ) throw(SQLException, RuntimeException, std::exception)
     615             : {
     616           0 :     return sal_False;
     617             : }
     618             : 
     619           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsANSI92IntermediateSQL(  ) throw(SQLException, RuntimeException, std::exception)
     620             : {
     621           0 :     return sal_False;
     622             : }
     623             : 
     624           4 : OUString SAL_CALL ODatabaseMetaData::getURL() throw(SQLException, RuntimeException, std::exception)
     625             : {
     626           4 :     return m_pConnection->getConnectionURL();
     627             : }
     628             : 
     629           0 : OUString SAL_CALL ODatabaseMetaData::getUserName(  ) throw(SQLException, RuntimeException, std::exception)
     630             : {
     631           0 :     OUString aValue;
     632           0 :     return aValue;
     633             : }
     634             : 
     635           0 : OUString SAL_CALL ODatabaseMetaData::getDriverName(  ) throw(SQLException, RuntimeException, std::exception)
     636             : {
     637           0 :     OUString aValue;
     638           0 :     return aValue;
     639             : }
     640             : 
     641           0 : OUString SAL_CALL ODatabaseMetaData::getDriverVersion() throw(SQLException, RuntimeException, std::exception)
     642             : {
     643           0 :     OUString aValue;
     644           0 :     return aValue;
     645             : }
     646             : 
     647           0 : OUString SAL_CALL ODatabaseMetaData::getDatabaseProductVersion(  ) throw(SQLException, RuntimeException, std::exception)
     648             : {
     649           0 :     OUString aValue;
     650           0 :     return aValue;
     651             : }
     652             : 
     653           0 : OUString SAL_CALL ODatabaseMetaData::getDatabaseProductName(  ) throw(SQLException, RuntimeException, std::exception)
     654             : {
     655           0 :     OUString aValue;
     656           0 :     return aValue;
     657             : }
     658             : 
     659           0 : OUString SAL_CALL ODatabaseMetaData::getProcedureTerm(  ) throw(SQLException, RuntimeException, std::exception)
     660             : {
     661           0 :     OUString aValue;
     662           0 :     return aValue;
     663             : }
     664             : 
     665           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMajorVersion(  ) throw(RuntimeException, std::exception)
     666             : {
     667           0 :     return 1;
     668             : }
     669             : 
     670           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getDriverMinorVersion(  ) throw(RuntimeException, std::exception)
     671             : {
     672           0 :     return 0;
     673             : }
     674             : 
     675           0 : OUString SAL_CALL ODatabaseMetaData::getSQLKeywords(  ) throw(SQLException, RuntimeException, std::exception)
     676             : {
     677           0 :     OUString aValue;
     678           0 :     return aValue;
     679             : }
     680             : 
     681           0 : OUString SAL_CALL ODatabaseMetaData::getSearchStringEscape(  ) throw(SQLException, RuntimeException, std::exception)
     682             : {
     683           0 :     OUString aValue;
     684           0 :     return aValue;
     685             : }
     686             : 
     687           0 : OUString SAL_CALL ODatabaseMetaData::getStringFunctions(  ) throw(SQLException, RuntimeException, std::exception)
     688             : {
     689           0 :     return OUString();
     690             : }
     691             : 
     692           0 : OUString SAL_CALL ODatabaseMetaData::getTimeDateFunctions(  ) throw(SQLException, RuntimeException, std::exception)
     693             : {
     694           0 :     return OUString();
     695             : }
     696             : 
     697           0 : OUString SAL_CALL ODatabaseMetaData::getSystemFunctions(  ) throw(SQLException, RuntimeException, std::exception)
     698             : {
     699           0 :     return OUString();
     700             : }
     701             : 
     702           0 : OUString SAL_CALL ODatabaseMetaData::getNumericFunctions(  ) throw(SQLException, RuntimeException, std::exception)
     703             : {
     704           0 :     return OUString();
     705             : }
     706             : 
     707           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsExtendedSQLGrammar(  ) throw(SQLException, RuntimeException, std::exception)
     708             : {
     709           0 :     return sal_False;
     710             : }
     711             : 
     712           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsFullOuterJoins(  ) throw(SQLException, RuntimeException, std::exception)
     713             : {
     714           0 :     return sal_False;
     715             : }
     716             : 
     717           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsLimitedOuterJoins(  ) throw(SQLException, RuntimeException, std::exception)
     718             : {
     719           0 :     return sal_False;
     720             : }
     721             : 
     722           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInGroupBy(  ) throw(SQLException, RuntimeException, std::exception)
     723             : {
     724           0 :     sal_Int32 nValue = 0; // 0 means no limit
     725           0 :     return nValue;
     726             : }
     727             : 
     728           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInOrderBy(  ) throw(SQLException, RuntimeException, std::exception)
     729             : {
     730           0 :     sal_Int32 nValue = 0; // 0 means no limit
     731           0 :     return nValue;
     732             : }
     733             : 
     734           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxColumnsInSelect(  ) throw(SQLException, RuntimeException, std::exception)
     735             : {
     736           0 :     sal_Int32 nValue = 0; // 0 means no limit
     737           0 :     return nValue;
     738             : }
     739             : 
     740           0 : sal_Int32 SAL_CALL ODatabaseMetaData::getMaxUserNameLength(  ) throw(SQLException, RuntimeException, std::exception)
     741             : {
     742           0 :     return 31;
     743             : }
     744             : 
     745           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetType(sal_Int32 setType)
     746             :     throw(SQLException, RuntimeException, std::exception)
     747             : {
     748           0 :     switch (setType)
     749             :     {
     750             :         case ResultSetType::FORWARD_ONLY:
     751           0 :             return sal_True;
     752             :         default:
     753           0 :             return sal_False;
     754             :     }
     755             : }
     756             : 
     757           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsResultSetConcurrency(
     758             :         sal_Int32 aResultSetType,
     759             :         sal_Int32 aConcurrency)
     760             :     throw(SQLException, RuntimeException, std::exception)
     761             : {
     762           0 :     if (aResultSetType == ResultSetType::FORWARD_ONLY
     763           0 :         && aConcurrency == ResultSetConcurrency::READ_ONLY)
     764           0 :         return sal_True;
     765             :     else
     766           0 :         return sal_False;
     767             : }
     768             : 
     769           0 : sal_Bool SAL_CALL ODatabaseMetaData::ownUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     770             : {
     771             :     (void) setType;
     772           0 :     return sal_False;
     773             : }
     774             : 
     775           0 : sal_Bool SAL_CALL ODatabaseMetaData::ownDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     776             : {
     777             :     (void) setType;
     778           0 :     return sal_False;
     779             : }
     780             : 
     781           0 : sal_Bool SAL_CALL ODatabaseMetaData::ownInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     782             : {
     783             :     (void) setType;
     784           0 :     return sal_False;
     785             : }
     786             : 
     787           0 : sal_Bool SAL_CALL ODatabaseMetaData::othersUpdatesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     788             : {
     789             :     (void) setType;
     790           0 :     return sal_False;
     791             : }
     792             : 
     793           0 : sal_Bool SAL_CALL ODatabaseMetaData::othersDeletesAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     794             : {
     795             :     (void) setType;
     796           0 :     return sal_False;
     797             : }
     798             : 
     799           0 : sal_Bool SAL_CALL ODatabaseMetaData::othersInsertsAreVisible( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     800             : {
     801             :     (void) setType;
     802           0 :     return sal_False;
     803             : }
     804             : 
     805           0 : sal_Bool SAL_CALL ODatabaseMetaData::updatesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     806             : {
     807             :     (void) setType;
     808           0 :     return sal_False;
     809             : }
     810             : 
     811           0 : sal_Bool SAL_CALL ODatabaseMetaData::deletesAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     812             : {
     813             :     (void) setType;
     814           0 :     return sal_False;
     815             : }
     816             : 
     817           0 : sal_Bool SAL_CALL ODatabaseMetaData::insertsAreDetected( sal_Int32 setType ) throw(SQLException, RuntimeException, std::exception)
     818             : {
     819             :     (void) setType;
     820           0 :     return sal_False;
     821             : }
     822             : 
     823           0 : sal_Bool SAL_CALL ODatabaseMetaData::supportsBatchUpdates()
     824             :     throw(SQLException, RuntimeException, std::exception)
     825             : {
     826             :     // No batch support in firebird
     827           0 :     return sal_False;
     828             : }
     829             : 
     830           2 : uno::Reference< XConnection > SAL_CALL ODatabaseMetaData::getConnection()
     831             :     throw(SQLException, RuntimeException, std::exception)
     832             : {
     833           2 :     return uno::Reference<XConnection>(m_pConnection.get());
     834             : }
     835             : 
     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
     840             : 
     841           4 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTableTypes(  ) throw(SQLException, RuntimeException, std::exception)
     842             : {
     843             :     OSL_FAIL("Not implemented yet!");
     844             :     // TODO implement
     845           4 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTableTypes);
     846             : }
     847             : 
     848           4 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
     849             :     throw(SQLException, RuntimeException, std::exception)
     850             : {
     851             :     SAL_INFO("connectivity.firebird", "getTypeInfo()");
     852             : 
     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           4 :             new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTypeInfo);
     857           4 :     uno::Reference< XResultSet > xResultSet = pResultSet;
     858           4 :     static ODatabaseMetaDataResultSet::ORows aResults;
     859             : 
     860           4 :     if(aResults.empty())
     861             :     {
     862           2 :         ODatabaseMetaDataResultSet::ORow aRow(19);
     863             : 
     864             :         // Common data
     865           2 :         aRow[4] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
     866           2 :         aRow[5] = ODatabaseMetaDataResultSet::getQuoteValue(); // Literal quote marks
     867           2 :         aRow[7] = new ORowSetValueDecorator(sal_True); // Nullable
     868           2 :         aRow[8] = new ORowSetValueDecorator(sal_True); // Case sensitive
     869           2 :         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           2 :         aRow[11] = new ORowSetValueDecorator(sal_False);
     875             :         // Localised Type Name -- TODO: implement (but can be null):
     876           2 :         aRow[13] = new ORowSetValueDecorator();
     877           2 :         aRow[16] = new ORowSetValueDecorator();             // Unused
     878           2 :         aRow[17] = new ORowSetValueDecorator();             // Unused
     879           2 :         aRow[18] = new ORowSetValueDecorator(sal_Int16(10));// Radix
     880             : 
     881             :         // SQL_TEXT
     882           2 :         aRow[1] = new ORowSetValueDecorator(OUString("CHAR"));
     883           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT));
     884           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
     885           2 :         aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
     886           6 :         aRow[9] = new ORowSetValueDecorator(
     887           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     888           2 :         aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
     889           2 :         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
     890           2 :         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
     891           2 :         aResults.push_back(aRow);
     892             : 
     893             :         // SQL_VARYING
     894           2 :         aRow[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
     895           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING));
     896           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(32767)); // Prevision = max length
     897           2 :         aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
     898           6 :         aRow[9] = new ORowSetValueDecorator(
     899           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     900           2 :         aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
     901           2 :         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
     902           2 :         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
     903           2 :         aResults.push_back(aRow);
     904             : 
     905             :         // Integer Types common
     906             :         {
     907           2 :             aRow[6] = new ORowSetValueDecorator(); // Create Params
     908           6 :             aRow[9] = new ORowSetValueDecorator(
     909           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     910           2 :             aRow[12] = new ORowSetValueDecorator(sal_True); // Autoincrement
     911           2 :             aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
     912           2 :             aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
     913             :         }
     914             :         // SQL_SHORT
     915           2 :         aRow[1] = new ORowSetValueDecorator(OUString("SMALLINT"));
     916           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT));
     917           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(5)); // Prevision
     918           2 :         aResults.push_back(aRow);
     919             :         // SQL_LONG
     920           2 :         aRow[1] = new ORowSetValueDecorator(OUString("INTEGER"));
     921           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG));
     922           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(10)); // Precision
     923           2 :         aResults.push_back(aRow);
     924             :         // SQL_INT64
     925           2 :         aRow[1] = new ORowSetValueDecorator(OUString("BIGINT"));
     926           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64));
     927           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(20)); // Precision
     928           2 :         aResults.push_back(aRow);
     929             : 
     930             :         // Decimal Types common
     931             :         {
     932           2 :             aRow[6] = new ORowSetValueDecorator(); // Create Params
     933           6 :             aRow[9] = new ORowSetValueDecorator(
     934           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     935           2 :             aRow[12] = new ORowSetValueDecorator(sal_True); // Autoincrement
     936             :         }
     937             :         // SQL_FLOAT
     938           2 :         aRow[1] = new ORowSetValueDecorator(OUString("FLOAT"));
     939           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT));
     940           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(7)); // Precision
     941           2 :         aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
     942           2 :         aRow[15] = new ORowSetValueDecorator(sal_Int16(7)); // Max scale
     943           2 :         aResults.push_back(aRow);
     944             :         // SQL_DOUBLE
     945           2 :         aRow[1] = new ORowSetValueDecorator(OUString("DOUBLE PRECISION"));
     946           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE));
     947           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
     948           2 :         aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
     949           2 :         aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
     950           2 :         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
     959             : 
     960             :         // SQL_TIMESTAMP
     961             :         // TODO: precision?
     962           2 :         aRow[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
     963           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP));
     964           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
     965           2 :         aRow[6] = new ORowSetValueDecorator(); // Create Params
     966           6 :         aRow[9] = new ORowSetValueDecorator(
     967           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     968           2 :         aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
     969           2 :         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
     970           2 :         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
     971           2 :         aResults.push_back(aRow);
     972             : 
     973             :         // SQL_TYPE_TIME
     974             :         // TODO: precision?
     975           2 :         aRow[1] = new ORowSetValueDecorator(OUString("TIME"));
     976           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME));
     977           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
     978           2 :         aRow[6] = new ORowSetValueDecorator(); // Create Params
     979           6 :         aRow[9] = new ORowSetValueDecorator(
     980           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     981           2 :         aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
     982           2 :         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
     983           2 :         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
     984           2 :         aResults.push_back(aRow);
     985             : 
     986             :         // SQL_TYPE_DATE
     987             :         // TODO: precision?
     988           2 :         aRow[1] = new ORowSetValueDecorator(OUString("DATE"));
     989           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE));
     990           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
     991           2 :         aRow[6] = new ORowSetValueDecorator(); // Create Params
     992           6 :         aRow[9] = new ORowSetValueDecorator(
     993           4 :                 sal_Int16(ColumnSearch::FULL)); // Searchable
     994           2 :         aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
     995           2 :         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
     996           2 :         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
     997           2 :         aResults.push_back(aRow);
     998             : 
     999             :         // SQL_BLOB
    1000             :         // TODO: precision?
    1001           2 :         aRow[1] = new ORowSetValueDecorator(OUString("BLOB"));
    1002           2 :         aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB));
    1003           2 :         aRow[3] = new ORowSetValueDecorator(sal_Int32(0)); // Prevision = max length
    1004           2 :         aRow[6] = new ORowSetValueDecorator(); // Create Params
    1005           6 :         aRow[9] = new ORowSetValueDecorator(
    1006           4 :                 sal_Int16(ColumnSearch::NONE)); // Searchable
    1007           2 :         aRow[12] = new ORowSetValueDecorator(sal_False); // Autoincrement
    1008           2 :         aRow[14] = ODatabaseMetaDataResultSet::get0Value(); // Minimum scale
    1009           2 :         aRow[15] = ODatabaseMetaDataResultSet::get0Value(); // Max scale
    1010           2 :         aResults.push_back(aRow);
    1011             : 
    1012             :         // TODO: complete
    1013             : //     case SQL_ARRAY:
    1014             : //     case SQL_NULL:
    1015             : //     case SQL_QUAD:      // Is a "Blob ID" according to the docs
    1016             :     }
    1017           4 :     pResultSet->setRows(aResults);
    1018           4 :     return xResultSet;
    1019             : }
    1020             : 
    1021           0 : 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)
    1027             : {
    1028             :     SAL_INFO("connectivity.firebird", "getColumnPrivileges() with "
    1029             :              "Table: " << sTable
    1030             :              << " & ColumnNamePattern: " << sColumnNamePattern);
    1031             : 
    1032             :     ODatabaseMetaDataResultSet* pResultSet = new
    1033           0 :         ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumnPrivileges);
    1034           0 :     uno::Reference< XResultSet > xResultSet = pResultSet;
    1035           0 :     uno::Reference< XStatement > statement = m_pConnection->createStatement();
    1036             : 
    1037           0 :     static const OUString 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           0 :             "FROM RDB$USER_PRIVILEGES priv ");
    1047             : 
    1048             :     {
    1049           0 :         OUString sAppend = "WHERE priv.RDB$RELATION_NAME = '%' ";
    1050           0 :         queryBuf.append(sAppend.replaceAll("%", sTable));
    1051             :     }
    1052           0 :     if (!sColumnNamePattern.isEmpty())
    1053             :     {
    1054           0 :         OUString sAppend;
    1055           0 :         if (sColumnNamePattern.match(wld))
    1056           0 :             sAppend = "AND priv.RDB$FIELD_NAME LIKE '%' ";
    1057             :         else
    1058           0 :             sAppend = "AND priv.RDB$FIELD_NAME = '%' ";
    1059             : 
    1060           0 :         queryBuf.append(sAppend.replaceAll(wld, sColumnNamePattern));
    1061             :     }
    1062             : 
    1063             :     queryBuf.append(" ORDER BY priv.RDB$FIELD, "
    1064           0 :                               "priv.RDB$PRIVILEGE");
    1065             : 
    1066           0 :     OUString query = queryBuf.makeStringAndClear();
    1067             : 
    1068           0 :     uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
    1069           0 :     uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1070           0 :     ODatabaseMetaDataResultSet::ORows aResults;
    1071             : 
    1072           0 :     ODatabaseMetaDataResultSet::ORow aCurrentRow(8);
    1073           0 :     aCurrentRow[0] = new ORowSetValueDecorator(); // Unused
    1074           0 :     aCurrentRow[1] = new ORowSetValueDecorator(); // 1. TABLE_CAT Unsupported
    1075           0 :     aCurrentRow[2] = new ORowSetValueDecorator(); // 1. TABLE_SCHEM Unsupported
    1076             : 
    1077           0 :     while( rs->next() )
    1078             :     {
    1079             :         // 3. TABLE_NAME
    1080           0 :         aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
    1081             :         // 4. COLUMN_NAME
    1082           0 :         aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(6)));
    1083           0 :         aCurrentRow[5] = new ORowSetValueDecorator(xRow->getString(2)); // 5. GRANTOR
    1084           0 :         aCurrentRow[6] = new ORowSetValueDecorator(xRow->getString(3)); // 6. GRANTEE
    1085           0 :         aCurrentRow[7] = new ORowSetValueDecorator(xRow->getString(4)); // 7. Privilege
    1086           0 :         aCurrentRow[7] = new ORowSetValueDecorator(xRow->getBoolean(5)); // 8. Grantable
    1087             : 
    1088           0 :         aResults.push_back(aCurrentRow);
    1089             :     }
    1090             : 
    1091           0 :     pResultSet->setRows( aResults );
    1092             : 
    1093           0 :     return xResultSet;
    1094             : }
    1095             : 
    1096           2 : 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)
    1102             : {
    1103             :     SAL_INFO("connectivity.firebird", "getColumns() with "
    1104             :              "TableNamePattern: " << tableNamePattern <<
    1105             :              " & ColumnNamePattern: " << columnNamePattern);
    1106             : 
    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           2 :         "WHERE (1 = 1) ");
    1125             : 
    1126           2 :     if (!tableNamePattern.isEmpty())
    1127             :     {
    1128           2 :         OUString sAppend;
    1129           2 :         if (tableNamePattern.match("%"))
    1130           0 :             sAppend = "AND relfields.RDB$RELATION_NAME LIKE '%' ";
    1131             :         else
    1132           2 :             sAppend = "AND relfields.RDB$RELATION_NAME = '%' ";
    1133             : 
    1134           2 :         queryBuf.append(sAppend.replaceAll("%", tableNamePattern));
    1135             :     }
    1136             : 
    1137           2 :     if (!columnNamePattern.isEmpty())
    1138             :     {
    1139           2 :         OUString sAppend;
    1140           2 :         if (columnNamePattern.match("%"))
    1141           2 :             sAppend = "AND relfields.RDB$FIELD_NAME LIKE '%' ";
    1142             :         else
    1143           0 :             sAppend = "AND relfields.RDB$FIELD_NAME = '%' ";
    1144             : 
    1145           2 :         queryBuf.append(sAppend.replaceAll("%", columnNamePattern));
    1146             :     }
    1147             : 
    1148           4 :     OUString query = queryBuf.makeStringAndClear();
    1149             : 
    1150           4 :     uno::Reference< XStatement > statement = m_pConnection->createStatement();
    1151           4 :     uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
    1152           4 :     uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1153             : 
    1154           4 :     ODatabaseMetaDataResultSet::ORows aResults;
    1155           4 :     ODatabaseMetaDataResultSet::ORow aCurrentRow(19);
    1156             : 
    1157           2 :     aCurrentRow[0] =  new ORowSetValueDecorator(); // Unused -- numbering starts from 0
    1158           2 :     aCurrentRow[1] =  new ORowSetValueDecorator(); // Catalog - can be null
    1159           2 :     aCurrentRow[2] =  new ORowSetValueDecorator(); // Schema - can be null
    1160           2 :     aCurrentRow[8] =  new ORowSetValueDecorator(); // Unused
    1161           2 :     aCurrentRow[10] = new ORowSetValueDecorator(sal_Int32(10)); // Radix: fixed in FB
    1162           2 :     aCurrentRow[14] = new ORowSetValueDecorator(); // Unused
    1163           2 :     aCurrentRow[15] = new ORowSetValueDecorator(); // Unused
    1164             : 
    1165          16 :     while( rs->next() )
    1166             :     {
    1167             :         // 3. TABLE_NAME
    1168          12 :         aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
    1169             :         // 4. Column Name
    1170          12 :         aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
    1171             :         // 5. Datatype
    1172          12 :         short aType = getFBTypeFromBlrType(xRow->getShort(6));
    1173          12 :         aCurrentRow[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType));
    1174             :         // 6. Typename (SQL_*)
    1175          12 :         aCurrentRow[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType));
    1176             : 
    1177             :         // 7. Column Sizes
    1178             :         {
    1179          12 :             sal_Int32 aColumnSize = 0;
    1180          12 :             switch (aType)
    1181             :             {
    1182             :                 case SQL_TEXT:
    1183             :                 case SQL_VARYING:
    1184           4 :                     aColumnSize = xRow->getShort(7);
    1185           4 :                     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           8 :                     aColumnSize = xRow->getShort(8);
    1194           8 :                     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           0 :                     break;
    1203             :             }
    1204          12 :             aCurrentRow[7] = new ORowSetValueDecorator(aColumnSize);
    1205             :         }
    1206             : 
    1207             :         // 9. Decimal Digits
    1208             :         // TODO: implement
    1209          12 :         aCurrentRow[9] = new ORowSetValueDecorator(sal_Int32(0));
    1210             : 
    1211             :         // 11. Nullable
    1212          12 :         if (xRow->getShort(9))
    1213             :         {
    1214           2 :             aCurrentRow[11] = new ORowSetValueDecorator(ColumnValue::NO_NULLS);
    1215             :         }
    1216             :         else
    1217             :         {
    1218          10 :             aCurrentRow[11] = new ORowSetValueDecorator(ColumnValue::NULLABLE);
    1219             :         }
    1220             :         // 12. Comments -- may be omitted
    1221             :         {
    1222          12 :             OUString aDescription;
    1223          24 :             uno::Reference< XBlob > xDescriptionBlob = xRow->getBlob(3);
    1224          12 :             if (xDescriptionBlob.is())
    1225             :             {
    1226           0 :                 sal_Int32 aBlobLength = (sal_Int32) xDescriptionBlob->length();
    1227           0 :                 aDescription = OUString((char*) xDescriptionBlob->getBytes(0, aBlobLength).getArray(),
    1228             :                                         aBlobLength,
    1229           0 :                                         RTL_TEXTENCODING_UTF8);
    1230             :             }
    1231          24 :             aCurrentRow[12] = new ORowSetValueDecorator(aDescription);
    1232             :         }
    1233             :         // 13. Default --  may be omitted.
    1234             :         {
    1235          12 :             uno::Reference< XBlob > xDefaultValueBlob = xRow->getBlob(4);
    1236          12 :             if (xDefaultValueBlob.is())
    1237             :             {
    1238             :                 // TODO: Implement
    1239             :             }
    1240          12 :             aCurrentRow[13] = new ORowSetValueDecorator();
    1241             :         }
    1242             : 
    1243             :         // 16. Bytes in Column for char
    1244          12 :         if (aType == SQL_TEXT)
    1245             :         {
    1246           2 :             aCurrentRow[16] = new ORowSetValueDecorator(xRow->getShort(7));
    1247             :         }
    1248          10 :         else if (aType == SQL_VARYING)
    1249             :         {
    1250           2 :             aCurrentRow[16] = new ORowSetValueDecorator(sal_Int32(32767));
    1251             :         }
    1252             :         else
    1253             :         {
    1254           8 :             aCurrentRow[16] = new ORowSetValueDecorator(sal_Int32(0));
    1255             :         }
    1256             :         // 17. Index of column
    1257             :         {
    1258          12 :             short nColumnNumber = xRow->getShort(5);
    1259             :             // Firebird stores column numbers beginning with 0 internally
    1260             :             // SDBC expects column numbering to begin with 1.
    1261          12 :             aCurrentRow[17] = new ORowSetValueDecorator(sal_Int32(nColumnNumber + 1));
    1262             :         }
    1263             :         // 18. Is nullable
    1264          12 :         if (xRow->getShort(9))
    1265             :         {
    1266           2 :             aCurrentRow[18] = new ORowSetValueDecorator(OUString("NO"));
    1267             :         }
    1268             :         else
    1269             :         {
    1270          10 :             aCurrentRow[18] = new ORowSetValueDecorator(OUString("YES"));
    1271             :         }
    1272             : 
    1273          12 :         aResults.push_back(aCurrentRow);
    1274             :     }
    1275             :     ODatabaseMetaDataResultSet* pResultSet = new
    1276           2 :             ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eColumns);
    1277           2 :     uno::Reference< XResultSet > xResultSet = pResultSet;
    1278           2 :     pResultSet->setRows( aResults );
    1279             : 
    1280           4 :     return xResultSet;
    1281             : }
    1282             : 
    1283           6 : 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)
    1289             : {
    1290             :     SAL_INFO("connectivity.firebird", "getTables() with "
    1291             :              "TableNamePattern: " << tableNamePattern);
    1292             : 
    1293             :     ODatabaseMetaDataResultSet* pResultSet = new
    1294           6 :         ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTables);
    1295           6 :     uno::Reference< XResultSet > xResultSet = pResultSet;
    1296          12 :     uno::Reference< XStatement > statement = m_pConnection->createStatement();
    1297             : 
    1298           6 :     static const OUString 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          12 :             "WHERE ");
    1308             : 
    1309             :     // TODO: GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, SYNONYM
    1310           6 :     if ((types.getLength() == 0) || (types.getLength() == 1 && types[0].match(wld)))
    1311             :     {
    1312             :         // All table types? I.e. includes system tables.
    1313           2 :         queryBuf.append("(RDB$RELATION_TYPE = 0 OR RDB$RELATION_TYPE = 1) ");
    1314             :     }
    1315             :     else
    1316             :     {
    1317           4 :         queryBuf.append("( (0 = 1) ");
    1318          12 :         for (int i = 0; i < types.getLength(); i++)
    1319             :         {
    1320           8 :             if (types[i] == "SYSTEM TABLE")
    1321           0 :                 queryBuf.append("OR (RDB$SYSTEM_FLAG = 1 AND RDB$VIEW_BLR IS NULL) ");
    1322           8 :             else if (types[i] == "TABLE")
    1323           4 :                 queryBuf.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NULL) ");
    1324           4 :             else if (types[i] == "VIEW")
    1325           4 :                 queryBuf.append("OR (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0 AND RDB$VIEW_BLR IS NOT NULL) ");
    1326             :             else
    1327           0 :                 throw SQLException(); // TODO: implement other types, see above.
    1328             :         }
    1329           4 :         queryBuf.append(") ");
    1330             :     }
    1331             : 
    1332           6 :     if (!tableNamePattern.isEmpty())
    1333             :     {
    1334           6 :         OUString sAppend;
    1335           6 :         if (tableNamePattern.match(wld))
    1336           4 :             sAppend = "AND RDB$RELATION_NAME LIKE '%' ";
    1337             :         else
    1338           2 :             sAppend = "AND RDB$RELATION_NAME = '%' ";
    1339             : 
    1340           6 :         queryBuf.append(sAppend.replaceAll(wld, tableNamePattern));
    1341             :     }
    1342             : 
    1343           6 :     queryBuf.append(" ORDER BY RDB$RELATION_TYPE, RDB$RELATION_NAME");
    1344             : 
    1345          12 :     OUString query = queryBuf.makeStringAndClear();
    1346             : 
    1347          12 :     uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
    1348          12 :     uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1349          12 :     ODatabaseMetaDataResultSet::ORows aResults;
    1350             : 
    1351          12 :     ODatabaseMetaDataResultSet::ORow aCurrentRow(6);
    1352           6 :     aCurrentRow[0] = new ORowSetValueDecorator(); // 0. Unused
    1353           6 :     aCurrentRow[1] = new ORowSetValueDecorator(); // 1. Table_Cat Unsupported
    1354           6 :     aCurrentRow[2] = new ORowSetValueDecorator(); // 2. Table_Schem Unsupported
    1355             : 
    1356          16 :     while( rs->next() )
    1357             :     {
    1358             :         // 3. TABLE_NAME
    1359           4 :         aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
    1360             :         // 4. TABLE_TYPE
    1361             :         {
    1362             :             // TODO: check this as the docs are a bit unclear.
    1363           4 :             sal_Int16 nSystemFlag = xRow->getShort(2);
    1364           4 :             sal_Int16 nTableType  = xRow->getShort(3);
    1365           4 :             xRow->getBlob(5); // We have to retrieve a column to verify it is null.
    1366           4 :             bool aIsView      = !xRow->wasNull();
    1367           4 :             OUString sTableType;
    1368             : 
    1369           4 :             if (nSystemFlag == 1)
    1370             :             {
    1371           0 :                 sTableType = "SYSTEM TABLE";
    1372             :             }
    1373           4 :             else if (aIsView)
    1374             :             {
    1375           0 :                 sTableType = "VIEW";
    1376             :             }
    1377             :             else
    1378             :             {
    1379           4 :                 if (nTableType == 0)
    1380           4 :                     sTableType = "TABLE";
    1381             :             }
    1382             : 
    1383           4 :             aCurrentRow[4] = new ORowSetValueDecorator(sTableType);
    1384             :         }
    1385             :         // 5. REMARKS
    1386             :         {
    1387           4 :             uno::Reference< XBlob > xBlob   = xRow->getBlob(4);
    1388           8 :             OUString sDescription;
    1389             : 
    1390           4 :             if (xBlob.is())
    1391             :             {
    1392             :                 // TODO: we should actually be using CLOB here instead.
    1393             :                 // However we haven't implemented CLOB yet, so use BLOB.
    1394           0 :                 sal_Int32 aBlobLength = (sal_Int32) xBlob->length();
    1395           0 :                 sDescription = OUString((char*) xBlob->getBytes(0, aBlobLength).getArray(),
    1396             :                                         aBlobLength,
    1397           0 :                                         RTL_TEXTENCODING_UTF8);
    1398             :             }
    1399             : 
    1400           8 :             aCurrentRow[5] = new ORowSetValueDecorator(sDescription);
    1401             :         }
    1402             : 
    1403           4 :         aResults.push_back(aCurrentRow);
    1404             :     }
    1405             : 
    1406           6 :     pResultSet->setRows( aResults );
    1407             : 
    1408          12 :     return xResultSet;
    1409             : }
    1410             : 
    1411           0 : 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)
    1414             : {
    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           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedureColumns);
    1423             : }
    1424             : 
    1425           0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedures(
    1426             :     const Any& catalog, const OUString& schemaPattern,
    1427             :     const OUString& procedureNamePattern ) throw(SQLException, RuntimeException, std::exception)
    1428             : {
    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           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eProcedures);
    1436             : }
    1437             : 
    1438           0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getVersionColumns(
    1439             :     const Any& catalog, const OUString& schema, const OUString& table ) throw(SQLException, RuntimeException, std::exception)
    1440             : {
    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           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eVersionColumns);
    1448             : }
    1449             : 
    1450           0 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getExportedKeys(
    1451             :     const Any& catalog, const OUString& schema, const OUString& table ) throw(SQLException, RuntimeException, std::exception)
    1452             : {
    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           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eExportedKeys);
    1463             : }
    1464             : 
    1465           2 : uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getImportedKeys(
    1466             :     const Any& catalog, const OUString& schema, const OUString& table ) throw(SQLException, RuntimeException, std::exception)
    1467             : {
    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           2 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eImportedKeys);
    1478             : }
    1479             : 
    1480           2 : 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)
    1485             : {
    1486             :     SAL_INFO("connectivity.firebird", "getPrimaryKeys() with "
    1487             :              "Table: " << sTable);
    1488             : 
    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           2 :         "on (constr.RDB$INDEX_NAME = inds.RDB$INDEX_NAME) ");
    1497             : 
    1498           4 :     OUString sAppend = "WHERE constr.RDB$RELATION_NAME = '%' ";
    1499           2 :     aQueryBuf.append(sAppend.replaceAll("%", sTable));
    1500             : 
    1501             :     aQueryBuf.append("AND constr.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
    1502           2 :                     "ORDER BY inds.RDB$FIELD_NAME");
    1503             : 
    1504           4 :     OUString sQuery = aQueryBuf.makeStringAndClear();
    1505             : 
    1506           4 :     uno::Reference< XStatement > xStatement = m_pConnection->createStatement();
    1507           4 :     uno::Reference< XResultSet > xRs = xStatement->executeQuery(sQuery);
    1508           4 :     uno::Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
    1509             : 
    1510           4 :     ODatabaseMetaDataResultSet::ORows aResults;
    1511           4 :     ODatabaseMetaDataResultSet::ORow aCurrentRow(7);
    1512             : 
    1513           2 :     aCurrentRow[0] =  new ORowSetValueDecorator(); // Unused -- numbering starts from 0
    1514           2 :     aCurrentRow[1] =  new ORowSetValueDecorator(); // Catalog - can be null
    1515           2 :     aCurrentRow[2] =  new ORowSetValueDecorator(); // Schema - can be null
    1516             : 
    1517           6 :     while(xRs->next())
    1518             :     {
    1519             :         // 3. Table Name
    1520           2 :         if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
    1521             :         {
    1522           2 :             aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
    1523             :         }
    1524             :         // 4. Column Name
    1525           2 :         aCurrentRow[4] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
    1526             :         // 5. KEY_SEQ (which key in the sequence)
    1527           2 :         aCurrentRow[5] = new ORowSetValueDecorator(xRow->getShort(3));
    1528             :         // 6. Primary Key Name
    1529           2 :         aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
    1530             : 
    1531           2 :         aResults.push_back(aCurrentRow);
    1532             :     }
    1533             :     ODatabaseMetaDataResultSet* pResultSet = new
    1534           2 :             ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys);
    1535           2 :     uno::Reference< XResultSet > xResultSet = pResultSet;
    1536           2 :     pResultSet->setRows( aResults );
    1537             : 
    1538           4 :     return xResultSet;
    1539             : }
    1540             : 
    1541           0 : 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)
    1548             : {
    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);
    1554             : 
    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           0 :         "WHERE indices.RDB$RELATION_NAME = '" + sTable + "' "
    1566           0 :         "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.
    1570             : 
    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           0 :     if (bIsUnique)
    1574           0 :         aQueryBuf.append("AND (indices.RDB$UNIQUE_FLAG = 1) ");
    1575             : 
    1576             :     // TODO: what is bIsApproximate?
    1577             :     (void) bIsApproximate;
    1578             : 
    1579           0 :     OUString sQuery = aQueryBuf.makeStringAndClear();
    1580             : 
    1581           0 :     uno::Reference< XStatement > xStatement = m_pConnection->createStatement();
    1582           0 :     uno::Reference< XResultSet > xRs = xStatement->executeQuery(sQuery);
    1583           0 :     uno::Reference< XRow > xRow( xRs, UNO_QUERY_THROW );
    1584             : 
    1585           0 :     ODatabaseMetaDataResultSet::ORows aResults;
    1586           0 :     ODatabaseMetaDataResultSet::ORow aCurrentRow(14);
    1587             : 
    1588           0 :     aCurrentRow[0] = new ORowSetValueDecorator(); // Unused -- numbering starts from 0
    1589           0 :     aCurrentRow[1] = new ORowSetValueDecorator(); // Catalog - can be null
    1590           0 :     aCurrentRow[2] = new ORowSetValueDecorator(); // Schema - can be null
    1591           0 :     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           0 :     aCurrentRow[7] = new ORowSetValueDecorator(IndexType::CLUSTERED); // 7. INDEX TYPE
    1595           0 :     aCurrentRow[13] = new ORowSetValueDecorator(); // Filter Condition -- can be null
    1596             : 
    1597           0 :     while(xRs->next())
    1598             :     {
    1599             :         // 3. Table Name
    1600           0 :         if (xRs->getRow() == 1) // Table name doesn't change, so only retrieve once
    1601             :         {
    1602           0 :             aCurrentRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
    1603             :         }
    1604             : 
    1605             :         // 4. NON_UNIQUE -- i.e. specifically negate here.
    1606           0 :         aCurrentRow[4] = new ORowSetValueDecorator(!xRow->getBoolean(5));
    1607             :         // 6. INDEX NAME
    1608           0 :         aCurrentRow[6] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(4)));
    1609             : 
    1610             :         // 8. ORDINAL POSITION
    1611           0 :         aCurrentRow[8] = new ORowSetValueDecorator(xRow->getShort(3));
    1612             :         // 9. COLUMN NAME
    1613           0 :         aCurrentRow[9] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(2)));
    1614             :         // 10. ASC(ending)/DESC(ending)
    1615           0 :         if (xRow->getShort(6) == 1)
    1616           0 :             aCurrentRow[10] = new ORowSetValueDecorator(OUString("D"));
    1617             :         else
    1618           0 :             aCurrentRow[10] = new ORowSetValueDecorator(OUString("A"));
    1619             :         // TODO: double check this^^^, doesn't seem to be officially documented anywhere.
    1620             :         // 11. CARDINALITY
    1621           0 :         aCurrentRow[11] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
    1622             :         // 12. PAGES
    1623           0 :         aCurrentRow[12] = new ORowSetValueDecorator((sal_Int32)0); // TODO: determine how to do this
    1624             : 
    1625           0 :         aResults.push_back(aCurrentRow);
    1626             :     }
    1627             :     ODatabaseMetaDataResultSet* pResultSet = new
    1628           0 :             ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::ePrimaryKeys);
    1629           0 :     uno::Reference< XResultSet > xResultSet = pResultSet;
    1630           0 :     pResultSet->setRows( aResults );
    1631             : 
    1632           0 :     return xResultSet;
    1633             : }
    1634             : 
    1635           0 : 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)
    1638             : {
    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           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eBestRowIdentifier);
    1647             : }
    1648             : 
    1649           0 : 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)
    1654             : {
    1655             :     SAL_INFO("connectivity.firebird", "getTablePrivileges() with "
    1656             :              "TableNamePattern: " << sTableNamePattern);
    1657             : 
    1658             :     ODatabaseMetaDataResultSet* pResultSet = new
    1659           0 :         ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eTablePrivileges);
    1660           0 :     uno::Reference< XResultSet > xResultSet = pResultSet;
    1661           0 :     uno::Reference< XStatement > statement = m_pConnection->createStatement();
    1662             : 
    1663             :     // TODO: column specific privileges are included, we may need
    1664             :     // to have WHERE RDB$FIELD_NAME = NULL or similar.
    1665           0 :     static const OUString 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           0 :             "FROM RDB$USER_PRIVILEGES priv ");
    1674             : 
    1675           0 :     if (!sTableNamePattern.isEmpty())
    1676             :     {
    1677           0 :         OUString sAppend;
    1678           0 :         if (sTableNamePattern.match(wld))
    1679           0 :             sAppend = "WHERE priv.RDB$RELATION_NAME LIKE '%' ";
    1680             :         else
    1681           0 :             sAppend = "WHERE priv.RDB$RELATION_NAME = '%' ";
    1682             : 
    1683           0 :         queryBuf.append(sAppend.replaceAll(wld, sTableNamePattern));
    1684             :     }
    1685             :     queryBuf.append(" ORDER BY priv.RDB$RELATION_TYPE, "
    1686             :                               "priv.RDB$RELATION_NAME, "
    1687           0 :                               "priv.RDB$PRIVILEGE");
    1688             : 
    1689           0 :     OUString query = queryBuf.makeStringAndClear();
    1690             : 
    1691           0 :     uno::Reference< XResultSet > rs = statement->executeQuery(query.getStr());
    1692           0 :     uno::Reference< XRow > xRow( rs, UNO_QUERY_THROW );
    1693           0 :     ODatabaseMetaDataResultSet::ORows aResults;
    1694             : 
    1695           0 :     ODatabaseMetaDataResultSet::ORow aRow(8);
    1696           0 :     aRow[0] = new ORowSetValueDecorator(); // Unused
    1697           0 :     aRow[1] = new ORowSetValueDecorator(); // TABLE_CAT unsupported
    1698           0 :     aRow[2] = new ORowSetValueDecorator(); // TABLE_SCHEM unussported.
    1699             : 
    1700           0 :     while( rs->next() )
    1701             :     {
    1702             :         // 3. TABLE_NAME
    1703           0 :         aRow[3] = new ORowSetValueDecorator(sanitizeIdentifier(xRow->getString(1)));
    1704           0 :         aRow[4] = new ORowSetValueDecorator(xRow->getString(2)); // 4. GRANTOR
    1705           0 :         aRow[5] = new ORowSetValueDecorator(xRow->getString(3)); // 5. GRANTEE
    1706           0 :         aRow[6] = new ORowSetValueDecorator(xRow->getString(4)); // 6. Privilege
    1707           0 :         aRow[7] = new ORowSetValueDecorator(xRow->getBoolean(5)); // 7. Is Grantable
    1708             : 
    1709           0 :         aResults.push_back(aRow);
    1710             :     }
    1711             : 
    1712           0 :     pResultSet->setRows( aResults );
    1713             : 
    1714           0 :     return xResultSet;
    1715             : }
    1716             : 
    1717           0 : 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)
    1721             : {
    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           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eCrossReference);
    1731             : }
    1732             : 
    1733           0 : 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)
    1734             : {
    1735             :     (void) catalog;
    1736             :     (void) schemaPattern;
    1737             :     (void) typeNamePattern;
    1738             :     (void) types;
    1739             :     OSL_FAIL("Not implemented yet!");
    1740             :     // TODO implement
    1741           0 :     return new ODatabaseMetaDataResultSet(ODatabaseMetaDataResultSet::eUDTs);
    1742             : }
    1743             : 
    1744             : 
    1745             : 
    1746             : 
    1747             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10