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

Generated by: LCOV version 1.10