1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: HDriver.cxx,v $
10 * $Revision: 1.28.56.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "hsqldb/HDriver.hxx"
34 #include "hsqldb/HConnection.hxx"
35 #include <osl/diagnose.h>
36 #include "connectivity/dbexception.hxx"
37 #include <com/sun/star/sdbc/XDriverAccess.hpp>
38 #include <com/sun/star/sdbc/XResultSet.hpp>
39 #include <com/sun/star/sdbc/XRow.hpp>
40 #include <com/sun/star/embed/XTransactionBroadcaster.hpp>
41 #include <com/sun/star/embed/ElementModes.hpp>
42 #include "TConnection.hxx"
43 #include "hsqldb/HStorageMap.hxx"
44 #include <jvmfwk/framework.h>
45 #include <com/sun/star/reflection/XProxyFactory.hpp>
46 #include <com/sun/star/embed/XStorage.hpp>
47 #include <com/sun/star/frame/XDesktop.hpp>
48 #include <com/sun/star/lang/Locale.hpp>
49 #include "HTerminateListener.hxx"
50 #include "hsqldb/HCatalog.hxx"
51 #include "diagnose_ex.h"
52 #include <rtl/ustrbuf.hxx>
54 #include <osl/process.h>
55 #include <connectivity/dbexception.hxx>
56 #include <comphelper/namedvaluecollection.hxx>
57 #include <unotools/confignode.hxx>
58 #include "resource/hsqldb_res.hrc"
59 #include "resource/sharedresources.hxx"
61 //........................................................................
62 namespace connectivity
64 //........................................................................
65 using namespace hsqldb
;
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::sdbc
;
68 using namespace ::com::sun::star::sdbcx
;
69 using namespace ::com::sun::star::beans
;
70 using namespace ::com::sun::star::frame
;
71 using namespace ::com::sun::star::lang
;
72 using namespace ::com::sun::star::embed
;
73 using namespace ::com::sun::star::reflection
;
77 Reference
< XInterface
> SAL_CALL
ODriverDelegator_CreateInstance(const Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& _rxFac
) throw( Exception
)
79 return *(new ODriverDelegator(_rxFac
));
85 //====================================================================
87 //====================================================================
88 //--------------------------------------------------------------------
89 ODriverDelegator::ODriverDelegator(const Reference
< XMultiServiceFactory
>& _rxFactory
)
90 : ODriverDelegator_BASE(m_aMutex
)
91 ,m_xFactory(_rxFactory
)
92 ,m_bInShutDownConnections(sal_False
)
96 //--------------------------------------------------------------------
97 ODriverDelegator::~ODriverDelegator()
101 ::comphelper::disposeComponent(m_xDriver
);
103 catch(const Exception
&)
108 // --------------------------------------------------------------------------------
109 void SAL_CALL
ODriverDelegator::disposing()
111 ::osl::MutexGuard
aGuard(m_aMutex
);
115 for (TWeakPairVector::iterator i
= m_aConnections
.begin(); m_aConnections
.end() != i
; ++i
)
117 Reference
<XInterface
> xTemp
= i
->first
.get();
118 ::comphelper::disposeComponent(xTemp
);
125 m_aConnections
.clear();
126 TWeakPairVector().swap(m_aConnections
);
128 cppu::WeakComponentImplHelperBase::disposing();
130 //--------------------------------------------------------------------
131 Reference
< XDriver
> ODriverDelegator::loadDriver( )
133 if ( !m_xDriver
.is() )
135 ::rtl::OUString
sURL(RTL_CONSTASCII_USTRINGPARAM("jdbc:hsqldb:db"));
136 Reference
<XDriverAccess
> xDriverAccess(m_xFactory
->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.DriverManager")) ),UNO_QUERY
);
137 OSL_ENSURE(xDriverAccess
.is(),"Could not load driver manager!");
138 if ( xDriverAccess
.is() )
139 m_xDriver
= xDriverAccess
->getDriverByURL(sURL
);
145 //--------------------------------------------------------------------
148 ::rtl::OUString
lcl_getPermittedJavaMethods_nothrow( const Reference
< XMultiServiceFactory
>& _rxORB
)
150 ::rtl::OUStringBuffer aConfigPath
;
151 aConfigPath
.appendAscii( "/org.openoffice.Office.DataAccess/DriverSettings/" );
152 aConfigPath
.append ( ODriverDelegator::getImplementationName_Static() );
153 aConfigPath
.appendAscii( "/PermittedJavaMethods" );
154 ::utl::OConfigurationTreeRoot
aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory(
155 _rxORB
, aConfigPath
.makeStringAndClear() ) );
157 ::rtl::OUStringBuffer aPermittedMethods
;
158 Sequence
< ::rtl::OUString
> aNodeNames( aConfig
.getNodeNames() );
159 for ( const ::rtl::OUString
* pNodeNames
= aNodeNames
.getConstArray();
160 pNodeNames
!= aNodeNames
.getConstArray() + aNodeNames
.getLength();
164 ::rtl::OUString sPermittedMethod
;
165 OSL_VERIFY( aConfig
.getNodeValue( *pNodeNames
) >>= sPermittedMethod
);
167 if ( aPermittedMethods
.getLength() )
168 aPermittedMethods
.append( (sal_Unicode
)';' );
169 aPermittedMethods
.append( sPermittedMethod
);
172 return aPermittedMethods
.makeStringAndClear();;
176 //--------------------------------------------------------------------
177 Reference
< XConnection
> SAL_CALL
ODriverDelegator::connect( const ::rtl::OUString
& url
, const Sequence
< PropertyValue
>& info
) throw (SQLException
, RuntimeException
)
179 Reference
< XConnection
> xConnection
;
180 if ( acceptsURL(url
) )
182 Reference
< XDriver
> xDriver
= loadDriver();
185 ::rtl::OUString sURL
;
186 Reference
<XStorage
> xStorage
;
187 const PropertyValue
* pIter
= info
.getConstArray();
188 const PropertyValue
* pEnd
= pIter
+ info
.getLength();
190 for (;pIter
!= pEnd
; ++pIter
)
192 if ( pIter
->Name
.equalsAscii("Storage") )
194 xStorage
.set(pIter
->Value
,UNO_QUERY
);
196 else if ( pIter
->Name
.equalsAscii("URL") )
198 pIter
->Value
>>= sURL
;
202 if ( !xStorage
.is() || !sURL
.getLength() )
204 ::connectivity::SharedResources aResources
;
205 const ::rtl::OUString sMessage
= aResources
.getResourceString(STR_NO_STROAGE
);
206 ::dbtools::throwGenericSQLException(sMessage
,*this);
209 ::rtl::OUString sSystemPath
;
210 osl_getSystemPathFromFileURL( sURL
.pData
, &sSystemPath
.pData
);
211 sal_Int32 nIndex
= sSystemPath
.lastIndexOf('.');
212 if ( !sURL
.getLength() || !sSystemPath
.getLength() )
214 ::connectivity::SharedResources aResources
;
215 const ::rtl::OUString sMessage
= aResources
.getResourceString(STR_INVALID_FILE_URL
);
216 ::dbtools::throwGenericSQLException(sMessage
,*this);
219 bool bIsNewDatabase
= !xStorage
->hasElements();
221 ::comphelper::NamedValueCollection aProperties
;
223 // properties for accessing the embedded storage
224 ::rtl::OUString sConnPartURL
= sSystemPath
.copy( 0, ::std::max
< sal_Int32
>( nIndex
, sSystemPath
.getLength() ) );
225 ::rtl::OUString sKey
= StorageContainer::registerStorage( xStorage
, sConnPartURL
);
226 aProperties
.put( "storage_key", sKey
);
227 aProperties
.put( "storage_class_name",
228 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbcx.comp.hsqldb.StorageAccess" ) ) );
229 aProperties
.put( "fileaccess_class_name",
230 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbcx.comp.hsqldb.StorageFileAccess" ) ) );
232 // JDBC driver and driver's classpath
233 aProperties
.put( "JavaDriverClass",
234 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.hsqldb.jdbcDriver" ) ) );
235 aProperties
.put( "JavaDriverClassPath",
238 RTL_CONSTASCII_USTRINGPARAM(HSQLDB_JAR
239 " vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/sdbc_hsqldb.jar" )
241 RTL_CONSTASCII_USTRINGPARAM("vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/hsqldb.jar"
242 " vnd.sun.star.expand:$OOO_BASE_DIR/program/classes/sdbc_hsqldb.jar" )
246 // auto increment handling
247 aProperties
.put( "IsAutoRetrievingEnabled", true );
248 aProperties
.put( "AutoRetrievingStatement",
249 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CALL IDENTITY()" ) ) );
250 aProperties
.put( "IgnoreDriverPrivileges", true );
252 // don't want to expose HSQLDB's schema capabilities which exist since 1.8.0RC10
253 aProperties
.put( "default_schema",
254 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
256 // security: permitted Java classes
257 NamedValue
aPermittedClasses(
258 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hsqldb.method_class_names" ) ),
259 makeAny( lcl_getPermittedJavaMethods_nothrow( m_xFactory
) )
261 aProperties
.put( "SystemProperties", Sequence
< NamedValue
>( &aPermittedClasses
, 1 ) );
264 Reference
<XPropertySet
> xProp(xStorage
,UNO_QUERY
);
268 xProp
->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenMode"))) >>= nMode
;
269 if ( (nMode
& ElementModes::WRITE
) != ElementModes::WRITE
)
271 aProperties
.put( "readonly", ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
275 Sequence
< PropertyValue
> aConnectionArgs
;
276 aProperties
>>= aConnectionArgs
;
278 ::rtl::OUString
sConnectURL(RTL_CONSTASCII_USTRINGPARAM("jdbc:hsqldb:"));
280 sConnectURL
+= sConnPartURL
;
281 Reference
<XConnection
> xOrig
;
284 xOrig
= xDriver
->connect( sConnectURL
, aConnectionArgs
);
286 catch(const Exception
& e
)
288 StorageContainer::revokeStorage(sKey
,NULL
);
293 // if the storage is completely empty, then we just created a new HSQLDB
294 // In this case, do some initializations.
295 if ( bIsNewDatabase
&& xOrig
.is() )
296 onConnectedNewDatabase( xOrig
);
300 OMetaConnection
* pMetaConnection
= NULL
;
301 // now we have to set the URL to get the correct answer for metadata()->getURL()
302 Reference
< XUnoTunnel
> xTunnel(xOrig
,UNO_QUERY
);
305 pMetaConnection
= reinterpret_cast<OMetaConnection
*>(xTunnel
->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
306 if ( pMetaConnection
)
307 pMetaConnection
->setURL(url
);
310 Reference
<XComponent
> xComp(xOrig
,UNO_QUERY
);
312 xComp
->addEventListener(this);
314 // we want to close all connections when the office shuts down
315 static Reference
< XTerminateListener
> s_xTerminateListener
;
316 if( !s_xTerminateListener
.is() )
318 Reference
< XDesktop
> xDesktop( m_xFactory
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY
);
322 s_xTerminateListener
= new OConnectionController(this);
323 xDesktop
->addTerminateListener(s_xTerminateListener
);
326 Reference
< XComponent
> xIfc
= new OHsqlConnection( this, xOrig
, m_xFactory
);
327 xConnection
.set(xIfc
,UNO_QUERY
);
328 m_aConnections
.push_back(TWeakPair(WeakReferenceHelper(xOrig
),TWeakConnectionPair(sKey
,TWeakRefPair(WeakReferenceHelper(xConnection
),WeakReferenceHelper()))));
330 Reference
<XTransactionBroadcaster
> xBroad(xStorage
,UNO_QUERY
);
333 Reference
<XTransactionListener
> xListener(*this,UNO_QUERY
);
334 xBroad
->addTransactionListener(xListener
);
342 //--------------------------------------------------------------------
343 sal_Bool SAL_CALL
ODriverDelegator::acceptsURL( const ::rtl::OUString
& url
) throw (SQLException
, RuntimeException
)
345 sal_Bool bEnabled
= sal_False
;
346 OSL_VERIFY_EQUALS( jfw_getEnabled( &bEnabled
), JFW_E_NONE
, "error in jfw_getEnabled" );
347 return bEnabled
&& url
.compareToAscii("sdbc:embedded:hsqldb",sizeof("sdbc:embedded:hsqldb")) == 0;
350 //--------------------------------------------------------------------
351 Sequence
< DriverPropertyInfo
> SAL_CALL
ODriverDelegator::getPropertyInfo( const ::rtl::OUString
& url
, const Sequence
< PropertyValue
>& /*info*/ ) throw (SQLException
, RuntimeException
)
353 if ( !acceptsURL(url
) )
354 return Sequence
< DriverPropertyInfo
>();
355 ::std::vector
< DriverPropertyInfo
> aDriverInfo
;
356 aDriverInfo
.push_back(DriverPropertyInfo(
357 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Storage"))
358 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the storage where the database will be stored."))
361 ,Sequence
< ::rtl::OUString
>())
363 aDriverInfo
.push_back(DriverPropertyInfo(
364 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"))
365 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the url of the data source."))
368 ,Sequence
< ::rtl::OUString
>())
370 aDriverInfo
.push_back(DriverPropertyInfo(
371 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoRetrievingStatement"))
372 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Defines the statement which will be executed to retrieve auto increment values."))
374 ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CALL IDENTITY()"))
375 ,Sequence
< ::rtl::OUString
>())
377 return Sequence
< DriverPropertyInfo
>(&aDriverInfo
[0],aDriverInfo
.size());
380 //--------------------------------------------------------------------
381 sal_Int32 SAL_CALL
ODriverDelegator::getMajorVersion( ) throw (RuntimeException
)
386 //--------------------------------------------------------------------
387 sal_Int32 SAL_CALL
ODriverDelegator::getMinorVersion( ) throw (RuntimeException
)
392 //--------------------------------------------------------------------
393 Reference
< XTablesSupplier
> SAL_CALL
ODriverDelegator::getDataDefinitionByConnection( const Reference
< XConnection
>& connection
) throw (SQLException
, RuntimeException
)
395 ::osl::MutexGuard
aGuard( m_aMutex
);
396 checkDisposed(ODriverDelegator_BASE::rBHelper
.bDisposed
);
398 Reference
< XTablesSupplier
> xTab
;
400 TWeakPairVector::iterator aEnd
= m_aConnections
.end();
401 for (TWeakPairVector::iterator i
= m_aConnections
.begin(); aEnd
!= i
; ++i
)
403 if ( i
->second
.second
.first
.get() == connection
.get() )
405 xTab
= Reference
< XTablesSupplier
>(i
->second
.second
.second
.get().get(),UNO_QUERY
);
408 xTab
= new OHCatalog(connection
);
409 i
->second
.second
.second
= WeakReferenceHelper(xTab
);
418 //--------------------------------------------------------------------
419 Reference
< XTablesSupplier
> SAL_CALL
ODriverDelegator::getDataDefinitionByURL( const ::rtl::OUString
& url
, const Sequence
< PropertyValue
>& info
) throw (SQLException
, RuntimeException
)
421 if ( ! acceptsURL(url
) )
423 ::connectivity::SharedResources aResources
;
424 const ::rtl::OUString sMessage
= aResources
.getResourceString(STR_URI_SYNTAX_ERROR
);
425 ::dbtools::throwGenericSQLException(sMessage
,*this);
428 return getDataDefinitionByConnection(connect(url
,info
));
432 // --------------------------------------------------------------------------------
433 //------------------------------------------------------------------------------
434 rtl::OUString
ODriverDelegator::getImplementationName_Static( ) throw(RuntimeException
)
436 return rtl::OUString::createFromAscii("com.sun.star.sdbcx.comp.hsqldb.Driver");
438 //------------------------------------------------------------------------------
439 Sequence
< ::rtl::OUString
> ODriverDelegator::getSupportedServiceNames_Static( ) throw (RuntimeException
)
441 Sequence
< ::rtl::OUString
> aSNS( 2 );
442 aSNS
[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.Driver"));
443 aSNS
[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Driver");
446 //------------------------------------------------------------------
447 ::rtl::OUString SAL_CALL
ODriverDelegator::getImplementationName( ) throw(RuntimeException
)
449 return getImplementationName_Static();
452 //------------------------------------------------------------------
453 sal_Bool SAL_CALL
ODriverDelegator::supportsService( const ::rtl::OUString
& _rServiceName
) throw(RuntimeException
)
455 Sequence
< ::rtl::OUString
> aSupported(getSupportedServiceNames());
456 const ::rtl::OUString
* pSupported
= aSupported
.getConstArray();
457 const ::rtl::OUString
* pEnd
= pSupported
+ aSupported
.getLength();
458 for (;pSupported
!= pEnd
&& !pSupported
->equals(_rServiceName
); ++pSupported
)
461 return pSupported
!= pEnd
;
463 //------------------------------------------------------------------
464 Sequence
< ::rtl::OUString
> SAL_CALL
ODriverDelegator::getSupportedServiceNames( ) throw(RuntimeException
)
466 return getSupportedServiceNames_Static();
468 //------------------------------------------------------------------
469 void SAL_CALL
ODriverDelegator::createCatalog( const Sequence
< PropertyValue
>& /*info*/ ) throw (SQLException
, ::com::sun::star::container::ElementExistException
, RuntimeException
)
471 ::dbtools::throwFeatureNotImplementedException( "XCreateCatalog::createCatalog", *this );
473 //------------------------------------------------------------------
474 void ODriverDelegator::shutdownConnection(const TWeakPairVector::iterator
& _aIter
)
476 OSL_ENSURE(m_aConnections
.end() != _aIter
,"Iterator equals .end()");
477 sal_Bool bLastOne
= sal_True
;
480 Reference
<XConnection
> _xConnection(_aIter
->first
.get(),UNO_QUERY
);
482 if ( _xConnection
.is() )
484 Reference
<XStatement
> xStmt
= _xConnection
->createStatement();
487 Reference
<XResultSet
> xRes(xStmt
->executeQuery(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT COUNT(*) FROM INFORMATION_SCHEMA.SYSTEM_SESSIONS WHERE USER_NAME ='SA'"))),UNO_QUERY
);
488 Reference
<XRow
> xRow(xRes
,UNO_QUERY
);
489 if ( xRow
.is() && xRes
->next() )
490 bLastOne
= xRow
->getInt(1) == 1;
492 xStmt
->execute(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SHUTDOWN")));
501 // Reference<XTransactionListener> xListener(*this,UNO_QUERY);
502 // a shutdown should commit all changes to the db files
503 StorageContainer::revokeStorage(_aIter
->second
.first
,NULL
);
505 if ( !m_bInShutDownConnections
)
506 m_aConnections
.erase(_aIter
);
508 //------------------------------------------------------------------
509 void SAL_CALL
ODriverDelegator::disposing( const ::com::sun::star::lang::EventObject
& Source
) throw(::com::sun::star::uno::RuntimeException
)
511 ::osl::MutexGuard
aGuard(m_aMutex
);
512 Reference
<XConnection
> xCon(Source
.Source
,UNO_QUERY
);
515 TWeakPairVector::iterator i
= m_aConnections
.begin();
516 for (; m_aConnections
.end() != i
; ++i
)
518 if ( i
->first
.get() == xCon
.get() )
520 shutdownConnection(i
);
527 Reference
< XStorage
> xStorage(Source
.Source
,UNO_QUERY
);
530 ::rtl::OUString sKey
= StorageContainer::getRegisteredKey(xStorage
);
531 TWeakPairVector::iterator i
= ::std::find_if(m_aConnections
.begin(),m_aConnections
.end(),::std::compose1(
532 ::std::bind2nd(::std::equal_to
< ::rtl::OUString
>(),sKey
)
533 ,::std::compose1(::std::select1st
<TWeakConnectionPair
>(),::std::select2nd
< TWeakPair
>())));
534 if ( i
!= m_aConnections
.end() )
535 shutdownConnection(i
);
539 //------------------------------------------------------------------
540 void ODriverDelegator::shutdownConnections()
542 m_bInShutDownConnections
= sal_True
;
543 TWeakPairVector::iterator aEnd
= m_aConnections
.end();
544 for (TWeakPairVector::iterator i
= m_aConnections
.begin(); aEnd
!= i
; ++i
)
548 Reference
<XConnection
> xCon(i
->first
,UNO_QUERY
);
549 ::comphelper::disposeComponent(xCon
);
555 m_aConnections
.clear();
556 m_bInShutDownConnections
= sal_True
;
558 //------------------------------------------------------------------
559 void SAL_CALL
ODriverDelegator::preCommit( const ::com::sun::star::lang::EventObject
& aEvent
) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
561 ::osl::MutexGuard
aGuard(m_aMutex
);
563 Reference
< XStorage
> xStorage(aEvent
.Source
,UNO_QUERY
);
564 ::rtl::OUString sKey
= StorageContainer::getRegisteredKey(xStorage
);
565 if ( sKey
.getLength() )
567 TWeakPairVector::iterator i
= ::std::find_if(m_aConnections
.begin(),m_aConnections
.end(),::std::compose1(
568 ::std::bind2nd(::std::equal_to
< ::rtl::OUString
>(),sKey
)
569 ,::std::compose1(::std::select1st
<TWeakConnectionPair
>(),::std::select2nd
< TWeakPair
>())));
570 OSL_ENSURE( i
!= m_aConnections
.end(), "ODriverDelegator::preCommit: they're committing a storage which I do not know!" );
571 if ( i
!= m_aConnections
.end() )
575 Reference
<XConnection
> xConnection(i
->first
,UNO_QUERY
);
576 if ( xConnection
.is() )
578 Reference
< XStatement
> xStmt
= xConnection
->createStatement();
579 OSL_ENSURE( xStmt
.is(), "ODriverDelegator::preCommit: no statement!" );
581 xStmt
->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SET WRITE_DELAY 0" ) ) );
583 sal_Bool bPreviousAutoCommit
= xConnection
->getAutoCommit();
584 xConnection
->setAutoCommit( sal_False
);
585 xConnection
->commit();
586 xConnection
->setAutoCommit( bPreviousAutoCommit
);
589 xStmt
->execute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SET WRITE_DELAY 60" ) ) );
594 OSL_ENSURE( false, "ODriverDelegator::preCommit: caught an exception!" );
599 //------------------------------------------------------------------
600 void SAL_CALL
ODriverDelegator::commited( const ::com::sun::star::lang::EventObject
& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException
)
603 //------------------------------------------------------------------
604 void SAL_CALL
ODriverDelegator::preRevert( const ::com::sun::star::lang::EventObject
& /*aEvent*/ ) throw (::com::sun::star::uno::Exception
, ::com::sun::star::uno::RuntimeException
)
607 //------------------------------------------------------------------
608 void SAL_CALL
ODriverDelegator::reverted( const ::com::sun::star::lang::EventObject
& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException
)
611 //------------------------------------------------------------------
614 //..............................................................
615 const sal_Char
* lcl_getCollationForLocale( const ::rtl::OUString
& _rLocaleString
, bool _bAcceptCountryMismatch
= false )
617 static const sal_Char
* pTranslations
[] =
619 "af-ZA", "Afrikaans",
623 "az-AZ", "Azerbaijani_Latin",
624 "az-cyrillic", "Azerbaijani_Cyrillic",
625 "be-BY", "Belarusian",
626 "bg-BG", "Bulgarian",
636 "en-US", "Latin1_General",
648 "hu-HU", "Hungarian",
650 "id-ID", "Indonesian",
652 "is-IS", "Icelandic",
654 "iu-CA", "Inuktitut",
665 "lt-LT", "Lithuanian",
668 "mk-MK", "Macedonian",
669 "ml-IN", "Malayalam",
670 "mn-MN", "Mongolian",
671 "mni-IN", "Manipuri",
676 "nb-NO", "Danish_Norwegian",
679 "nn-NO", "Norwegian",
684 "pt-PT", "Portuguese",
690 "sl-SI", "Slovenian",
693 "sr-YU", "Serbian_Cyrillic",
704 "uk-UA", "Ukrainian",
706 "uz-UZ", "Uzbek_Latin",
708 "vi-VN", "Vietnamese",
715 ::rtl::OUString
sLocaleString( _rLocaleString
);
716 sal_Char nCompareTermination
= 0;
718 if ( _bAcceptCountryMismatch
)
720 // strip the country part from the compare string
721 sal_Int32 nCountrySep
= sLocaleString
.indexOf( '-' );
722 if ( nCountrySep
> -1 )
723 sLocaleString
= sLocaleString
.copy( 0, nCountrySep
);
725 // the entries in the translation table are compared until the
726 // - character only, not until the terminating 0
727 nCompareTermination
= '-';
730 const sal_Char
** pLookup
= pTranslations
;
731 for ( ; *pLookup
; pLookup
+=2 )
733 sal_Int32 nCompareUntil
= 0;
734 while ( (*pLookup
)[ nCompareUntil
] != nCompareTermination
&& (*pLookup
)[ nCompareUntil
] != 0 )
737 if ( sLocaleString
.equalsAsciiL( *pLookup
, nCompareUntil
) )
738 return *( pLookup
+ 1 );
741 if ( !_bAcceptCountryMismatch
)
742 // second round, this time without matching the country
743 return lcl_getCollationForLocale( _rLocaleString
, true );
745 OSL_ENSURE( false, "lcl_getCollationForLocale: unknown locale string, falling back to Latin1_General!" );
746 return "Latin1_General";
749 //..............................................................
750 ::rtl::OUString
lcl_getSystemLocale( const Reference
< XMultiServiceFactory
>& _rxORB
)
752 ::rtl::OUString sLocaleString
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en-US" ) );
755 //.........................................................
756 Reference
< XMultiServiceFactory
> xConfigProvider(
757 _rxORB
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
760 OSL_ENSURE( xConfigProvider
.is(), "lcl_getSystemLocale: could not create the config provider!" );
762 if ( !xConfigProvider
.is() )
763 return sLocaleString
;
765 //.........................................................
766 // arguments for creating the config access
767 Sequence
< Any
> aArguments(2);
768 // the path to the node to open
769 ::rtl::OUString sNodePath
= ::rtl::OUString::createFromAscii ("/org.openoffice.Setup/L10N" );
770 aArguments
[0] <<= PropertyValue( ::rtl::OUString::createFromAscii( "nodepath"), 0,
771 makeAny( sNodePath
), PropertyState_DIRECT_VALUE
773 // the depth: -1 means unlimited
774 aArguments
[1] <<= PropertyValue(
775 ::rtl::OUString::createFromAscii( "depth"), 0,
776 makeAny( (sal_Int32
)-1 ), PropertyState_DIRECT_VALUE
779 //.........................................................
781 Reference
< XPropertySet
> xNode(
782 xConfigProvider
->createInstanceWithArguments(
783 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
786 OSL_ENSURE( xNode
.is(), "lcl_getSystemLocale: invalid access returned (should throw an exception instead)!" );
788 //.........................................................
789 // ask for the system locale setting
791 xNode
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupSystemLocale" ) ) ) >>= sLocaleString
;
793 catch( const Exception
& )
795 OSL_ENSURE( sal_False
, "lcl_getSystemLocale: caught an exception!" );
797 if ( !sLocaleString
.getLength() )
799 rtl_Locale
* pProcessLocale
= NULL
;
800 osl_getProcessLocale( &pProcessLocale
);
802 ::rtl::OUStringBuffer aProcLocale
;
803 aProcLocale
.append( pProcessLocale
->Language
->buffer
, pProcessLocale
->Language
->length
);
804 if ( pProcessLocale
->Country
->length
)
806 aProcLocale
.appendAscii( "-" );
807 aProcLocale
.append( pProcessLocale
->Country
->buffer
, pProcessLocale
->Country
->length
);
809 sLocaleString
= aProcLocale
.makeStringAndClear();
811 return sLocaleString
;
814 //------------------------------------------------------------------
815 void ODriverDelegator::onConnectedNewDatabase( const Reference
< XConnection
>& _rxConnection
)
819 Reference
< XStatement
> xStatement
= _rxConnection
->createStatement();
820 OSL_ENSURE( xStatement
.is(), "ODriverDelegator::onConnectedNewDatabase: could not create a statement!" );
821 if ( xStatement
.is() )
823 ::rtl::OUStringBuffer aStatement
;
824 aStatement
.appendAscii( "SET DATABASE COLLATION \"" );
825 aStatement
.appendAscii( lcl_getCollationForLocale( lcl_getSystemLocale( m_xFactory
) ) );
826 aStatement
.appendAscii( "\"" );
828 xStatement
->execute( aStatement
.makeStringAndClear() );
831 catch( const Exception
& )
833 OSL_ENSURE( sal_False
, "ODriverDelegator::onConnectedNewDatabase: caught an exception!" );
837 //------------------------------------------------------------------
838 //------------------------------------------------------------------
839 //........................................................................
840 } // namespace connectivity
841 //........................................................................