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