1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hsqldb/HDriver.hxx>
21 #include <hsqldb/HConnection.hxx>
22 #include <osl/diagnose.h>
23 #include <sal/log.hxx>
24 #include <connectivity/dbexception.hxx>
25 #include <com/sun/star/configuration/theDefaultProvider.hpp>
26 #include <com/sun/star/sdbc/DriverManager.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.hxx>
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/util/XFlushable.hpp>
38 #include "HTerminateListener.hxx"
39 #include <hsqldb/HCatalog.hxx>
40 #include <rtl/ustrbuf.hxx>
42 #include <osl/process.h>
43 #include <comphelper/namedvaluecollection.hxx>
44 #include <comphelper/propertysequence.hxx>
45 #include <comphelper/servicehelper.hxx>
46 #include <cppuhelper/supportsservice.hxx>
47 #include <comphelper/types.hxx>
48 #include <unotools/confignode.hxx>
49 #include <unotools/ucbstreamhelper.hxx>
50 #include <strings.hrc>
51 #include <resource/sharedresources.hxx>
52 #include <i18nlangtag/languagetag.hxx>
53 #include <tools/diagnose_ex.h>
58 namespace connectivity
61 using namespace hsqldb
;
62 using namespace css::uno
;
63 using namespace css::sdbc
;
64 using namespace css::sdbcx
;
65 using namespace css::beans
;
66 using namespace css::frame
;
67 using namespace css::lang
;
68 using namespace css::embed
;
69 using namespace css::io
;
70 using namespace css::util
;
71 using namespace css::reflection
;
73 constexpr OUStringLiteral IMPL_NAME
= u
"com.sun.star.sdbcx.comp.hsqldb.Driver";
77 ODriverDelegator::ODriverDelegator(const Reference
< XComponentContext
>& _rxContext
)
78 : ODriverDelegator_BASE(m_aMutex
)
79 ,m_xContext(_rxContext
)
80 ,m_bInShutDownConnections(false)
85 ODriverDelegator::~ODriverDelegator()
89 ::comphelper::disposeComponent(m_xDriver
);
91 catch(const Exception
&)
97 void SAL_CALL
ODriverDelegator::disposing()
99 ::osl::MutexGuard
aGuard(m_aMutex
);
103 for (const auto& rConnection
: m_aConnections
)
105 Reference
<XInterface
> xTemp
= rConnection
.first
.get();
106 ::comphelper::disposeComponent(xTemp
);
113 m_aConnections
.clear();
114 TWeakPairVector().swap(m_aConnections
);
116 cppu::WeakComponentImplHelperBase::disposing();
119 Reference
< XDriver
> const & ODriverDelegator::loadDriver( )
121 if ( !m_xDriver
.is() )
123 Reference
<XDriverManager2
> xDriverAccess
= DriverManager::create( m_xContext
);
124 m_xDriver
= xDriverAccess
->getDriverByURL("jdbc:hsqldb:db");
133 OUString
lcl_getPermittedJavaMethods_nothrow( const Reference
< XComponentContext
>& _rxContext
)
135 OUString aConfigPath
=
136 "/org.openoffice.Office.DataAccess/DriverSettings/" +
138 "/PermittedJavaMethods";
139 ::utl::OConfigurationTreeRoot
aConfig( ::utl::OConfigurationTreeRoot::createWithComponentContext(
140 _rxContext
, aConfigPath
) );
142 OUStringBuffer aPermittedMethods
;
143 const Sequence
< OUString
> aNodeNames( aConfig
.getNodeNames() );
144 for ( auto const & nodeName
: aNodeNames
)
146 OUString sPermittedMethod
;
147 OSL_VERIFY( aConfig
.getNodeValue( nodeName
) >>= sPermittedMethod
);
149 if ( !aPermittedMethods
.isEmpty() )
150 aPermittedMethods
.append( ';' );
151 aPermittedMethods
.append( sPermittedMethod
);
154 return aPermittedMethods
.makeStringAndClear();
159 Reference
< XConnection
> SAL_CALL
ODriverDelegator::connect( const OUString
& url
, const Sequence
< PropertyValue
>& info
)
161 Reference
< XConnection
> xConnection
;
162 if ( acceptsURL(url
) )
164 Reference
< XDriver
> xDriver
= loadDriver();
168 Reference
<XStorage
> xStorage
;
169 const PropertyValue
* pIter
= info
.getConstArray();
170 const PropertyValue
* pEnd
= pIter
+ info
.getLength();
172 for (;pIter
!= pEnd
; ++pIter
)
174 if ( pIter
->Name
== "Storage" )
176 xStorage
.set(pIter
->Value
,UNO_QUERY
);
178 else if ( pIter
->Name
== "URL" )
180 pIter
->Value
>>= sURL
;
184 if ( !xStorage
.is() || sURL
.isEmpty() )
186 ::connectivity::SharedResources aResources
;
187 const OUString sMessage
= aResources
.getResourceString(STR_NO_STORAGE
);
188 ::dbtools::throwGenericSQLException(sMessage
,*this);
191 OUString sSystemPath
;
192 osl_getSystemPathFromFileURL( sURL
.pData
, &sSystemPath
.pData
);
193 if ( sURL
.isEmpty() || sSystemPath
.isEmpty() )
195 ::connectivity::SharedResources aResources
;
196 const OUString sMessage
= aResources
.getResourceString(STR_INVALID_FILE_URL
);
197 ::dbtools::throwGenericSQLException(sMessage
,*this);
200 bool bIsNewDatabase
= !xStorage
->hasElements();
202 ::comphelper::NamedValueCollection aProperties
;
204 // properties for accessing the embedded storage
205 OUString sKey
= StorageContainer::registerStorage( xStorage
, sSystemPath
);
206 aProperties
.put( "storage_key", sKey
);
207 aProperties
.put( "storage_class_name",
208 OUString( "com.sun.star.sdbcx.comp.hsqldb.StorageAccess" ) );
209 aProperties
.put( "fileaccess_class_name",
210 OUString( "com.sun.star.sdbcx.comp.hsqldb.StorageFileAccess" ) );
212 // JDBC driver and driver's classpath
213 aProperties
.put( "JavaDriverClass",
214 OUString( "org.hsqldb.jdbcDriver" ) );
215 aProperties
.put( "JavaDriverClassPath",
220 "vnd.sun.star.expand:$LO_JAVA_DIR/hsqldb.jar"
222 " vnd.sun.star.expand:$LO_JAVA_DIR/sdbc_hsqldb.jar"
225 // auto increment handling
226 aProperties
.put( "IsAutoRetrievingEnabled", true );
227 aProperties
.put( "AutoRetrievingStatement",
228 OUString( "CALL IDENTITY()" ) );
229 aProperties
.put( "IgnoreDriverPrivileges", true );
231 // don't want to expose HSQLDB's schema capabilities which exist since 1.8.0RC10
232 aProperties
.put( "default_schema",
233 OUString( "true" ) );
235 // security: permitted Java classes
236 NamedValue
aPermittedClasses(
237 "hsqldb.method_class_names",
238 makeAny( lcl_getPermittedJavaMethods_nothrow( m_xContext
) )
240 aProperties
.put( "SystemProperties", Sequence
< NamedValue
>( &aPermittedClasses
, 1 ) );
245 static const OUStringLiteral
sProperties( u
"properties" );
246 if ( !bIsNewDatabase
&& xStorage
->isStreamElement(sProperties
) )
248 Reference
<XStream
> xStream
= xStorage
->openStreamElement(sProperties
,ElementModes::READ
);
251 std::unique_ptr
<SvStream
> pStream( ::utl::UcbStreamHelper::CreateStream(xStream
) );
255 OString sVersionString
;
256 while ( pStream
->ReadLine(sLine
) )
258 if ( sLine
.isEmpty() )
261 const OString sIniKey
= sLine
.getToken(0, '=', nIdx
);
262 const OString sValue
= sLine
.getToken(0, '=', nIdx
);
263 if( sIniKey
== "hsqldb.compatible_version" )
265 sVersionString
= sValue
;
269 if (sIniKey
== "version" && sVersionString
.isEmpty())
271 sVersionString
= sValue
;
275 if (!sVersionString
.isEmpty())
278 const sal_Int32 nMajor
= sVersionString
.getToken(0, '.', nIdx
).toInt32();
279 const sal_Int32 nMinor
= sVersionString
.getToken(0, '.', nIdx
).toInt32();
280 const sal_Int32 nMicro
= sVersionString
.getToken(0, '.', nIdx
).toInt32();
282 || ( nMajor
== 1 && nMinor
> 8 )
283 || ( nMajor
== 1 && nMinor
== 8 && nMicro
> 0 ) )
285 ::connectivity::SharedResources aResources
;
286 sMessage
= aResources
.getResourceString(STR_ERROR_NEW_VERSION
);
290 } // if ( xStream.is() )
291 ::comphelper::disposeComponent(xStream
);
297 if ( !sMessage
.isEmpty() )
299 ::dbtools::throwGenericSQLException(sMessage
,*this);
303 Reference
<XPropertySet
> xProp(xStorage
,UNO_QUERY
);
307 xProp
->getPropertyValue("OpenMode") >>= nMode
;
308 if ( (nMode
& ElementModes::WRITE
) != ElementModes::WRITE
)
310 aProperties
.put( "readonly", OUString( "true" ) );
314 Sequence
< PropertyValue
> aConnectionArgs
;
315 aProperties
>>= aConnectionArgs
;
316 OUString sConnectURL
= "jdbc:hsqldb:" + sSystemPath
;
317 Reference
<XConnection
> xOrig
;
320 xOrig
= xDriver
->connect( sConnectURL
, aConnectionArgs
);
322 catch(const Exception
&)
324 StorageContainer::revokeStorage(sKey
,nullptr);
328 // if the storage is completely empty, then we just created a new HSQLDB
329 // In this case, do some initializations.
330 if ( bIsNewDatabase
&& xOrig
.is() )
331 onConnectedNewDatabase( xOrig
);
335 // now we have to set the URL to get the correct answer for metadata()->getURL()
336 auto pMetaConnection
= comphelper::getUnoTunnelImplementation
<OMetaConnection
>(xOrig
);
337 if ( pMetaConnection
)
338 pMetaConnection
->setURL(url
);
340 Reference
<XComponent
> xComp(xOrig
,UNO_QUERY
);
342 xComp
->addEventListener(this);
344 // we want to close all connections when the office shuts down
345 static Reference
< XTerminateListener
> s_xTerminateListener
= [&]()
347 Reference
< XDesktop2
> xDesktop
= Desktop::create( m_xContext
);
349 rtl::Reference
<OConnectionController
> tmp
= new OConnectionController(this);
350 xDesktop
->addTerminateListener(tmp
);
353 Reference
< XComponent
> xIfc
= new OHsqlConnection( this, xOrig
, m_xContext
);
354 xConnection
.set(xIfc
,UNO_QUERY
);
355 m_aConnections
.push_back(TWeakPair(WeakReferenceHelper(xOrig
),TWeakConnectionPair(sKey
,TWeakRefPair(WeakReferenceHelper(xConnection
),WeakReferenceHelper()))));
357 Reference
<XTransactionBroadcaster
> xBroad(xStorage
,UNO_QUERY
);
360 Reference
<XTransactionListener
> xListener(*this,UNO_QUERY
);
361 xBroad
->addTransactionListener(xListener
);
370 sal_Bool SAL_CALL
ODriverDelegator::acceptsURL( const OUString
& url
)
372 bool bEnabled
= false;
373 javaFrameworkError e
= jfw_getEnabled(&bEnabled
);
377 case JFW_E_DIRECT_MODE
:
379 "connectivity.hsqldb",
380 "jfw_getEnabled: JFW_E_DIRECT_MODE, assuming true");
385 "connectivity.hsqldb", "jfw_getEnabled: error code " << +e
);
388 return bEnabled
&& url
== "sdbc:embedded:hsqldb";
392 Sequence
< DriverPropertyInfo
> SAL_CALL
ODriverDelegator::getPropertyInfo( const OUString
& url
, const Sequence
< PropertyValue
>& /*info*/ )
394 if ( !acceptsURL(url
) )
395 return Sequence
< DriverPropertyInfo
>();
400 "Defines the storage where the database will be stored.",
407 "Defines the url of the data source.",
413 "AutoRetrievingStatement",
414 "Defines the statement which will be executed to retrieve auto increment values.",
423 sal_Int32 SAL_CALL
ODriverDelegator::getMajorVersion( )
429 sal_Int32 SAL_CALL
ODriverDelegator::getMinorVersion( )
435 Reference
< XTablesSupplier
> SAL_CALL
ODriverDelegator::getDataDefinitionByConnection( const Reference
< XConnection
>& connection
)
437 ::osl::MutexGuard
aGuard( m_aMutex
);
438 checkDisposed(ODriverDelegator_BASE::rBHelper
.bDisposed
);
440 Reference
< XTablesSupplier
> xTab
;
442 TWeakPairVector::iterator i
= std::find_if(m_aConnections
.begin(), m_aConnections
.end(),
443 [&connection
](const TWeakPairVector::value_type
& rConnection
) {
444 return rConnection
.second
.second
.first
.get() == connection
.get(); });
445 if (i
!= m_aConnections
.end())
447 xTab
.set(i
->second
.second
.second
,UNO_QUERY
);
450 xTab
= new OHCatalog(connection
);
451 i
->second
.second
.second
= WeakReferenceHelper(xTab
);
459 Reference
< XTablesSupplier
> SAL_CALL
ODriverDelegator::getDataDefinitionByURL( const OUString
& url
, const Sequence
< PropertyValue
>& info
)
461 if ( ! acceptsURL(url
) )
463 ::connectivity::SharedResources aResources
;
464 const OUString sMessage
= aResources
.getResourceString(STR_URI_SYNTAX_ERROR
);
465 ::dbtools::throwGenericSQLException(sMessage
,*this);
468 return getDataDefinitionByConnection(connect(url
,info
));
473 OUString SAL_CALL
ODriverDelegator::getImplementationName( )
478 sal_Bool SAL_CALL
ODriverDelegator::supportsService( const OUString
& _rServiceName
)
480 return cppu::supportsService(this, _rServiceName
);
483 Sequence
< OUString
> SAL_CALL
ODriverDelegator::getSupportedServiceNames( )
485 return { "com.sun.star.sdbc.Driver", "com.sun.star.sdbcx.Driver" };
488 void SAL_CALL
ODriverDelegator::createCatalog( const Sequence
< PropertyValue
>& /*info*/ )
490 ::dbtools::throwFeatureNotImplementedSQLException( "XCreateCatalog::createCatalog", *this );
493 void ODriverDelegator::shutdownConnection(const TWeakPairVector::iterator
& _aIter
)
495 OSL_ENSURE(m_aConnections
.end() != _aIter
,"Iterator equals .end()");
496 bool bLastOne
= true;
499 Reference
<XConnection
> _xConnection(_aIter
->first
.get(),UNO_QUERY
);
501 if ( _xConnection
.is() )
503 Reference
<XStatement
> xStmt
= _xConnection
->createStatement();
506 Reference
<XResultSet
> xRes
= xStmt
->executeQuery("SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS WHERE USER_NAME ='SA'");
507 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
508 if ( xRow
.is() && xRes
->next() )
509 bLastOne
= xRow
->getInt(1) == 1;
511 xStmt
->execute("SHUTDOWN");
520 // Reference<XTransactionListener> xListener(*this,UNO_QUERY);
521 // a shutdown should commit all changes to the db files
522 StorageContainer::revokeStorage(_aIter
->second
.first
,nullptr);
524 if ( !m_bInShutDownConnections
)
525 m_aConnections
.erase(_aIter
);
528 void SAL_CALL
ODriverDelegator::disposing( const css::lang::EventObject
& Source
)
530 ::osl::MutexGuard
aGuard(m_aMutex
);
531 Reference
<XConnection
> xCon(Source
.Source
,UNO_QUERY
);
534 TWeakPairVector::iterator i
= std::find_if(m_aConnections
.begin(), m_aConnections
.end(),
535 [&xCon
](const TWeakPairVector::value_type
& rConnection
) { return rConnection
.first
.get() == xCon
.get(); });
537 if (i
!= m_aConnections
.end())
538 shutdownConnection(i
);
542 Reference
< XStorage
> xStorage(Source
.Source
,UNO_QUERY
);
545 OUString sKey
= StorageContainer::getRegisteredKey(xStorage
);
546 TWeakPairVector::iterator i
= std::find_if(m_aConnections
.begin(),m_aConnections
.end(),
547 [&sKey
] (const TWeakPairVector::value_type
& conn
) {
548 return conn
.second
.first
== sKey
;
551 if ( i
!= m_aConnections
.end() )
552 shutdownConnection(i
);
557 void ODriverDelegator::shutdownConnections()
559 m_bInShutDownConnections
= true;
560 for (const auto& rConnection
: m_aConnections
)
564 Reference
<XConnection
> xCon(rConnection
.first
,UNO_QUERY
);
565 ::comphelper::disposeComponent(xCon
);
571 m_aConnections
.clear();
572 m_bInShutDownConnections
= true;
575 void ODriverDelegator::flushConnections()
577 for (const auto& rConnection
: m_aConnections
)
581 Reference
<XFlushable
> xCon(rConnection
.second
.second
.first
.get(),UNO_QUERY
);
587 DBG_UNHANDLED_EXCEPTION("connectivity.hsqldb");
592 void SAL_CALL
ODriverDelegator::preCommit( const css::lang::EventObject
& aEvent
)
594 ::osl::MutexGuard
aGuard(m_aMutex
);
596 Reference
< XStorage
> xStorage(aEvent
.Source
,UNO_QUERY
);
597 OUString sKey
= StorageContainer::getRegisteredKey(xStorage
);
598 if ( sKey
.isEmpty() )
601 TWeakPairVector::const_iterator i
= std::find_if(m_aConnections
.begin(), m_aConnections
.end(),
602 [&sKey
] (const TWeakPairVector::value_type
& conn
) {
603 return conn
.second
.first
== sKey
;
606 OSL_ENSURE( i
!= m_aConnections
.end(), "ODriverDelegator::preCommit: they're committing a storage which I do not know!" );
607 if ( i
== m_aConnections
.end() )
612 Reference
<XConnection
> xConnection(i
->first
,UNO_QUERY
);
613 if ( xConnection
.is() )
615 Reference
< XStatement
> xStmt
= xConnection
->createStatement();
616 OSL_ENSURE( xStmt
.is(), "ODriverDelegator::preCommit: no statement!" );
618 xStmt
->execute( "SET WRITE_DELAY 0" );
620 bool bPreviousAutoCommit
= xConnection
->getAutoCommit();
621 xConnection
->setAutoCommit( false );
622 xConnection
->commit();
623 xConnection
->setAutoCommit( bPreviousAutoCommit
);
626 xStmt
->execute( "SET WRITE_DELAY 60" );
631 TOOLS_WARN_EXCEPTION( "connectivity.hsqldb", "ODriverDelegator::preCommit" );
635 void SAL_CALL
ODriverDelegator::commited( const css::lang::EventObject
& /*aEvent*/ )
639 void SAL_CALL
ODriverDelegator::preRevert( const css::lang::EventObject
& /*aEvent*/ )
643 void SAL_CALL
ODriverDelegator::reverted( const css::lang::EventObject
& /*aEvent*/ )
650 const char* lcl_getCollationForLocale( const OUString
& _rLocaleString
, bool _bAcceptCountryMismatch
= false )
652 static const char* pTranslations
[] =
654 "af-ZA", "Afrikaans",
658 "az-AZ", "Azerbaijani_Latin",
659 "az-cyrillic", "Azerbaijani_Cyrillic",
660 "be-BY", "Belarusian",
661 "bg-BG", "Bulgarian",
671 "en-US", "Latin1_General",
683 "hu-HU", "Hungarian",
685 "id-ID", "Indonesian",
687 "is-IS", "Icelandic",
689 "iu-CA", "Inuktitut",
700 "lt-LT", "Lithuanian",
703 "mk-MK", "Macedonian",
704 "ml-IN", "Malayalam",
705 "mn-MN", "Mongolian",
706 "mni-IN", "Manipuri",
711 "nb-NO", "Danish_Norwegian",
714 "nn-NO", "Norwegian",
719 "pt-PT", "Portuguese",
725 "sl-SI", "Slovenian",
728 "sr-YU", "Serbian_Cyrillic",
739 "uk-UA", "Ukrainian",
741 "uz-UZ", "Uzbek_Latin",
743 "vi-VN", "Vietnamese",
750 OUString
sLocaleString( _rLocaleString
);
751 char nCompareTermination
= 0;
753 if ( _bAcceptCountryMismatch
)
755 // strip the country part from the compare string
756 sal_Int32 nCountrySep
= sLocaleString
.indexOf( '-' );
757 if ( nCountrySep
> -1 )
758 sLocaleString
= sLocaleString
.copy( 0, nCountrySep
);
760 // the entries in the translation table are compared until the
761 // - character only, not until the terminating 0
762 nCompareTermination
= '-';
765 const char** pLookup
= pTranslations
;
766 for ( ; *pLookup
; pLookup
+=2 )
768 sal_Int32 nCompareUntil
= 0;
769 while ( (*pLookup
)[ nCompareUntil
] != nCompareTermination
&& (*pLookup
)[ nCompareUntil
] != 0 )
772 if ( sLocaleString
.equalsAsciiL( *pLookup
, nCompareUntil
) )
773 return *( pLookup
+ 1 );
776 if ( !_bAcceptCountryMismatch
)
777 // second round, this time without matching the country
778 return lcl_getCollationForLocale( _rLocaleString
, true );
780 OSL_FAIL( "lcl_getCollationForLocale: unknown locale string, falling back to Latin1_General!" );
781 return "Latin1_General";
785 OUString
lcl_getSystemLocale( const Reference
< XComponentContext
>& _rxContext
)
787 OUString sLocaleString
= "en-US";
791 Reference
< XMultiServiceFactory
> xConfigProvider(
792 css::configuration::theDefaultProvider::get( _rxContext
) );
795 // arguments for creating the config access
796 Sequence
<Any
> aArguments(comphelper::InitAnyPropertySequence(
798 {"nodepath", Any(OUString("/org.openoffice.Setup/L10N" ))}, // the path to the node to open
799 {"depth", Any(sal_Int32(-1))}, // the depth: -1 means unlimited
802 Reference
< XPropertySet
> xNode(
803 xConfigProvider
->createInstanceWithArguments(
804 "com.sun.star.configuration.ConfigurationAccess",
807 OSL_ENSURE( xNode
.is(), "lcl_getSystemLocale: invalid access returned (should throw an exception instead)!" );
810 // ask for the system locale setting
812 xNode
->getPropertyValue("ooSetupSystemLocale") >>= sLocaleString
;
814 catch( const Exception
& )
816 TOOLS_WARN_EXCEPTION( "connectivity.hsqldb", "lcl_getSystemLocale" );
818 if ( sLocaleString
.isEmpty() )
820 rtl_Locale
* pProcessLocale
= nullptr;
821 osl_getProcessLocale( &pProcessLocale
);
822 sLocaleString
= LanguageTag( *pProcessLocale
).getBcp47();
824 return sLocaleString
;
828 void ODriverDelegator::onConnectedNewDatabase( const Reference
< XConnection
>& _rxConnection
)
832 Reference
< XStatement
> xStatement
= _rxConnection
->createStatement();
833 OSL_ENSURE( xStatement
.is(), "ODriverDelegator::onConnectedNewDatabase: could not create a statement!" );
834 if ( xStatement
.is() )
836 OUStringBuffer aStatement
;
837 aStatement
.append( "SET DATABASE COLLATION \"" );
838 aStatement
.appendAscii( lcl_getCollationForLocale( lcl_getSystemLocale( m_xContext
) ) );
839 aStatement
.append( "\"" );
841 xStatement
->execute( aStatement
.makeStringAndClear() );
844 catch( const Exception
& )
846 TOOLS_WARN_EXCEPTION( "connectivity.hsqldb", "ODriverDelegator::onConnectedNewDatabase" );
851 } // namespace connectivity
854 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
855 connectivity_hsqldb_ODriverDelegator_implementation(
856 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
858 return cppu::acquire(new connectivity::ODriverDelegator(context
));
862 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */