LCOV - code coverage report
Current view: top level - connectivity/source/commontools - dbmetadata.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 44 157 28.0 %
Date: 2014-11-03 Functions: 14 28 50.0 %
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             : 
      21             : #include <connectivity/dbmetadata.hxx>
      22             : #include <connectivity/dbexception.hxx>
      23             : #include <connectivity/DriversConfig.hxx>
      24             : #include "resource/common_res.hrc"
      25             : #include "resource/sharedresources.hxx"
      26             : 
      27             : #include <com/sun/star/lang/IllegalArgumentException.hpp>
      28             : #include <com/sun/star/container/XChild.hpp>
      29             : #include <com/sun/star/beans/XPropertySet.hpp>
      30             : #include <com/sun/star/beans/PropertyValue.hpp>
      31             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      32             : #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
      33             : #include <com/sun/star/sdbc/XDatabaseMetaData2.hpp>
      34             : #include <com/sun/star/sdbcx/XUsersSupplier.hpp>
      35             : #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
      36             : #include <com/sun/star/sdbc/XDriverAccess.hpp>
      37             : #include <com/sun/star/sdbc/DriverManager.hpp>
      38             : 
      39             : #include <tools/diagnose_ex.h>
      40             : #include <comphelper/namedvaluecollection.hxx>
      41             : #include <comphelper/processfactory.hxx>
      42             : #include <sal/macros.h>
      43             : 
      44             : #include <boost/optional.hpp>
      45             : 
      46             : 
      47             : namespace dbtools
      48             : {
      49             : 
      50             : 
      51             :     using ::com::sun::star::uno::Reference;
      52             :     using ::com::sun::star::sdbc::XConnection;
      53             :     using ::com::sun::star::sdbc::XDatabaseMetaData;
      54             :     using ::com::sun::star::sdbc::XDatabaseMetaData2;
      55             :     using ::com::sun::star::lang::IllegalArgumentException;
      56             :     using ::com::sun::star::uno::Exception;
      57             :     using ::com::sun::star::uno::Any;
      58             :     using ::com::sun::star::uno::XComponentContext;
      59             :     using ::com::sun::star::container::XChild;
      60             :     using ::com::sun::star::uno::UNO_QUERY_THROW;
      61             :     using ::com::sun::star::beans::XPropertySet;
      62             :     using ::com::sun::star::uno::Sequence;
      63             :     using ::com::sun::star::beans::PropertyValue;
      64             :     using ::com::sun::star::beans::XPropertySetInfo;
      65             :     using ::com::sun::star::uno::UNO_QUERY;
      66             :     using ::com::sun::star::sdbcx::XUsersSupplier;
      67             :     using ::com::sun::star::sdbcx::XDataDefinitionSupplier;
      68             :     using ::com::sun::star::sdbc::XDriverAccess;
      69             :     using ::com::sun::star::sdbc::DriverManager;
      70             :     using ::com::sun::star::sdbc::XDriverManager2;
      71             :     using ::com::sun::star::uno::UNO_SET_THROW;
      72             : 
      73             :     namespace BooleanComparisonMode = ::com::sun::star::sdb::BooleanComparisonMode;
      74             : 
      75             : 
      76             :     //= DatabaseMetaData_Impl
      77             : 
      78       45141 :     struct DatabaseMetaData_Impl
      79             :     {
      80             :         Reference< XConnection >        xConnection;
      81             :         Reference< XDatabaseMetaData >  xConnectionMetaData;
      82             :         ::connectivity::DriversConfig   aDriverConfig;
      83             : 
      84             :         ::boost::optional< OUString >    sCachedIdentifierQuoteString;
      85             :         ::boost::optional< OUString >    sCachedCatalogSeparator;
      86             : 
      87        3907 :         DatabaseMetaData_Impl()
      88             :             :xConnection()
      89             :             ,xConnectionMetaData()
      90             :             ,aDriverConfig( ::comphelper::getProcessComponentContext() )
      91             :             ,sCachedIdentifierQuoteString()
      92        3907 :             ,sCachedCatalogSeparator()
      93             :         {
      94        3907 :         }
      95             :     };
      96             : 
      97             : 
      98             :     namespace
      99             :     {
     100             : 
     101        3905 :         static void lcl_construct( DatabaseMetaData_Impl& _metaDataImpl, const Reference< XConnection >& _connection )
     102             :         {
     103        3905 :             _metaDataImpl.xConnection = _connection;
     104        3905 :             if ( !_metaDataImpl.xConnection.is() )
     105        3907 :                 return;
     106             : 
     107        3903 :             _metaDataImpl.xConnectionMetaData = _connection->getMetaData();
     108        3903 :             if ( !_metaDataImpl.xConnectionMetaData.is() )
     109           0 :                 throw IllegalArgumentException();
     110             :         }
     111             : 
     112             : 
     113        8658 :         static void lcl_checkConnected( const DatabaseMetaData_Impl& _metaDataImpl )
     114             :         {
     115        8658 :             if ( !_metaDataImpl.xConnection.is() || !_metaDataImpl.xConnectionMetaData.is() )
     116             :             {
     117           0 :                 ::connectivity::SharedResources aResources;
     118           0 :                 const OUString sError( aResources.getResourceString(STR_NO_CONNECTION_GIVEN));
     119           0 :                 throwSQLException( sError, SQL_CONNECTION_DOES_NOT_EXIST, NULL );
     120             :             }
     121        8658 :         }
     122             : 
     123             : 
     124           0 :         static bool lcl_getDriverSetting( const sal_Char* _asciiName, const DatabaseMetaData_Impl& _metaData, Any& _out_setting )
     125             :         {
     126           0 :             lcl_checkConnected( _metaData );
     127           0 :             const ::comphelper::NamedValueCollection& rDriverMetaData = _metaData.aDriverConfig.getMetaData( _metaData.xConnectionMetaData->getURL() );
     128           0 :             if ( !rDriverMetaData.has( _asciiName ) )
     129           0 :                 return false;
     130           0 :             _out_setting = rDriverMetaData.get( _asciiName );
     131           0 :             return true;
     132             :         }
     133             : 
     134             : 
     135           0 :         static bool lcl_getConnectionSetting( const sal_Char* _asciiName, const DatabaseMetaData_Impl& _metaData, Any& _out_setting )
     136             :         {
     137             :             try
     138             :             {
     139           0 :                 Reference< XChild > xConnectionAsChild( _metaData.xConnection, UNO_QUERY );
     140           0 :                 if ( xConnectionAsChild.is() )
     141             :                 {
     142           0 :                     Reference< XPropertySet > xDataSource( xConnectionAsChild->getParent(), UNO_QUERY_THROW );
     143             :                     Reference< XPropertySet > xDataSourceSettings(
     144           0 :                         xDataSource->getPropertyValue("Settings"),
     145           0 :                         UNO_QUERY_THROW );
     146             : 
     147           0 :                     _out_setting = xDataSourceSettings->getPropertyValue( OUString::createFromAscii( _asciiName ) );
     148             :                 }
     149             :                 else
     150             :                 {
     151           0 :                     Reference< XDatabaseMetaData2 > xExtendedMetaData( _metaData.xConnectionMetaData, UNO_QUERY_THROW );
     152           0 :                     ::comphelper::NamedValueCollection aSettings( xExtendedMetaData->getConnectionInfo() );
     153           0 :                     _out_setting = aSettings.get( _asciiName );
     154           0 :                     return _out_setting.hasValue();
     155             :                 }
     156           0 :                 return true;
     157             :             }
     158           0 :             catch( const Exception& )
     159             :             {
     160             :                 DBG_UNHANDLED_EXCEPTION();
     161             :             }
     162           0 :             return false;
     163             :         }
     164             : 
     165             : 
     166       10652 :         static const OUString& lcl_getConnectionStringSetting(
     167             :             const DatabaseMetaData_Impl& _metaData, ::boost::optional< OUString >& _cachedSetting,
     168             :             OUString (SAL_CALL XDatabaseMetaData::*_getter)() )
     169             :         {
     170       10652 :             if ( !_cachedSetting )
     171             :             {
     172        8170 :                 lcl_checkConnected( _metaData );
     173             :                 try
     174             :                 {
     175        8170 :                     _cachedSetting.reset( (_metaData.xConnectionMetaData.get()->*_getter)() );
     176             :                 }
     177           0 :                 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
     178             :             }
     179       10652 :             return *_cachedSetting;
     180             :         }
     181             :     }
     182             : 
     183             : 
     184             :     //= DatabaseMetaData
     185             : 
     186             : 
     187           2 :     DatabaseMetaData::DatabaseMetaData()
     188           2 :         :m_pImpl( new DatabaseMetaData_Impl )
     189             :     {
     190           2 :     }
     191             : 
     192             : 
     193        3905 :     DatabaseMetaData::DatabaseMetaData( const Reference< XConnection >& _connection )
     194        3905 :         :m_pImpl( new DatabaseMetaData_Impl )
     195             :     {
     196        3905 :         lcl_construct( *m_pImpl, _connection );
     197        3905 :     }
     198             : 
     199             : 
     200       20615 :     DatabaseMetaData::DatabaseMetaData( const DatabaseMetaData& _copyFrom )
     201       20615 :         :m_pImpl( new DatabaseMetaData_Impl( *_copyFrom.m_pImpl ) )
     202             :     {
     203       20615 :     }
     204             : 
     205             : 
     206           2 :     DatabaseMetaData& DatabaseMetaData::operator=( const DatabaseMetaData& _copyFrom )
     207             :     {
     208           2 :         if ( this == &_copyFrom )
     209           0 :             return *this;
     210             : 
     211           2 :         m_pImpl.reset( new DatabaseMetaData_Impl( *_copyFrom.m_pImpl ) );
     212           2 :         return *this;
     213             :     }
     214             : 
     215             : 
     216       24522 :     DatabaseMetaData::~DatabaseMetaData()
     217             :     {
     218       24522 :     }
     219             : 
     220             : 
     221           0 :     bool DatabaseMetaData::isConnected() const
     222             :     {
     223           0 :         return m_pImpl->xConnection.is();
     224             :     }
     225             : 
     226             : 
     227         488 :     bool DatabaseMetaData::supportsSubqueriesInFrom() const
     228             :     {
     229         488 :         lcl_checkConnected( *m_pImpl );
     230             : 
     231         488 :         bool supportsSubQueries = false;
     232             :         try
     233             :         {
     234         488 :             sal_Int32 maxTablesInselect = m_pImpl->xConnectionMetaData->getMaxTablesInSelect();
     235         488 :             supportsSubQueries = ( maxTablesInselect > 1 ) || ( maxTablesInselect == 0 );
     236             :             // TODO: is there a better way to determine this? The above is not really true. More precise,
     237             :             // it's a *very* generous heuristics ...
     238             :         }
     239           0 :         catch( const Exception& )
     240             :         {
     241             :             DBG_UNHANDLED_EXCEPTION();
     242             :         }
     243         488 :         return supportsSubQueries;
     244             :     }
     245             : 
     246             : 
     247           0 :     bool DatabaseMetaData::supportsPrimaryKeys() const
     248             :     {
     249           0 :         lcl_checkConnected( *m_pImpl );
     250             : 
     251           0 :         bool doesSupportPrimaryKeys = false;
     252             :         try
     253             :         {
     254           0 :             Any setting;
     255           0 :             if  (   !( lcl_getConnectionSetting( "PrimaryKeySupport", *m_pImpl, setting ) )
     256           0 :                 ||  !( setting >>= doesSupportPrimaryKeys )
     257             :                 )
     258           0 :                 doesSupportPrimaryKeys = m_pImpl->xConnectionMetaData->supportsCoreSQLGrammar();
     259             :         }
     260           0 :         catch( const Exception& )
     261             :         {
     262             :             DBG_UNHANDLED_EXCEPTION();
     263             :         }
     264           0 :         return doesSupportPrimaryKeys;
     265             :     }
     266             : 
     267             : 
     268        4964 :     const OUString&  DatabaseMetaData::getIdentifierQuoteString() const
     269             :     {
     270        4964 :         return lcl_getConnectionStringSetting( *m_pImpl, m_pImpl->sCachedIdentifierQuoteString, &XDatabaseMetaData::getIdentifierQuoteString );
     271             :     }
     272             : 
     273             : 
     274        5688 :     const OUString&  DatabaseMetaData::getCatalogSeparator() const
     275             :     {
     276        5688 :         return lcl_getConnectionStringSetting( *m_pImpl, m_pImpl->sCachedCatalogSeparator, &XDatabaseMetaData::getCatalogSeparator );
     277             :     }
     278             : 
     279             : 
     280           0 :     bool DatabaseMetaData::restrictIdentifiersToSQL92() const
     281             :     {
     282           0 :         lcl_checkConnected( *m_pImpl );
     283             : 
     284           0 :         bool restrict( false );
     285           0 :         Any setting;
     286           0 :         if ( lcl_getConnectionSetting( "EnableSQL92Check", *m_pImpl, setting ) )
     287           0 :             OSL_VERIFY( setting >>= restrict );
     288           0 :         return restrict;
     289             :     }
     290             : 
     291             : 
     292           0 :     bool DatabaseMetaData::generateASBeforeCorrelationName() const
     293             :     {
     294           0 :         bool doGenerate( false );
     295           0 :         Any setting;
     296           0 :         if ( lcl_getConnectionSetting( "GenerateASBeforeCorrelationName", *m_pImpl, setting ) )
     297           0 :             OSL_VERIFY( setting >>= doGenerate );
     298           0 :         return doGenerate;
     299             :     }
     300             : 
     301           0 :     bool DatabaseMetaData::shouldEscapeDateTime() const
     302             :     {
     303           0 :         bool doGenerate( true );
     304           0 :         Any setting;
     305           0 :         if ( lcl_getConnectionSetting( "EscapeDateTime", *m_pImpl, setting ) )
     306           0 :             OSL_VERIFY( setting >>= doGenerate );
     307           0 :         return doGenerate;
     308             :     }
     309             : 
     310           0 :     bool DatabaseMetaData::isAutoIncrementPrimaryKey() const
     311             :     {
     312           0 :         bool is( true );
     313           0 :         Any setting;
     314           0 :         if ( lcl_getDriverSetting( "AutoIncrementIsPrimaryKey", *m_pImpl, setting ) )
     315           0 :             OSL_VERIFY( setting >>= is );
     316           0 :         return is;
     317             :     }
     318             : 
     319           0 :     sal_Int32 DatabaseMetaData::getBooleanComparisonMode() const
     320             :     {
     321           0 :         sal_Int32 mode( BooleanComparisonMode::EQUAL_INTEGER );
     322           0 :         Any setting;
     323           0 :         if ( lcl_getConnectionSetting( "BooleanComparisonMode", *m_pImpl, setting ) )
     324           0 :             OSL_VERIFY( setting >>= mode );
     325           0 :         return mode;
     326             :     }
     327             : 
     328           0 :     bool DatabaseMetaData::supportsRelations() const
     329             :     {
     330           0 :         lcl_checkConnected( *m_pImpl );
     331           0 :         bool bSupport = false;
     332             :         try
     333             :         {
     334           0 :             bSupport = m_pImpl->xConnectionMetaData->supportsIntegrityEnhancementFacility();
     335             :         }
     336           0 :         catch( const Exception& )
     337             :         {
     338             :             DBG_UNHANDLED_EXCEPTION();
     339             :         }
     340             :         try
     341             :         {
     342           0 :             if ( !bSupport )
     343             :             {
     344           0 :                 const OUString url = m_pImpl->xConnectionMetaData->getURL();
     345           0 :                 char pMySQL[] = "sdbc:mysql";
     346           0 :                 bSupport = url.matchAsciiL(pMySQL,(sizeof(pMySQL)/sizeof(pMySQL[0]))-1);
     347             :             }
     348             :         }
     349           0 :         catch( const Exception& )
     350             :         {
     351             :             DBG_UNHANDLED_EXCEPTION();
     352             :         }
     353           0 :         return bSupport;
     354             :     }
     355             : 
     356             : 
     357           0 :     bool DatabaseMetaData::supportsColumnAliasInOrderBy() const
     358             :     {
     359           0 :         bool doGenerate( true );
     360           0 :         Any setting;
     361           0 :         if ( lcl_getConnectionSetting( "ColumnAliasInOrderBy", *m_pImpl, setting ) )
     362           0 :             OSL_VERIFY( setting >>= doGenerate );
     363           0 :         return doGenerate;
     364             :     }
     365             : 
     366             : 
     367           0 :     bool DatabaseMetaData::supportsUserAdministration( const Reference<XComponentContext>& _rContext ) const
     368             :     {
     369           0 :         lcl_checkConnected( *m_pImpl  );
     370             : 
     371           0 :         bool isSupported( false );
     372             :         try
     373             :         {
     374             :             // find the XUsersSupplier interface
     375             :             // - either directly at the connection
     376           0 :             Reference< XUsersSupplier > xUsersSupp( m_pImpl->xConnection, UNO_QUERY );
     377           0 :             if ( !xUsersSupp.is() )
     378             :             {
     379             :                 // - or at the driver manager
     380           0 :                 Reference< XDriverManager2 > xDriverManager = DriverManager::create( _rContext );
     381           0 :                 Reference< XDataDefinitionSupplier > xDriver( xDriverManager->getDriverByURL( m_pImpl->xConnectionMetaData->getURL() ), UNO_QUERY );
     382           0 :                 if ( xDriver.is() )
     383           0 :                     xUsersSupp.set( xDriver->getDataDefinitionByConnection( m_pImpl->xConnection ), UNO_QUERY );
     384             :             }
     385             : 
     386           0 :             isSupported = ( xUsersSupp.is() && xUsersSupp->getUsers().is() );
     387             :         }
     388           0 :         catch( const Exception& )
     389             :         {
     390             :             DBG_UNHANDLED_EXCEPTION();
     391             :         }
     392           0 :         return isSupported;
     393             :     }
     394             : 
     395             : 
     396           0 :     bool DatabaseMetaData::displayEmptyTableFolders() const
     397             :     {
     398           0 :         bool doDisplay( true );
     399             : #ifdef IMPLEMENTED_LATER
     400             :         Any setting;
     401             :         if ( lcl_getConnectionSetting( "DisplayEmptyTableFolders", *m_pImpl, setting ) )
     402             :             OSL_VERIFY( setting >>= doDisplay );
     403             : #else
     404             :         try
     405             :         {
     406           0 :             Reference< XDatabaseMetaData > xMeta( m_pImpl->xConnectionMetaData, UNO_SET_THROW );
     407           0 :             OUString sConnectionURL( xMeta->getURL() );
     408           0 :             doDisplay = sConnectionURL.startsWith( "sdbc:mysql:mysqlc" );
     409             :         }
     410           0 :         catch( const Exception& )
     411             :         {
     412             :             DBG_UNHANDLED_EXCEPTION();
     413             :         }
     414             : #endif
     415           0 :         return doDisplay;
     416             :     }
     417             : 
     418           0 :     bool DatabaseMetaData::supportsThreads() const
     419             :     {
     420           0 :         bool bSupported( true );
     421             :         try
     422             :         {
     423           0 :             Reference< XDatabaseMetaData > xMeta( m_pImpl->xConnectionMetaData, UNO_SET_THROW );
     424           0 :             OUString sConnectionURL( xMeta->getURL() );
     425           0 :             bSupported = !sConnectionURL.startsWith( "sdbc:mysql:mysqlc" );
     426             :         }
     427           0 :         catch( const Exception& )
     428             :         {
     429             :             DBG_UNHANDLED_EXCEPTION();
     430             :         }
     431           0 :         return bSupported;
     432             :     }
     433             : 
     434             : 
     435             : } // namespace dbtools
     436             : 
     437             : 
     438             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10