LCOV - code coverage report
Current view: top level - libreoffice/connectivity/source/drivers/hsqldb - HDriver.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 351 0.0 %
Date: 2012-12-27 Functions: 0 31 0.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             : #include "hsqldb/HDriver.hxx"
      21             : #include "hsqldb/HConnection.hxx"
      22             : #include <osl/diagnose.h>
      23             : #include "connectivity/dbexception.hxx"
      24             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      25             : #include <com/sun/star/sdbc/DriverManager.hpp>
      26             : #include <com/sun/star/sdbc/XDriverAccess.hpp>
      27             : #include <com/sun/star/sdbc/XResultSet.hpp>
      28             : #include <com/sun/star/sdbc/XRow.hpp>
      29             : #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
      30             : #include <com/sun/star/embed/ElementModes.hpp>
      31             : #include "TConnection.hxx"
      32             : #include "hsqldb/HStorageMap.hxx"
      33             : #include <jvmfwk/framework.h>
      34             : #include <com/sun/star/reflection/XProxyFactory.hpp>
      35             : #include <com/sun/star/embed/XStorage.hpp>
      36             : #include <com/sun/star/frame/Desktop.hpp>
      37             : #include <com/sun/star/lang/Locale.hpp>
      38             : #include <com/sun/star/util/XFlushable.hpp>
      39             : #include "HTerminateListener.hxx"
      40             : #include "hsqldb/HCatalog.hxx"
      41             : #include "diagnose_ex.h"
      42             : #include <rtl/ustrbuf.hxx>
      43             : #include <osl/file.h>
      44             : #include <osl/process.h>
      45             : #include <connectivity/dbexception.hxx>
      46             : #include <comphelper/namedvaluecollection.hxx>
      47             : #include <comphelper/processfactory.hxx>
      48             : #include <comphelper/string.hxx>
      49             : #include <unotools/confignode.hxx>
      50             : #include <unotools/ucbstreamhelper.hxx>
      51             : #include "resource/hsqldb_res.hrc"
      52             : #include "resource/sharedresources.hxx"
      53             : 
      54             : #include <o3tl/compat_functional.hxx>
      55             : 
      56             : //........................................................................
      57             : namespace connectivity
      58             : {
      59             : //........................................................................
      60             :     using namespace hsqldb;
      61             :     using namespace ::com::sun::star::uno;
      62             :     using namespace ::com::sun::star::sdbc;
      63             :     using namespace ::com::sun::star::sdbcx;
      64             :     using namespace ::com::sun::star::beans;
      65             :     using namespace ::com::sun::star::frame;
      66             :     using namespace ::com::sun::star::lang;
      67             :     using namespace ::com::sun::star::embed;
      68             :     using namespace ::com::sun::star::io;
      69             :     using namespace ::com::sun::star::task;
      70             :     using namespace ::com::sun::star::util;
      71             :     using namespace ::com::sun::star::reflection;
      72             : 
      73             :     namespace hsqldb
      74             :     {
      75           0 :         Reference< XInterface >  SAL_CALL ODriverDelegator_CreateInstance(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFac) throw( Exception )
      76             :         {
      77           0 :             return *(new ODriverDelegator(_rxFac));
      78             :         }
      79             :     }
      80             : 
      81             : 
      82             : 
      83             :     //====================================================================
      84             :     //= ODriverDelegator
      85             :     //====================================================================
      86             :     //--------------------------------------------------------------------
      87           0 :     ODriverDelegator::ODriverDelegator(const Reference< XMultiServiceFactory >& _rxFactory)
      88             :         : ODriverDelegator_BASE(m_aMutex)
      89             :         ,m_xFactory(_rxFactory)
      90           0 :         ,m_bInShutDownConnections(sal_False)
      91             :     {
      92           0 :     }
      93             : 
      94             :     //--------------------------------------------------------------------
      95           0 :     ODriverDelegator::~ODriverDelegator()
      96             :     {
      97             :         try
      98             :         {
      99           0 :             ::comphelper::disposeComponent(m_xDriver);
     100             :         }
     101           0 :         catch(const Exception&)
     102             :         {
     103             :         }
     104           0 :     }
     105             : 
     106             :     // --------------------------------------------------------------------------------
     107           0 :     void SAL_CALL ODriverDelegator::disposing()
     108             :     {
     109           0 :         ::osl::MutexGuard aGuard(m_aMutex);
     110             : 
     111             :         try
     112             :         {
     113           0 :             for (TWeakPairVector::iterator i = m_aConnections.begin(); m_aConnections.end() != i; ++i)
     114             :             {
     115           0 :                 Reference<XInterface > xTemp = i->first.get();
     116           0 :                 ::comphelper::disposeComponent(xTemp);
     117           0 :             }
     118             :         }
     119           0 :         catch(Exception&)
     120             :         {
     121             :             // not interested in
     122             :         }
     123           0 :         m_aConnections.clear();
     124           0 :         TWeakPairVector().swap(m_aConnections);
     125             : 
     126           0 :         cppu::WeakComponentImplHelperBase::disposing();
     127           0 :     }
     128             :     //--------------------------------------------------------------------
     129           0 :     Reference< XDriver > ODriverDelegator::loadDriver( )
     130             :     {
     131           0 :         if ( !m_xDriver.is() )
     132             :         {
     133           0 :             ::rtl::OUString sURL("jdbc:hsqldb:db");
     134           0 :             Reference<XDriverManager2> xDriverAccess = DriverManager::create( comphelper::getComponentContext(m_xFactory) );
     135           0 :             m_xDriver = xDriverAccess->getDriverByURL(sURL);
     136             :         }
     137             : 
     138           0 :         return m_xDriver;
     139             :     }
     140             : 
     141             :     //--------------------------------------------------------------------
     142             :     namespace
     143             :     {
     144           0 :         ::rtl::OUString lcl_getPermittedJavaMethods_nothrow( const Reference< XMultiServiceFactory >& _rxORB )
     145             :         {
     146           0 :             ::rtl::OUStringBuffer aConfigPath;
     147           0 :             aConfigPath.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" );
     148           0 :             aConfigPath.append     ( ODriverDelegator::getImplementationName_Static() );
     149           0 :             aConfigPath.appendAscii( "/PermittedJavaMethods" );
     150             :             ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
     151           0 :                 _rxORB, aConfigPath.makeStringAndClear() ) );
     152             : 
     153           0 :             ::rtl::OUStringBuffer aPermittedMethods;
     154           0 :             Sequence< ::rtl::OUString > aNodeNames( aConfig.getNodeNames() );
     155           0 :             for (   const ::rtl::OUString* pNodeNames = aNodeNames.getConstArray();
     156           0 :                     pNodeNames != aNodeNames.getConstArray() + aNodeNames.getLength();
     157             :                     ++pNodeNames
     158             :                 )
     159             :             {
     160           0 :                 ::rtl::OUString sPermittedMethod;
     161           0 :                 OSL_VERIFY( aConfig.getNodeValue( *pNodeNames ) >>= sPermittedMethod );
     162             : 
     163           0 :                 if ( aPermittedMethods.getLength() )
     164           0 :                     aPermittedMethods.append( (sal_Unicode)';' );
     165           0 :                 aPermittedMethods.append( sPermittedMethod );
     166           0 :             }
     167             : 
     168           0 :             return aPermittedMethods.makeStringAndClear();
     169             :         }
     170             :     }
     171             : 
     172             :     //--------------------------------------------------------------------
     173           0 :     Reference< XConnection > SAL_CALL ODriverDelegator::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
     174             :     {
     175           0 :         Reference< XConnection > xConnection;
     176           0 :         if ( acceptsURL(url) )
     177             :         {
     178           0 :             Reference< XDriver > xDriver = loadDriver();
     179           0 :             if ( xDriver.is() )
     180             :             {
     181           0 :                 ::rtl::OUString sURL;
     182           0 :                 Reference<XStorage> xStorage;
     183           0 :                 const PropertyValue* pIter = info.getConstArray();
     184           0 :                 const PropertyValue* pEnd = pIter + info.getLength();
     185             : 
     186           0 :                 for (;pIter != pEnd; ++pIter)
     187             :                 {
     188           0 :                     if ( pIter->Name == "Storage" )
     189             :                     {
     190           0 :                         xStorage.set(pIter->Value,UNO_QUERY);
     191             :                     }
     192           0 :                     else if ( pIter->Name == "URL" )
     193             :                     {
     194           0 :                         pIter->Value >>= sURL;
     195             :                     }
     196             :                 }
     197             : 
     198           0 :                 if ( !xStorage.is() || sURL.isEmpty() )
     199             :                 {
     200           0 :                     ::connectivity::SharedResources aResources;
     201           0 :                     const ::rtl::OUString sMessage = aResources.getResourceString(STR_NO_STROAGE);
     202           0 :                     ::dbtools::throwGenericSQLException(sMessage ,*this);
     203             :                 }
     204             : 
     205           0 :                 ::rtl::OUString sSystemPath;
     206           0 :                 osl_getSystemPathFromFileURL( sURL.pData, &sSystemPath.pData );
     207           0 :                 sal_Int32 nIndex = sSystemPath.lastIndexOf('.');
     208           0 :                 if ( sURL.isEmpty() || sSystemPath.isEmpty() )
     209             :                 {
     210           0 :                     ::connectivity::SharedResources aResources;
     211           0 :                     const ::rtl::OUString sMessage = aResources.getResourceString(STR_INVALID_FILE_URL);
     212           0 :                     ::dbtools::throwGenericSQLException(sMessage ,*this);
     213             :                 }
     214             : 
     215           0 :                 bool bIsNewDatabase = !xStorage->hasElements();
     216             : 
     217           0 :                 ::comphelper::NamedValueCollection aProperties;
     218             : 
     219             :                 // properties for accessing the embedded storage
     220           0 :                 ::rtl::OUString sConnPartURL = sSystemPath.copy( 0, ::std::max< sal_Int32 >( nIndex, sSystemPath.getLength() ) );
     221           0 :                 ::rtl::OUString sKey = StorageContainer::registerStorage( xStorage, sConnPartURL );
     222           0 :                 aProperties.put( "storage_key", sKey );
     223             :                 aProperties.put( "storage_class_name",
     224           0 :                     ::rtl::OUString(  "com.sun.star.sdbcx.comp.hsqldb.StorageAccess"  ) );
     225             :                 aProperties.put( "fileaccess_class_name",
     226           0 :                     ::rtl::OUString(  "com.sun.star.sdbcx.comp.hsqldb.StorageFileAccess"  ) );
     227             : 
     228             :                 // JDBC driver and driver's classpath
     229             :                 aProperties.put( "JavaDriverClass",
     230           0 :                     ::rtl::OUString(  "org.hsqldb.jdbcDriver"  ) );
     231             :                 aProperties.put( "JavaDriverClassPath",
     232             :                     ::rtl::OUString(
     233             : #ifdef SYSTEM_HSQLDB
     234             :                         HSQLDB_JAR
     235             :                         " vnd.sun.star.expand:$BRAND_BASE_DIR/program/classes/sdbc_hsqldb.jar"
     236             : #else
     237             :                         "vnd.sun.star.expand:$BRAND_BASE_DIR/program/classes/hsqldb.jar"
     238             :                         " vnd.sun.star.expand:$BRAND_BASE_DIR/program/classes/sdbc_hsqldb.jar"
     239             : #endif
     240           0 :                         ) );
     241             : 
     242             :                 // auto increment handling
     243           0 :                 aProperties.put( "IsAutoRetrievingEnabled", true );
     244             :                 aProperties.put( "AutoRetrievingStatement",
     245           0 :                     ::rtl::OUString(  "CALL IDENTITY()" ) );
     246           0 :                 aProperties.put( "IgnoreDriverPrivileges", true );
     247             : 
     248             :                 // don't want to expose HSQLDB's schema capabilities which exist since 1.8.0RC10
     249             :                 aProperties.put( "default_schema",
     250           0 :                     ::rtl::OUString(  "true"  ) );
     251             : 
     252             :                 // security: permitted Java classes
     253             :                 NamedValue aPermittedClasses(
     254             :                     ::rtl::OUString(  "hsqldb.method_class_names"  ),
     255             :                     makeAny( lcl_getPermittedJavaMethods_nothrow( m_xFactory ) )
     256           0 :                 );
     257           0 :                 aProperties.put( "SystemProperties", Sequence< NamedValue >( &aPermittedClasses, 1 ) );
     258             : 
     259           0 :                 const ::rtl::OUString sProperties(  "properties"  );
     260           0 :                 ::rtl::OUString sMessage;
     261             :                 try
     262             :                 {
     263           0 :                     if ( !bIsNewDatabase && xStorage->isStreamElement(sProperties) )
     264             :                     {
     265           0 :                         Reference<XStream > xStream = xStorage->openStreamElement(sProperties,ElementModes::READ);
     266           0 :                         if ( xStream.is() )
     267             :                         {
     268           0 :                             ::std::auto_ptr<SvStream> pStream( ::utl::UcbStreamHelper::CreateStream(xStream) );
     269           0 :                             if ( pStream.get() )
     270             :                             {
     271           0 :                                 rtl::OString sLine;
     272           0 :                                 rtl::OString sVersionString;
     273           0 :                                 while ( pStream->ReadLine(sLine) )
     274             :                                 {
     275           0 :                                     if ( sLine.getLength() == 0 )
     276           0 :                                         continue;
     277           0 :                                     const rtl::OString sIniKey = comphelper::string::getToken(sLine, 0, '=');
     278           0 :                                     const rtl::OString sValue = comphelper::string::getToken(sLine, 1, '=');
     279           0 :                                     if (sIniKey.equalsL(RTL_CONSTASCII_STRINGPARAM("hsqldb.compatible_version")))
     280             :                                     {
     281           0 :                                         sVersionString = sValue;
     282             :                                     }
     283             :                                     else
     284             :                                     {
     285           0 :                                         if (sIniKey.equalsL(RTL_CONSTASCII_STRINGPARAM("version"))
     286           0 :                                             &&  ( sVersionString.isEmpty() )
     287             :                                             )
     288             :                                         {
     289           0 :                                             sVersionString = sValue;
     290             :                                         }
     291             :                                     }
     292           0 :                                 }
     293           0 :                                 if (!sVersionString.isEmpty())
     294             :                                 {
     295             :                                     using comphelper::string::getToken;
     296           0 :                                     const sal_Int32 nMajor = getToken(sVersionString, 0, '.').toInt32();
     297           0 :                                     const sal_Int32 nMinor = getToken(sVersionString, 1, '.').toInt32();
     298           0 :                                     const sal_Int32 nMicro = getToken(sVersionString, 2, '.').toInt32();
     299           0 :                                     if (     nMajor > 1
     300             :                                         || ( nMajor == 1 && nMinor > 8 )
     301             :                                         || ( nMajor == 1 && nMinor == 8 && nMicro > 0 ) )
     302             :                                     {
     303           0 :                                         ::connectivity::SharedResources aResources;
     304           0 :                                         sMessage = aResources.getResourceString(STR_ERROR_NEW_VERSION);
     305             :                                     }
     306           0 :                                 }
     307           0 :                             }
     308             :                         } // if ( xStream.is() )
     309           0 :                         ::comphelper::disposeComponent(xStream);
     310             :                     }
     311             :                 }
     312           0 :                 catch(Exception&)
     313             :                 {
     314             :                 }
     315           0 :                 if ( !sMessage.isEmpty() )
     316             :                 {
     317           0 :                     ::dbtools::throwGenericSQLException(sMessage ,*this);
     318             :                 }
     319             : 
     320             :                 // readonly?
     321           0 :                 Reference<XPropertySet> xProp(xStorage,UNO_QUERY);
     322           0 :                 if ( xProp.is() )
     323             :                 {
     324           0 :                     sal_Int32 nMode = 0;
     325           0 :                     xProp->getPropertyValue(::rtl::OUString("OpenMode")) >>= nMode;
     326           0 :                     if ( (nMode & ElementModes::WRITE) != ElementModes::WRITE )
     327             :                     {
     328           0 :                         aProperties.put( "readonly", ::rtl::OUString(  "true"  ) );
     329             :                     }
     330             :                 }
     331             : 
     332           0 :                 Sequence< PropertyValue > aConnectionArgs;
     333           0 :                 aProperties >>= aConnectionArgs;
     334             : 
     335           0 :                 ::rtl::OUString sConnectURL("jdbc:hsqldb:");
     336             : 
     337           0 :                 sConnectURL += sConnPartURL;
     338           0 :                 Reference<XConnection> xOrig;
     339             :                 try
     340             :                 {
     341           0 :                     xOrig = xDriver->connect( sConnectURL, aConnectionArgs );
     342             :                 }
     343           0 :                 catch(const Exception& e)
     344             :                 {
     345           0 :                     StorageContainer::revokeStorage(sKey,NULL);
     346             :                     (void)e;
     347           0 :                     throw;
     348             :                 }
     349             : 
     350             :                 // if the storage is completely empty, then we just created a new HSQLDB
     351             :                 // In this case, do some initializations.
     352           0 :                 if ( bIsNewDatabase && xOrig.is() )
     353           0 :                     onConnectedNewDatabase( xOrig );
     354             : 
     355           0 :                 if ( xOrig.is() )
     356             :                 {
     357           0 :                     OMetaConnection* pMetaConnection = NULL;
     358             :                     // now we have to set the URL to get the correct answer for metadata()->getURL()
     359           0 :                     Reference< XUnoTunnel> xTunnel(xOrig,UNO_QUERY);
     360           0 :                     if ( xTunnel.is() )
     361             :                     {
     362           0 :                         pMetaConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
     363           0 :                         if ( pMetaConnection )
     364           0 :                             pMetaConnection->setURL(url);
     365             :                     }
     366             : 
     367           0 :                     Reference<XComponent> xComp(xOrig,UNO_QUERY);
     368           0 :                     if ( xComp.is() )
     369           0 :                         xComp->addEventListener(this);
     370             : 
     371             :                     // we want to close all connections when the office shuts down
     372           0 :                     static Reference< XTerminateListener> s_xTerminateListener;
     373           0 :                     if( !s_xTerminateListener.is() )
     374             :                     {
     375           0 :                         Reference< XDesktop2 > xDesktop = Desktop::create( comphelper::getComponentContext(m_xFactory) );
     376             : 
     377           0 :                         s_xTerminateListener = new OConnectionController(this);
     378           0 :                         xDesktop->addTerminateListener(s_xTerminateListener);
     379             :                     }
     380           0 :                     Reference< XComponent> xIfc = new OHsqlConnection( this, xOrig, comphelper::getComponentContext(m_xFactory) );
     381           0 :                     xConnection.set(xIfc,UNO_QUERY);
     382           0 :                     m_aConnections.push_back(TWeakPair(WeakReferenceHelper(xOrig),TWeakConnectionPair(sKey,TWeakRefPair(WeakReferenceHelper(xConnection),WeakReferenceHelper()))));
     383             : 
     384           0 :                     Reference<XTransactionBroadcaster> xBroad(xStorage,UNO_QUERY);
     385           0 :                     if ( xBroad.is() )
     386             :                     {
     387           0 :                         Reference<XTransactionListener> xListener(*this,UNO_QUERY);
     388           0 :                         xBroad->addTransactionListener(xListener);
     389           0 :                     }
     390           0 :                 }
     391           0 :             }
     392             :         }
     393           0 :         return xConnection;
     394             :     }
     395             : 
     396             :     //--------------------------------------------------------------------
     397           0 :     sal_Bool SAL_CALL ODriverDelegator::acceptsURL( const ::rtl::OUString& url ) throw (SQLException, RuntimeException)
     398             :     {
     399           0 :         sal_Bool bEnabled = sal_False;
     400           0 :         OSL_VERIFY_EQUALS( jfw_getEnabled( &bEnabled ), JFW_E_NONE, "error in jfw_getEnabled" );
     401           0 :         return bEnabled  && url.compareToAscii("sdbc:embedded:hsqldb",sizeof("sdbc:embedded:hsqldb")) == 0;
     402             :     }
     403             : 
     404             :     //--------------------------------------------------------------------
     405           0 :     Sequence< DriverPropertyInfo > SAL_CALL ODriverDelegator::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, RuntimeException)
     406             :     {
     407           0 :         if ( !acceptsURL(url) )
     408           0 :             return Sequence< DriverPropertyInfo >();
     409           0 :         ::std::vector< DriverPropertyInfo > aDriverInfo;
     410             :         aDriverInfo.push_back(DriverPropertyInfo(
     411             :                 ::rtl::OUString("Storage")
     412             :                 ,::rtl::OUString("Defines the storage where the database will be stored.")
     413             :                 ,sal_True
     414             :                 ,::rtl::OUString()
     415             :                 ,Sequence< ::rtl::OUString >())
     416           0 :                 );
     417             :         aDriverInfo.push_back(DriverPropertyInfo(
     418             :                 ::rtl::OUString("URL")
     419             :                 ,::rtl::OUString("Defines the url of the data source.")
     420             :                 ,sal_True
     421             :                 ,::rtl::OUString()
     422             :                 ,Sequence< ::rtl::OUString >())
     423           0 :                 );
     424             :         aDriverInfo.push_back(DriverPropertyInfo(
     425             :                 ::rtl::OUString("AutoRetrievingStatement")
     426             :                 ,::rtl::OUString("Defines the statement which will be executed to retrieve auto increment values.")
     427             :                 ,sal_False
     428             :                 ,::rtl::OUString("CALL IDENTITY()")
     429             :                 ,Sequence< ::rtl::OUString >())
     430           0 :                 );
     431           0 :         return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
     432             :     }
     433             : 
     434             :     //--------------------------------------------------------------------
     435           0 :     sal_Int32 SAL_CALL ODriverDelegator::getMajorVersion(  ) throw (RuntimeException)
     436             :     {
     437           0 :         return 1;
     438             :     }
     439             : 
     440             :     //--------------------------------------------------------------------
     441           0 :     sal_Int32 SAL_CALL ODriverDelegator::getMinorVersion(  ) throw (RuntimeException)
     442             :     {
     443           0 :         return 0;
     444             :     }
     445             : 
     446             :     //--------------------------------------------------------------------
     447           0 :     Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByConnection( const Reference< XConnection >& connection ) throw (SQLException, RuntimeException)
     448             :     {
     449           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     450           0 :         checkDisposed(ODriverDelegator_BASE::rBHelper.bDisposed);
     451             : 
     452           0 :         Reference< XTablesSupplier > xTab;
     453             : 
     454           0 :         TWeakPairVector::iterator aEnd = m_aConnections.end();
     455           0 :         for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
     456             :         {
     457           0 :             if ( i->second.second.first.get() == connection.get() )
     458             :             {
     459           0 :                 xTab = Reference< XTablesSupplier >(i->second.second.second.get().get(),UNO_QUERY);
     460           0 :                 if ( !xTab.is() )
     461             :                 {
     462           0 :                     xTab = new OHCatalog(connection);
     463           0 :                     i->second.second.second = WeakReferenceHelper(xTab);
     464             :                 }
     465           0 :                 break;
     466             :             }
     467             :         }
     468             : 
     469           0 :         return xTab;
     470             :     }
     471             : 
     472             :     //--------------------------------------------------------------------
     473           0 :     Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByURL( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
     474             :     {
     475           0 :         if ( ! acceptsURL(url) )
     476             :         {
     477           0 :             ::connectivity::SharedResources aResources;
     478           0 :             const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
     479           0 :             ::dbtools::throwGenericSQLException(sMessage ,*this);
     480             :         }
     481             : 
     482           0 :         return getDataDefinitionByConnection(connect(url,info));
     483             :     }
     484             : 
     485             :     // XServiceInfo
     486             :     // --------------------------------------------------------------------------------
     487             :     //------------------------------------------------------------------------------
     488           0 :     rtl::OUString ODriverDelegator::getImplementationName_Static(  ) throw(RuntimeException)
     489             :     {
     490           0 :         return rtl::OUString("com.sun.star.sdbcx.comp.hsqldb.Driver");
     491             :     }
     492             :     //------------------------------------------------------------------------------
     493           0 :     Sequence< ::rtl::OUString > ODriverDelegator::getSupportedServiceNames_Static(  ) throw (RuntimeException)
     494             :     {
     495           0 :         Sequence< ::rtl::OUString > aSNS( 2 );
     496           0 :         aSNS[0] = ::rtl::OUString("com.sun.star.sdbc.Driver");
     497           0 :         aSNS[1] = ::rtl::OUString("com.sun.star.sdbcx.Driver");
     498           0 :         return aSNS;
     499             :     }
     500             :     //------------------------------------------------------------------
     501           0 :     ::rtl::OUString SAL_CALL ODriverDelegator::getImplementationName(  ) throw(RuntimeException)
     502             :     {
     503           0 :         return getImplementationName_Static();
     504             :     }
     505             : 
     506             :     //------------------------------------------------------------------
     507           0 :     sal_Bool SAL_CALL ODriverDelegator::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
     508             :     {
     509           0 :         Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
     510           0 :         const ::rtl::OUString* pSupported = aSupported.getConstArray();
     511           0 :         const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
     512           0 :         for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
     513             :             ;
     514             : 
     515           0 :         return pSupported != pEnd;
     516             :     }
     517             :     //------------------------------------------------------------------
     518           0 :     Sequence< ::rtl::OUString > SAL_CALL ODriverDelegator::getSupportedServiceNames(  ) throw(RuntimeException)
     519             :     {
     520           0 :         return getSupportedServiceNames_Static();
     521             :     }
     522             :     //------------------------------------------------------------------
     523           0 :     void SAL_CALL ODriverDelegator::createCatalog( const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, ::com::sun::star::container::ElementExistException, RuntimeException)
     524             :     {
     525           0 :         ::dbtools::throwFeatureNotImplementedException( "XCreateCatalog::createCatalog", *this );
     526           0 :     }
     527             :     //------------------------------------------------------------------
     528           0 :     void ODriverDelegator::shutdownConnection(const TWeakPairVector::iterator& _aIter )
     529             :     {
     530             :         OSL_ENSURE(m_aConnections.end() != _aIter,"Iterator equals .end()");
     531           0 :         sal_Bool bLastOne = sal_True;
     532             :         try
     533             :         {
     534           0 :             Reference<XConnection> _xConnection(_aIter->first.get(),UNO_QUERY);
     535             : 
     536           0 :             if ( _xConnection.is() )
     537             :             {
     538           0 :                 Reference<XStatement> xStmt = _xConnection->createStatement();
     539           0 :                 if ( xStmt.is() )
     540             :                 {
     541           0 :                     Reference<XResultSet> xRes(xStmt->executeQuery(::rtl::OUString("SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS WHERE USER_NAME ='SA'")),UNO_QUERY);
     542           0 :                     Reference<XRow> xRow(xRes,UNO_QUERY);
     543           0 :                     if ( xRow.is() && xRes->next() )
     544           0 :                         bLastOne = xRow->getInt(1) == 1;
     545           0 :                     if ( bLastOne )
     546           0 :                         xStmt->execute(::rtl::OUString("SHUTDOWN"));
     547           0 :                 }
     548           0 :             }
     549             :         }
     550           0 :         catch(Exception&)
     551             :         {
     552             :         }
     553           0 :         if ( bLastOne )
     554             :         {
     555             :             // Reference<XTransactionListener> xListener(*this,UNO_QUERY);
     556             :             // a shutdown should commit all changes to the db files
     557           0 :             StorageContainer::revokeStorage(_aIter->second.first,NULL);
     558             :         }
     559           0 :         if ( !m_bInShutDownConnections )
     560           0 :             m_aConnections.erase(_aIter);
     561           0 :     }
     562             :     //------------------------------------------------------------------
     563           0 :     void SAL_CALL ODriverDelegator::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException)
     564             :     {
     565           0 :         ::osl::MutexGuard aGuard(m_aMutex);
     566           0 :         Reference<XConnection> xCon(Source.Source,UNO_QUERY);
     567           0 :         if ( xCon.is() )
     568             :         {
     569           0 :             TWeakPairVector::iterator i = m_aConnections.begin();
     570           0 :             for (; m_aConnections.end() != i; ++i)
     571             :             {
     572           0 :                 if ( i->first.get() == xCon.get() )
     573             :                 {
     574           0 :                     shutdownConnection(i);
     575           0 :                     break;
     576             :                 }
     577             :             }
     578             :         }
     579             :         else
     580             :         {
     581           0 :             Reference< XStorage> xStorage(Source.Source,UNO_QUERY);
     582           0 :             if ( xStorage.is() )
     583             :             {
     584           0 :                 ::rtl::OUString sKey = StorageContainer::getRegisteredKey(xStorage);
     585             :                 TWeakPairVector::iterator i = ::std::find_if(m_aConnections.begin(),m_aConnections.end(),::o3tl::compose1(
     586             :                                 ::std::bind2nd(::std::equal_to< ::rtl::OUString >(),sKey)
     587           0 :                                 ,::o3tl::compose1(::o3tl::select1st<TWeakConnectionPair>(),::o3tl::select2nd< TWeakPair >())));
     588           0 :                 if ( i != m_aConnections.end() )
     589           0 :                     shutdownConnection(i);
     590           0 :             }
     591           0 :         }
     592           0 :     }
     593             :     //------------------------------------------------------------------
     594           0 :     void ODriverDelegator::shutdownConnections()
     595             :     {
     596           0 :         m_bInShutDownConnections = sal_True;
     597           0 :         TWeakPairVector::iterator aEnd = m_aConnections.end();
     598           0 :         for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
     599             :         {
     600             :             try
     601             :             {
     602           0 :                 Reference<XConnection> xCon(i->first,UNO_QUERY);
     603           0 :                 ::comphelper::disposeComponent(xCon);
     604             :             }
     605           0 :             catch(Exception&)
     606             :             {
     607             :             }
     608             :         }
     609           0 :         m_aConnections.clear();
     610           0 :         m_bInShutDownConnections = sal_True;
     611           0 :     }
     612             :     //------------------------------------------------------------------
     613           0 :     void ODriverDelegator::flushConnections()
     614             :     {
     615           0 :         TWeakPairVector::iterator aEnd = m_aConnections.end();
     616           0 :         for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
     617             :         {
     618             :             try
     619             :             {
     620           0 :                 Reference<XFlushable> xCon(i->second.second.first.get(),UNO_QUERY);
     621           0 :                 xCon->flush();
     622             :             }
     623           0 :             catch(Exception&)
     624             :             {
     625             :             }
     626             :         }
     627           0 :     }
     628             :     //------------------------------------------------------------------
     629           0 :     void SAL_CALL ODriverDelegator::preCommit( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
     630             :     {
     631           0 :         ::osl::MutexGuard aGuard(m_aMutex);
     632             : 
     633           0 :         Reference< XStorage> xStorage(aEvent.Source,UNO_QUERY);
     634           0 :         ::rtl::OUString sKey = StorageContainer::getRegisteredKey(xStorage);
     635           0 :         if ( !sKey.isEmpty() )
     636             :         {
     637             :             TWeakPairVector::iterator i = ::std::find_if(m_aConnections.begin(),m_aConnections.end(),::o3tl::compose1(
     638             :                             ::std::bind2nd(::std::equal_to< ::rtl::OUString >(),sKey)
     639           0 :                             ,::o3tl::compose1(::o3tl::select1st<TWeakConnectionPair>(),::o3tl::select2nd< TWeakPair >())));
     640             :             OSL_ENSURE( i != m_aConnections.end(), "ODriverDelegator::preCommit: they're committing a storage which I do not know!" );
     641           0 :             if ( i != m_aConnections.end() )
     642             :             {
     643             :                 try
     644             :                 {
     645           0 :                     Reference<XConnection> xConnection(i->first,UNO_QUERY);
     646           0 :                     if ( xConnection.is() )
     647             :                     {
     648           0 :                         Reference< XStatement> xStmt = xConnection->createStatement();
     649             :                         OSL_ENSURE( xStmt.is(), "ODriverDelegator::preCommit: no statement!" );
     650           0 :                         if ( xStmt.is() )
     651           0 :                             xStmt->execute( ::rtl::OUString(  "SET WRITE_DELAY 0"  ) );
     652             : 
     653           0 :                         sal_Bool bPreviousAutoCommit = xConnection->getAutoCommit();
     654           0 :                         xConnection->setAutoCommit( sal_False );
     655           0 :                         xConnection->commit();
     656           0 :                         xConnection->setAutoCommit( bPreviousAutoCommit );
     657             : 
     658           0 :                         if ( xStmt.is() )
     659           0 :                             xStmt->execute( ::rtl::OUString(  "SET WRITE_DELAY 60"  ) );
     660           0 :                     }
     661             :                 }
     662           0 :                 catch(Exception&)
     663             :                 {
     664             :                     OSL_FAIL( "ODriverDelegator::preCommit: caught an exception!" );
     665             :                 }
     666             :             }
     667           0 :         }
     668           0 :     }
     669             :     //------------------------------------------------------------------
     670           0 :     void SAL_CALL ODriverDelegator::commited( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
     671             :     {
     672           0 :     }
     673             :     //------------------------------------------------------------------
     674           0 :     void SAL_CALL ODriverDelegator::preRevert( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
     675             :     {
     676           0 :     }
     677             :     //------------------------------------------------------------------
     678           0 :     void SAL_CALL ODriverDelegator::reverted( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
     679             :     {
     680           0 :     }
     681             :     //------------------------------------------------------------------
     682             :     namespace
     683             :     {
     684             :         //..............................................................
     685           0 :         const sal_Char* lcl_getCollationForLocale( const ::rtl::OUString& _rLocaleString, bool _bAcceptCountryMismatch = false )
     686             :         {
     687             :             static const sal_Char* pTranslations[] =
     688             :             {
     689             :                 "af-ZA", "Afrikaans",
     690             :                 "am-ET", "Amharic",
     691             :                 "ar", "Arabic",
     692             :                 "as-IN", "Assamese",
     693             :                 "az-AZ", "Azerbaijani_Latin",
     694             :                 "az-cyrillic", "Azerbaijani_Cyrillic",
     695             :                 "be-BY", "Belarusian",
     696             :                 "bg-BG", "Bulgarian",
     697             :                 "bn-IN", "Bengali",
     698             :                 "bo-CN", "Tibetan",
     699             :                 "bs-BA", "Bosnian",
     700             :                 "ca-ES", "Catalan",
     701             :                 "cs-CZ", "Czech",
     702             :                 "cy-GB", "Welsh",
     703             :                 "da-DK", "Danish",
     704             :                 "de-DE", "German",
     705             :                 "el-GR", "Greek",
     706             :                 "en-US", "Latin1_General",
     707             :                 "es-ES", "Spanish",
     708             :                 "et-EE", "Estonian",
     709             :                 "eu", "Basque",
     710             :                 "fi-FI", "Finnish",
     711             :                 "fr-FR", "French",
     712             :                 "gn-PY", "Guarani",
     713             :                 "gu-IN", "Gujarati",
     714             :                 "ha-NG", "Hausa",
     715             :                 "he-IL", "Hebrew",
     716             :                 "hi-IN", "Hindi",
     717             :                 "hr-HR", "Croatian",
     718             :                 "hu-HU", "Hungarian",
     719             :                 "hy-AM", "Armenian",
     720             :                 "id-ID", "Indonesian",
     721             :                 "ig-NG", "Igbo",
     722             :                 "is-IS", "Icelandic",
     723             :                 "it-IT", "Italian",
     724             :                 "iu-CA", "Inuktitut",
     725             :                 "ja-JP", "Japanese",
     726             :                 "ka-GE", "Georgian",
     727             :                 "kk-KZ", "Kazakh",
     728             :                 "km-KH", "Khmer",
     729             :                 "kn-IN", "Kannada",
     730             :                 "ko-KR", "Korean",
     731             :                 "kok-IN", "Konkani",
     732             :                 "ks", "Kashmiri",
     733             :                 "ky-KG", "Kirghiz",
     734             :                 "lo-LA", "Lao",
     735             :                 "lt-LT", "Lithuanian",
     736             :                 "lv-LV", "Latvian",
     737             :                 "mi-NZ", "Maori",
     738             :                 "mk-MK", "Macedonian",
     739             :                 "ml-IN", "Malayalam",
     740             :                 "mn-MN", "Mongolian",
     741             :                 "mni-IN", "Manipuri",
     742             :                 "mr-IN", "Marathi",
     743             :                 "ms-MY", "Malay",
     744             :                 "mt-MT", "Maltese",
     745             :                 "my-MM", "Burmese",
     746             :                 "nb-NO", "Danish_Norwegian",
     747             :                 "ne-NP", "Nepali",
     748             :                 "nl-NL", "Dutch",
     749             :                 "nn-NO", "Norwegian",
     750             :                 "or-IN", "Oriya",
     751             :                 "pa-IN", "Punjabi",
     752             :                 "pl-PL", "Polish",
     753             :                 "ps-AF", "Pashto",
     754             :                 "pt-PT", "Portuguese",
     755             :                 "ro-RO", "Romanian",
     756             :                 "ru-RU", "Russian",
     757             :                 "sa-IN", "Sanskrit",
     758             :                 "sd-IN", "Sindhi",
     759             :                 "sk-SK", "Slovak",
     760             :                 "sl-SI", "Slovenian",
     761             :                 "so-SO", "Somali",
     762             :                 "sq-AL", "Albanian",
     763             :                 "sr-YU", "Serbian_Cyrillic",
     764             :                 "sv-SE", "Swedish",
     765             :                 "sw-KE", "Swahili",
     766             :                 "ta-IN", "Tamil",
     767             :                 "te-IN", "Telugu",
     768             :                 "tg-TJ", "Tajik",
     769             :                 "th-TH", "Thai",
     770             :                 "tk-TM", "Turkmen",
     771             :                 "tn-BW", "Tswana",
     772             :                 "tr-TR", "Turkish",
     773             :                 "tt-RU", "Tatar",
     774             :                 "uk-UA", "Ukrainian",
     775             :                 "ur-PK", "Urdu",
     776             :                 "uz-UZ", "Uzbek_Latin",
     777             :                 "ven-ZA", "Venda",
     778             :                 "vi-VN", "Vietnamese",
     779             :                 "yo-NG", "Yoruba",
     780             :                 "zh-CN", "Chinese",
     781             :                 "zu-ZA", "Zulu",
     782             :                 NULL, NULL
     783             :             };
     784             : 
     785           0 :             ::rtl::OUString sLocaleString( _rLocaleString );
     786           0 :             sal_Char nCompareTermination = 0;
     787             : 
     788           0 :             if ( _bAcceptCountryMismatch )
     789             :             {
     790             :                 // strip the country part from the compare string
     791           0 :                 sal_Int32 nCountrySep = sLocaleString.indexOf( '-' );
     792           0 :                 if ( nCountrySep > -1 )
     793           0 :                     sLocaleString = sLocaleString.copy( 0, nCountrySep );
     794             : 
     795             :                 // the entries in the translation table are compared until the
     796             :                 // - character only, not until the terminating 0
     797           0 :                 nCompareTermination = '-';
     798             :             }
     799             : 
     800           0 :             const sal_Char** pLookup = pTranslations;
     801           0 :             for ( ; *pLookup; pLookup +=2 )
     802             :             {
     803           0 :                 sal_Int32 nCompareUntil = 0;
     804           0 :                 while ( (*pLookup)[ nCompareUntil ] != nCompareTermination && (*pLookup)[ nCompareUntil ] != 0 )
     805           0 :                     ++nCompareUntil;
     806             : 
     807           0 :                 if ( sLocaleString.equalsAsciiL( *pLookup, nCompareUntil ) )
     808           0 :                     return *( pLookup + 1 );
     809             :             }
     810             : 
     811           0 :             if ( !_bAcceptCountryMismatch )
     812             :                 // second round, this time without matching the country
     813           0 :                 return lcl_getCollationForLocale( _rLocaleString, true );
     814             : 
     815             :             OSL_FAIL( "lcl_getCollationForLocale: unknown locale string, falling back to Latin1_General!" );
     816           0 :             return "Latin1_General";
     817             :         }
     818             : 
     819             :         //..............................................................
     820           0 :         ::rtl::OUString lcl_getSystemLocale( const Reference< XMultiServiceFactory >& _rxORB )
     821             :         {
     822           0 :             ::rtl::OUString sLocaleString = ::rtl::OUString(  "en-US"  );
     823             :             try
     824             :             {
     825             :                 //.........................................................
     826             :                 Reference< XMultiServiceFactory > xConfigProvider(
     827             :                     com::sun::star::configuration::theDefaultProvider::get(
     828           0 :                         comphelper::getComponentContext( _rxORB ) ) );
     829             : 
     830             :                 //.........................................................
     831             :                 // arguments for creating the config access
     832           0 :                 Sequence< Any > aArguments(2);
     833             :                 // the path to the node to open
     834           0 :                 ::rtl::OUString sNodePath("/org.openoffice.Setup/L10N" );
     835           0 :                 aArguments[0] <<= PropertyValue( ::rtl::OUString("nodepath"), 0,
     836             :                     makeAny( sNodePath ), PropertyState_DIRECT_VALUE
     837           0 :                 );
     838             :                 // the depth: -1 means unlimited
     839           0 :                 aArguments[1] <<= PropertyValue(
     840             :                     ::rtl::OUString("depth"), 0,
     841             :                     makeAny( (sal_Int32)-1 ), PropertyState_DIRECT_VALUE
     842           0 :                 );
     843             : 
     844             :                 //.........................................................
     845             :                 // create the access
     846             :                 Reference< XPropertySet > xNode(
     847           0 :                     xConfigProvider->createInstanceWithArguments(
     848             :                         ::rtl::OUString("com.sun.star.configuration.ConfigurationAccess"),
     849           0 :                         aArguments ),
     850           0 :                     UNO_QUERY );
     851             :                 OSL_ENSURE( xNode.is(), "lcl_getSystemLocale: invalid access returned (should throw an exception instead)!" );
     852             : 
     853             :                 //.........................................................
     854             :                 // ask for the system locale setting
     855           0 :                 if ( xNode.is() )
     856           0 :                     xNode->getPropertyValue( ::rtl::OUString(  "ooSetupSystemLocale"  ) ) >>= sLocaleString;
     857             :             }
     858           0 :             catch( const Exception& )
     859             :             {
     860             :                 OSL_FAIL( "lcl_getSystemLocale: caught an exception!" );
     861             :             }
     862           0 :             if ( sLocaleString.isEmpty() )
     863             :             {
     864           0 :                 rtl_Locale* pProcessLocale = NULL;
     865           0 :                 osl_getProcessLocale( &pProcessLocale );
     866             : 
     867           0 :                 ::rtl::OUStringBuffer aProcLocale;
     868           0 :                 aProcLocale.append( pProcessLocale->Language->buffer, pProcessLocale->Language->length );
     869           0 :                 if ( pProcessLocale->Country->length )
     870             :                 {
     871           0 :                     aProcLocale.appendAscii( "-" );
     872           0 :                     aProcLocale.append( pProcessLocale->Country->buffer, pProcessLocale->Country->length );
     873             :                 }
     874           0 :                 sLocaleString = aProcLocale.makeStringAndClear();
     875             :             }
     876           0 :             return sLocaleString;
     877             :         }
     878             :     }
     879             :     //------------------------------------------------------------------
     880           0 :     void ODriverDelegator::onConnectedNewDatabase( const Reference< XConnection >& _rxConnection )
     881             :     {
     882             :         try
     883             :         {
     884           0 :             Reference< XStatement > xStatement = _rxConnection->createStatement();
     885             :             OSL_ENSURE( xStatement.is(), "ODriverDelegator::onConnectedNewDatabase: could not create a statement!" );
     886           0 :             if ( xStatement.is() )
     887             :             {
     888           0 :                 ::rtl::OUStringBuffer aStatement;
     889           0 :                 aStatement.appendAscii( "SET DATABASE COLLATION \"" );
     890           0 :                 aStatement.appendAscii( lcl_getCollationForLocale( lcl_getSystemLocale( m_xFactory ) ) );
     891           0 :                 aStatement.appendAscii( "\"" );
     892             : 
     893           0 :                 xStatement->execute( aStatement.makeStringAndClear() );
     894           0 :             }
     895             :         }
     896           0 :         catch( const Exception& )
     897             :         {
     898             :             OSL_FAIL( "ODriverDelegator::onConnectedNewDatabase: caught an exception!" );
     899             :         }
     900           0 :     }
     901             : 
     902             :     //------------------------------------------------------------------
     903             :     //------------------------------------------------------------------
     904             : //........................................................................
     905             : }   // namespace connectivity
     906             : //........................................................................
     907             : 
     908             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10