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

Generated by: LCOV version 1.11