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 "ado/AConnection.hxx"
27cdf0e10cSrcweir #include "ado/ADatabaseMetaData.hxx"
28cdf0e10cSrcweir #include "ado/ADriver.hxx"
29cdf0e10cSrcweir #include "ado/AStatement.hxx"
30cdf0e10cSrcweir #include "ado/ACallableStatement.hxx"
31cdf0e10cSrcweir #include "ado/APreparedStatement.hxx"
32cdf0e10cSrcweir #include "ado/ACatalog.hxx"
33cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
34cdf0e10cSrcweir #include <com/sun/star/sdbc/TransactionIsolation.hpp>
35cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
36cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
37cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx>
38cdf0e10cSrcweir #include "connectivity/dbexception.hxx"
39cdf0e10cSrcweir #include <osl/file.hxx>
40cdf0e10cSrcweir #include "resource/ado_res.hrc"
41cdf0e10cSrcweir 
42cdf0e10cSrcweir using namespace dbtools;
43cdf0e10cSrcweir using namespace connectivity::ado;
44cdf0e10cSrcweir using namespace com::sun::star::uno;
45cdf0e10cSrcweir using namespace com::sun::star::lang;
46cdf0e10cSrcweir using namespace com::sun::star::beans;
47cdf0e10cSrcweir using namespace com::sun::star::sdbc;
48cdf0e10cSrcweir using namespace com::sun::star::sdbcx;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir //------------------------------------------------------------------------------
51cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO(OConnection,"com.sun.star.sdbcx.AConnection","com.sun.star.sdbc.Connection");
52cdf0e10cSrcweir // --------------------------------------------------------------------------------
OConnection(ODriver * _pDriver)53cdf0e10cSrcweir OConnection::OConnection(ODriver*	_pDriver) throw(SQLException, RuntimeException)
54cdf0e10cSrcweir 						 : OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)_pDriver, this),
55cdf0e10cSrcweir 						 m_bClosed(sal_False),
56cdf0e10cSrcweir 						 m_xCatalog(NULL),
57cdf0e10cSrcweir 						 m_pDriver(_pDriver),
58cdf0e10cSrcweir 						 m_pAdoConnection(NULL),
59cdf0e10cSrcweir 						 m_bAutocommit(sal_True),
60cdf0e10cSrcweir 						 m_nEngineType(0),
61cdf0e10cSrcweir 						 m_pCatalog(NULL)
62cdf0e10cSrcweir {
63cdf0e10cSrcweir 	osl_incrementInterlockedCount( &m_refCount );
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 	IClassFactory2* pIUnknown	= NULL;
66cdf0e10cSrcweir 	IUnknown        *pOuter		= NULL;
67cdf0e10cSrcweir 	HRESULT         hr;
68cdf0e10cSrcweir 	hr = CoGetClassObject( ADOS::CLSID_ADOCONNECTION_21,
69cdf0e10cSrcweir 						  CLSCTX_INPROC_SERVER,
70cdf0e10cSrcweir 						  NULL,
71cdf0e10cSrcweir 						  IID_IClassFactory2,
72cdf0e10cSrcweir 						  (void**)&pIUnknown );
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 	if( !FAILED( hr ) )
75cdf0e10cSrcweir 	{
76cdf0e10cSrcweir 		ADOConnection *pCon			= NULL;
77cdf0e10cSrcweir 		hr = pIUnknown->CreateInstanceLic(  pOuter,
78cdf0e10cSrcweir 											NULL,
79cdf0e10cSrcweir 											ADOS::IID_ADOCONNECTION_21,
80cdf0e10cSrcweir 											ADOS::GetKeyStr(),
81cdf0e10cSrcweir 											(void**) &pCon);
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 		if( !FAILED( hr ) )
84cdf0e10cSrcweir 		{
85cdf0e10cSrcweir 			OSL_ENSURE( pCon, "OConnection::OConnection: invalid ADO object!" );
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 			m_pAdoConnection = new WpADOConnection( pCon );
88cdf0e10cSrcweir 			// CreateInstanceLic returned an object which was already acquired
89cdf0e10cSrcweir 			pCon->Release( );
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 		}
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 		// Class Factory is no longer needed
94cdf0e10cSrcweir 		pIUnknown->Release();
95cdf0e10cSrcweir 	}
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 	osl_decrementInterlockedCount( &m_refCount );
98cdf0e10cSrcweir }
99cdf0e10cSrcweir //-----------------------------------------------------------------------------
~OConnection()100cdf0e10cSrcweir OConnection::~OConnection()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir }
103cdf0e10cSrcweir //-----------------------------------------------------------------------------
construct(const::rtl::OUString & url,const Sequence<PropertyValue> & info)104cdf0e10cSrcweir void OConnection::construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info)
105cdf0e10cSrcweir {
106cdf0e10cSrcweir 	osl_incrementInterlockedCount( &m_refCount );
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     setConnectionInfo(info);
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 	sal_Int32 nLen = url.indexOf(':');
111cdf0e10cSrcweir 	nLen = url.indexOf(':',nLen+1);
112cdf0e10cSrcweir 	::rtl::OUString aDSN(url.copy(nLen+1)),aUID,aPWD;
113cdf0e10cSrcweir 	if ( aDSN.compareToAscii("access:",7) == 0 )
114cdf0e10cSrcweir 		aDSN = aDSN.copy(7);
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 	sal_Int32 nTimeout = 20;
117cdf0e10cSrcweir 	sal_Bool bSilent = sal_True;
118cdf0e10cSrcweir 	const PropertyValue *pIter	= info.getConstArray();
119cdf0e10cSrcweir 	const PropertyValue *pEnd	= pIter + info.getLength();
120cdf0e10cSrcweir 	for(;pIter != pEnd;++pIter)
121cdf0e10cSrcweir 	{
122cdf0e10cSrcweir 		if(!pIter->Name.compareToAscii("Timeout"))
123cdf0e10cSrcweir 			pIter->Value >>= nTimeout;
124cdf0e10cSrcweir 		else if(!pIter->Name.compareToAscii("Silent"))
125cdf0e10cSrcweir 			pIter->Value >>= bSilent;
126cdf0e10cSrcweir 		else if(!pIter->Name.compareToAscii("user"))
127cdf0e10cSrcweir 			pIter->Value >>= aUID;
128cdf0e10cSrcweir 		else if(!pIter->Name.compareToAscii("password"))
129cdf0e10cSrcweir 			pIter->Value >>= aPWD;
130cdf0e10cSrcweir 	}
131cdf0e10cSrcweir     try
132cdf0e10cSrcweir     {
133cdf0e10cSrcweir 	    if(m_pAdoConnection)
134cdf0e10cSrcweir 	    {
135cdf0e10cSrcweir 		    if(m_pAdoConnection->Open(aDSN,aUID,aPWD,adConnectUnspecified))
136cdf0e10cSrcweir 			    m_pAdoConnection->PutCommandTimeout(nTimeout);
137cdf0e10cSrcweir 		    else
138cdf0e10cSrcweir 			    ADOS::ThrowException(*m_pAdoConnection,*this);
139cdf0e10cSrcweir 		    if(m_pAdoConnection->get_State() != adStateOpen)
140cdf0e10cSrcweir                 throwGenericSQLException( STR_NO_CONNECTION,*this );
141cdf0e10cSrcweir 
142cdf0e10cSrcweir 		    WpADOProperties aProps = m_pAdoConnection->get_Properties();
143cdf0e10cSrcweir 		    if(aProps.IsValid())
144cdf0e10cSrcweir 		    {
145cdf0e10cSrcweir 			    OTools::putValue(aProps,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Jet OLEDB:ODBC Parsing")),sal_True);
146cdf0e10cSrcweir 			    OLEVariant aVar(OTools::getValue(aProps,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Jet OLEDB:Engine Type"))));
147cdf0e10cSrcweir 			    if(!aVar.isNull() && !aVar.isEmpty())
148cdf0e10cSrcweir 				    m_nEngineType = aVar;
149cdf0e10cSrcweir 		    }
150cdf0e10cSrcweir 		    buildTypeInfo();
151cdf0e10cSrcweir 		    //bErg = TRUE;
152cdf0e10cSrcweir 	    }
153cdf0e10cSrcweir 	    else
154cdf0e10cSrcweir 		    ::dbtools::throwFunctionSequenceException(*this);
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     }
157cdf0e10cSrcweir     catch(const Exception )
158cdf0e10cSrcweir     {
159cdf0e10cSrcweir         osl_decrementInterlockedCount( &m_refCount );
160cdf0e10cSrcweir         throw;
161cdf0e10cSrcweir     }
162cdf0e10cSrcweir 	osl_decrementInterlockedCount( &m_refCount );
163cdf0e10cSrcweir }
164cdf0e10cSrcweir //-----------------------------------------------------------------------------
release()165cdf0e10cSrcweir void SAL_CALL OConnection::release() throw()
166cdf0e10cSrcweir {
167cdf0e10cSrcweir 	relase_ChildImpl();
168cdf0e10cSrcweir }
169cdf0e10cSrcweir // --------------------------------------------------------------------------------
createStatement()170cdf0e10cSrcweir Reference< XStatement > SAL_CALL OConnection::createStatement(  ) throw(SQLException, RuntimeException)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
173cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 	OStatement* pStmt = new OStatement(this);
176cdf0e10cSrcweir 	Reference< XStatement > xStmt = pStmt;
177cdf0e10cSrcweir 	m_aStatements.push_back(WeakReferenceHelper(*pStmt));
178cdf0e10cSrcweir 	return pStmt;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir // --------------------------------------------------------------------------------
prepareStatement(const::rtl::OUString & sql)181cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
182cdf0e10cSrcweir {
183cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
184cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
185cdf0e10cSrcweir 
186cdf0e10cSrcweir 
187cdf0e10cSrcweir 	OPreparedStatement* pStmt = new OPreparedStatement(this,m_aTypeInfo,sql);
188cdf0e10cSrcweir 	Reference< XPreparedStatement > xPStmt = pStmt;
189cdf0e10cSrcweir 	m_aStatements.push_back(WeakReferenceHelper(*pStmt));
190cdf0e10cSrcweir 	return xPStmt;
191cdf0e10cSrcweir }
192cdf0e10cSrcweir // --------------------------------------------------------------------------------
prepareCall(const::rtl::OUString & sql)193cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
194cdf0e10cSrcweir {
195cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
196cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	OCallableStatement* pStmt = new OCallableStatement(this,m_aTypeInfo,sql);
200cdf0e10cSrcweir 	Reference< XPreparedStatement > xPStmt = pStmt;
201cdf0e10cSrcweir 	m_aStatements.push_back(WeakReferenceHelper(*pStmt));
202cdf0e10cSrcweir 	return xPStmt;
203cdf0e10cSrcweir }
204cdf0e10cSrcweir // --------------------------------------------------------------------------------
nativeSQL(const::rtl::OUString & _sql)205cdf0e10cSrcweir ::rtl::OUString SAL_CALL OConnection::nativeSQL( const ::rtl::OUString& _sql ) throw(SQLException, RuntimeException)
206cdf0e10cSrcweir {
207cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
208cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 	::rtl::OUString sql = _sql;
212cdf0e10cSrcweir 	WpADOProperties aProps = m_pAdoConnection->get_Properties();
213cdf0e10cSrcweir 	if(aProps.IsValid())
214cdf0e10cSrcweir 	{
215cdf0e10cSrcweir 		OTools::putValue(aProps,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Jet OLEDB:ODBC Parsing")),sal_True);
216cdf0e10cSrcweir 		WpADOCommand aCommand;
217cdf0e10cSrcweir 		aCommand.Create();
218cdf0e10cSrcweir 		aCommand.put_ActiveConnection((IDispatch*)*m_pAdoConnection);
219cdf0e10cSrcweir 		aCommand.put_CommandText(sql);
220cdf0e10cSrcweir 		sql = aCommand.get_CommandText();
221cdf0e10cSrcweir 	}
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 	return sql;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir // --------------------------------------------------------------------------------
setAutoCommit(sal_Bool autoCommit)226cdf0e10cSrcweir void SAL_CALL OConnection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException)
227cdf0e10cSrcweir {
228cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
229cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 
232cdf0e10cSrcweir 	m_bAutocommit = autoCommit;
233cdf0e10cSrcweir 	if(!autoCommit)
234cdf0e10cSrcweir 		m_pAdoConnection->BeginTrans();
235cdf0e10cSrcweir 	else
236cdf0e10cSrcweir 		m_pAdoConnection->RollbackTrans();
237cdf0e10cSrcweir }
238cdf0e10cSrcweir // --------------------------------------------------------------------------------
getAutoCommit()239cdf0e10cSrcweir sal_Bool SAL_CALL OConnection::getAutoCommit(  ) throw(SQLException, RuntimeException)
240cdf0e10cSrcweir {
241cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
242cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 	return m_bAutocommit;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir // --------------------------------------------------------------------------------
commit()248cdf0e10cSrcweir void SAL_CALL OConnection::commit(  ) throw(SQLException, RuntimeException)
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
251cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 	m_pAdoConnection->CommitTrans();
255cdf0e10cSrcweir }
256cdf0e10cSrcweir // --------------------------------------------------------------------------------
rollback()257cdf0e10cSrcweir void SAL_CALL OConnection::rollback(  ) throw(SQLException, RuntimeException)
258cdf0e10cSrcweir {
259cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
260cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	m_pAdoConnection->RollbackTrans();
264cdf0e10cSrcweir }
265cdf0e10cSrcweir // --------------------------------------------------------------------------------
isClosed()266cdf0e10cSrcweir sal_Bool SAL_CALL OConnection::isClosed(  ) throw(SQLException, RuntimeException)
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
269cdf0e10cSrcweir 
270cdf0e10cSrcweir 	return OConnection_BASE::rBHelper.bDisposed && !m_pAdoConnection->get_State();
271cdf0e10cSrcweir }
272cdf0e10cSrcweir // --------------------------------------------------------------------------------
getMetaData()273cdf0e10cSrcweir Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData(  ) throw(SQLException, RuntimeException)
274cdf0e10cSrcweir {
275cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
276cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 	Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
280cdf0e10cSrcweir 	if(!xMetaData.is())
281cdf0e10cSrcweir 	{
282cdf0e10cSrcweir 		xMetaData = new ODatabaseMetaData(this);
283cdf0e10cSrcweir 		m_xMetaData = xMetaData;
284cdf0e10cSrcweir 	}
285cdf0e10cSrcweir 
286cdf0e10cSrcweir 	return xMetaData;
287cdf0e10cSrcweir }
288cdf0e10cSrcweir // --------------------------------------------------------------------------------
setReadOnly(sal_Bool readOnly)289cdf0e10cSrcweir void SAL_CALL OConnection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException)
290cdf0e10cSrcweir {
291cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
292cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     m_pAdoConnection->put_Mode(readOnly ? adModeRead : adModeReadWrite);
297cdf0e10cSrcweir 	ADOS::ThrowException(*m_pAdoConnection,*this);
298cdf0e10cSrcweir }
299cdf0e10cSrcweir // --------------------------------------------------------------------------------
isReadOnly()300cdf0e10cSrcweir sal_Bool SAL_CALL OConnection::isReadOnly(  ) throw(SQLException, RuntimeException)
301cdf0e10cSrcweir {
302cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
303cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 	return m_pAdoConnection->get_Mode() == adModeRead;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir // --------------------------------------------------------------------------------
setCatalog(const::rtl::OUString & catalog)309cdf0e10cSrcweir void SAL_CALL OConnection::setCatalog( const ::rtl::OUString& catalog ) throw(SQLException, RuntimeException)
310cdf0e10cSrcweir {
311cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
312cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
313cdf0e10cSrcweir 
314cdf0e10cSrcweir 	m_pAdoConnection->PutDefaultDatabase(catalog);
315cdf0e10cSrcweir 	ADOS::ThrowException(*m_pAdoConnection,*this);
316cdf0e10cSrcweir }
317cdf0e10cSrcweir // --------------------------------------------------------------------------------
getCatalog()318cdf0e10cSrcweir ::rtl::OUString SAL_CALL OConnection::getCatalog(  ) throw(SQLException, RuntimeException)
319cdf0e10cSrcweir {
320cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
321cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 	return m_pAdoConnection->GetDefaultDatabase();
324cdf0e10cSrcweir }
325cdf0e10cSrcweir // --------------------------------------------------------------------------------
setTransactionIsolation(sal_Int32 level)326cdf0e10cSrcweir void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 level ) throw(SQLException, RuntimeException)
327cdf0e10cSrcweir {
328cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
329cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 	IsolationLevelEnum eIso;
333cdf0e10cSrcweir 	switch(level)
334cdf0e10cSrcweir 	{
335cdf0e10cSrcweir 		case TransactionIsolation::NONE:
336cdf0e10cSrcweir 			eIso = adXactUnspecified;
337cdf0e10cSrcweir 			break;
338cdf0e10cSrcweir 		case TransactionIsolation::READ_UNCOMMITTED:
339cdf0e10cSrcweir 			eIso = adXactReadUncommitted;
340cdf0e10cSrcweir 			break;
341cdf0e10cSrcweir 		case TransactionIsolation::READ_COMMITTED:
342cdf0e10cSrcweir 			eIso = adXactReadCommitted;
343cdf0e10cSrcweir 			break;
344cdf0e10cSrcweir 		case TransactionIsolation::REPEATABLE_READ:
345cdf0e10cSrcweir 			eIso = adXactRepeatableRead;
346cdf0e10cSrcweir 			break;
347cdf0e10cSrcweir 		case TransactionIsolation::SERIALIZABLE:
348cdf0e10cSrcweir 			eIso = adXactSerializable;
349cdf0e10cSrcweir 			break;
350cdf0e10cSrcweir 		default:
351cdf0e10cSrcweir 			OSL_ENSURE(0,"OConnection::setTransactionIsolation invalid level");
352cdf0e10cSrcweir 			return;
353cdf0e10cSrcweir 	}
354cdf0e10cSrcweir 	m_pAdoConnection->put_IsolationLevel(eIso);
355cdf0e10cSrcweir 	ADOS::ThrowException(*m_pAdoConnection,*this);
356cdf0e10cSrcweir }
357cdf0e10cSrcweir // --------------------------------------------------------------------------------
getTransactionIsolation()358cdf0e10cSrcweir sal_Int32 SAL_CALL OConnection::getTransactionIsolation(  ) throw(SQLException, RuntimeException)
359cdf0e10cSrcweir {
360cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
361cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 
364cdf0e10cSrcweir 	sal_Int32 nRet = 0;
365cdf0e10cSrcweir 	switch(m_pAdoConnection->get_IsolationLevel())
366cdf0e10cSrcweir 	{
367cdf0e10cSrcweir 		case adXactUnspecified:
368cdf0e10cSrcweir 			nRet = TransactionIsolation::NONE;
369cdf0e10cSrcweir 			break;
370cdf0e10cSrcweir 		case adXactReadUncommitted:
371cdf0e10cSrcweir 			nRet = TransactionIsolation::READ_UNCOMMITTED;
372cdf0e10cSrcweir 			break;
373cdf0e10cSrcweir 		case adXactReadCommitted:
374cdf0e10cSrcweir 			nRet = TransactionIsolation::READ_COMMITTED;
375cdf0e10cSrcweir 			break;
376cdf0e10cSrcweir 		case adXactRepeatableRead:
377cdf0e10cSrcweir 			nRet = TransactionIsolation::REPEATABLE_READ;
378cdf0e10cSrcweir 			break;
379cdf0e10cSrcweir 		case adXactSerializable:
380cdf0e10cSrcweir 			nRet = TransactionIsolation::SERIALIZABLE;
381cdf0e10cSrcweir 			break;
382cdf0e10cSrcweir 		default:
383cdf0e10cSrcweir 			OSL_ENSURE(0,"OConnection::setTransactionIsolation invalid level");
384cdf0e10cSrcweir 	}
385cdf0e10cSrcweir 	ADOS::ThrowException(*m_pAdoConnection,*this);
386cdf0e10cSrcweir 	return nRet;
387cdf0e10cSrcweir }
388cdf0e10cSrcweir // --------------------------------------------------------------------------------
getTypeMap()389cdf0e10cSrcweir Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getTypeMap(  ) throw(SQLException, RuntimeException)
390cdf0e10cSrcweir {
391cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
392cdf0e10cSrcweir 	checkDisposed(OConnection_BASE::rBHelper.bDisposed);
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 	return NULL;
396cdf0e10cSrcweir }
397cdf0e10cSrcweir // --------------------------------------------------------------------------------
setTypeMap(const Reference<::com::sun::star::container::XNameAccess> &)398cdf0e10cSrcweir void SAL_CALL OConnection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
399cdf0e10cSrcweir {
400cdf0e10cSrcweir     ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
401cdf0e10cSrcweir }
402cdf0e10cSrcweir // --------------------------------------------------------------------------------
403cdf0e10cSrcweir // XCloseable
close()404cdf0e10cSrcweir void SAL_CALL OConnection::close(  ) throw(SQLException, RuntimeException)
405cdf0e10cSrcweir {
406cdf0e10cSrcweir 	{
407cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
408cdf0e10cSrcweir 		checkDisposed(OConnection_BASE::rBHelper.bDisposed);
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 	}
411cdf0e10cSrcweir 	dispose();
412cdf0e10cSrcweir }
413cdf0e10cSrcweir // --------------------------------------------------------------------------------
414cdf0e10cSrcweir // XWarningsSupplier
getWarnings()415cdf0e10cSrcweir Any SAL_CALL OConnection::getWarnings(  ) throw(SQLException, RuntimeException)
416cdf0e10cSrcweir {
417cdf0e10cSrcweir 	return Any();
418cdf0e10cSrcweir }
419cdf0e10cSrcweir // --------------------------------------------------------------------------------
clearWarnings()420cdf0e10cSrcweir void SAL_CALL OConnection::clearWarnings(  ) throw(SQLException, RuntimeException)
421cdf0e10cSrcweir {
422cdf0e10cSrcweir }
423cdf0e10cSrcweir //--------------------------------------------------------------------
buildTypeInfo()424cdf0e10cSrcweir void OConnection::buildTypeInfo() throw( SQLException)
425cdf0e10cSrcweir {
426cdf0e10cSrcweir 	::osl::MutexGuard aGuard( m_aMutex );
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 	ADORecordset *pRecordset = m_pAdoConnection->getTypeInfo();
429cdf0e10cSrcweir 	if ( pRecordset )
430cdf0e10cSrcweir 	{
431cdf0e10cSrcweir 		pRecordset->AddRef();
432cdf0e10cSrcweir 		VARIANT_BOOL bIsAtBOF;
433cdf0e10cSrcweir 		pRecordset->get_BOF(&bIsAtBOF);
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 		sal_Bool bOk = sal_True;
436cdf0e10cSrcweir 		if ( bIsAtBOF == VARIANT_TRUE )
437cdf0e10cSrcweir 			bOk = SUCCEEDED(pRecordset->MoveNext());
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 		if ( bOk )
440cdf0e10cSrcweir 		{
441cdf0e10cSrcweir 			// HACK for access
442cdf0e10cSrcweir 			static const ::rtl::OUString s_sVarChar(RTL_CONSTASCII_USTRINGPARAM("VarChar"));
443cdf0e10cSrcweir 			do
444cdf0e10cSrcweir 			{
445cdf0e10cSrcweir 				sal_Int32 nPos = 1;
446cdf0e10cSrcweir 				OExtendedTypeInfo* aInfo			= new OExtendedTypeInfo();
447cdf0e10cSrcweir 				aInfo->aSimpleType.aTypeName		= ADOS::getField(pRecordset,nPos++).get_Value();
448cdf0e10cSrcweir 				aInfo->eType						= (DataTypeEnum)(sal_Int32)ADOS::getField(pRecordset,nPos++).get_Value();
449cdf0e10cSrcweir 				if ( aInfo->eType == adWChar && aInfo->aSimpleType.aTypeName == s_sVarChar )
450cdf0e10cSrcweir 					aInfo->eType = adVarWChar;
451cdf0e10cSrcweir 				aInfo->aSimpleType.nType			= (sal_Int16)ADOS::MapADOType2Jdbc(static_cast<DataTypeEnum>(aInfo->eType));
452cdf0e10cSrcweir 				aInfo->aSimpleType.nPrecision		= ADOS::getField(pRecordset,nPos++).get_Value();
453cdf0e10cSrcweir 				aInfo->aSimpleType.aLiteralPrefix	= ADOS::getField(pRecordset,nPos++).get_Value();
454cdf0e10cSrcweir 				aInfo->aSimpleType.aLiteralSuffix	= ADOS::getField(pRecordset,nPos++).get_Value();
455cdf0e10cSrcweir 				aInfo->aSimpleType.aCreateParams	= ADOS::getField(pRecordset,nPos++).get_Value();
456cdf0e10cSrcweir 				aInfo->aSimpleType.bNullable		= ADOS::getField(pRecordset,nPos++).get_Value();
457cdf0e10cSrcweir 				aInfo->aSimpleType.bCaseSensitive	= ADOS::getField(pRecordset,nPos++).get_Value();
458cdf0e10cSrcweir 				aInfo->aSimpleType.nSearchType		= ADOS::getField(pRecordset,nPos++).get_Value();
459cdf0e10cSrcweir 				aInfo->aSimpleType.bUnsigned		= ADOS::getField(pRecordset,nPos++).get_Value();
460cdf0e10cSrcweir 				aInfo->aSimpleType.bCurrency		= ADOS::getField(pRecordset,nPos++).get_Value();
461cdf0e10cSrcweir 				aInfo->aSimpleType.bAutoIncrement	= ADOS::getField(pRecordset,nPos++).get_Value();
462cdf0e10cSrcweir 				aInfo->aSimpleType.aLocalTypeName	= ADOS::getField(pRecordset,nPos++).get_Value();
463cdf0e10cSrcweir 				aInfo->aSimpleType.nMinimumScale	= ADOS::getField(pRecordset,nPos++).get_Value();
464cdf0e10cSrcweir 				aInfo->aSimpleType.nMaximumScale	= ADOS::getField(pRecordset,nPos++).get_Value();
465cdf0e10cSrcweir                 if ( adCurrency == aInfo->eType && !aInfo->aSimpleType.nMaximumScale)
466cdf0e10cSrcweir                 {
467cdf0e10cSrcweir                     aInfo->aSimpleType.nMinimumScale = 4;
468cdf0e10cSrcweir                     aInfo->aSimpleType.nMaximumScale = 4;
469cdf0e10cSrcweir                 }
470cdf0e10cSrcweir 				aInfo->aSimpleType.nNumPrecRadix	= ADOS::getField(pRecordset,nPos++).get_Value();
471cdf0e10cSrcweir 				// Now that we have the type info, save it
472cdf0e10cSrcweir 				// in the Hashtable if we don't already have an
473cdf0e10cSrcweir 				// entry for this SQL type.
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 				m_aTypeInfo.insert(OTypeInfoMap::value_type(aInfo->eType,aInfo));
476cdf0e10cSrcweir 			}
477cdf0e10cSrcweir 			while ( SUCCEEDED(pRecordset->MoveNext()) );
478cdf0e10cSrcweir 		}
479cdf0e10cSrcweir 		pRecordset->Release();
480cdf0e10cSrcweir 	}
481cdf0e10cSrcweir }
482cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing()483cdf0e10cSrcweir void OConnection::disposing()
484cdf0e10cSrcweir {
485cdf0e10cSrcweir 	::osl::MutexGuard aGuard(m_aMutex);
486cdf0e10cSrcweir 
487cdf0e10cSrcweir     OConnection_BASE::disposing();
488cdf0e10cSrcweir 
489cdf0e10cSrcweir 	m_bClosed	= sal_True;
490cdf0e10cSrcweir 	m_xMetaData = ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDatabaseMetaData>();
491cdf0e10cSrcweir 	m_xCatalog  = ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbcx::XTablesSupplier>();
492cdf0e10cSrcweir 	m_pDriver	= NULL;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 	m_pAdoConnection->Close();
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 	OTypeInfoMap::iterator aIter = m_aTypeInfo.begin();
497cdf0e10cSrcweir 	for (; aIter != m_aTypeInfo.end(); ++aIter)
498cdf0e10cSrcweir 		delete aIter->second;
499cdf0e10cSrcweir 
500cdf0e10cSrcweir 	m_aTypeInfo.clear();
501cdf0e10cSrcweir 
502cdf0e10cSrcweir 	delete m_pAdoConnection;
503cdf0e10cSrcweir 	m_pAdoConnection = NULL;
504cdf0e10cSrcweir 
505cdf0e10cSrcweir 	dispose_ChildImpl();
506cdf0e10cSrcweir }
507cdf0e10cSrcweir // -----------------------------------------------------------------------------
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & rId)508cdf0e10cSrcweir sal_Int64 SAL_CALL OConnection::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException)
509cdf0e10cSrcweir {
510cdf0e10cSrcweir 	return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
511cdf0e10cSrcweir 				?
512cdf0e10cSrcweir 			reinterpret_cast< sal_Int64 >( this )
513cdf0e10cSrcweir 				:
514cdf0e10cSrcweir 			OConnection_BASE::getSomething(rId);
515cdf0e10cSrcweir }
516cdf0e10cSrcweir // -----------------------------------------------------------------------------
getUnoTunnelImplementationId()517cdf0e10cSrcweir Sequence< sal_Int8 > OConnection::getUnoTunnelImplementationId()
518cdf0e10cSrcweir {
519cdf0e10cSrcweir 	static ::cppu::OImplementationId * pId = 0;
520cdf0e10cSrcweir 	if (! pId)
521cdf0e10cSrcweir 	{
522cdf0e10cSrcweir 		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
523cdf0e10cSrcweir 		if (! pId)
524cdf0e10cSrcweir 		{
525cdf0e10cSrcweir 			static ::cppu::OImplementationId aId;
526cdf0e10cSrcweir 			pId = &aId;
527cdf0e10cSrcweir 		}
528cdf0e10cSrcweir 	}
529cdf0e10cSrcweir 	return pId->getImplementationId();
530cdf0e10cSrcweir }
531cdf0e10cSrcweir // -----------------------------------------------------------------------------
getTypeInfoFromType(const OTypeInfoMap & _rTypeInfo,DataTypeEnum _nType,const::rtl::OUString & _sTypeName,sal_Int32 _nPrecision,sal_Int32 _nScale,sal_Bool & _brForceToType)532cdf0e10cSrcweir const OExtendedTypeInfo* OConnection::getTypeInfoFromType(const OTypeInfoMap& _rTypeInfo,
533cdf0e10cSrcweir 						   DataTypeEnum _nType,
534cdf0e10cSrcweir 						   const ::rtl::OUString& _sTypeName,
535cdf0e10cSrcweir 						   sal_Int32 _nPrecision,
536cdf0e10cSrcweir 						   sal_Int32 _nScale,
537cdf0e10cSrcweir 						   sal_Bool& _brForceToType)
538cdf0e10cSrcweir {
539cdf0e10cSrcweir 	const OExtendedTypeInfo* pTypeInfo = NULL;
540cdf0e10cSrcweir 	_brForceToType = sal_False;
541cdf0e10cSrcweir 	// search for type
542cdf0e10cSrcweir 	::std::pair<OTypeInfoMap::const_iterator, OTypeInfoMap::const_iterator> aPair = _rTypeInfo.equal_range(_nType);
543cdf0e10cSrcweir 	OTypeInfoMap::const_iterator aIter = aPair.first;
544cdf0e10cSrcweir 	if(aIter != _rTypeInfo.end()) // compare with end is correct here
545cdf0e10cSrcweir 	{
546cdf0e10cSrcweir 		for(;aIter != aPair.second;++aIter)
547cdf0e10cSrcweir 		{
548cdf0e10cSrcweir 			// search the best matching type
549cdf0e10cSrcweir 			OExtendedTypeInfo* pInfo = aIter->second;
550cdf0e10cSrcweir 	#ifdef DBG_UTIL
551cdf0e10cSrcweir 			::rtl::OUString sDBTypeName = pInfo->aSimpleType.aTypeName;
552cdf0e10cSrcweir             sal_Int32       nDBTypePrecision = pInfo->aSimpleType.nPrecision;   (void)nDBTypePrecision;
553cdf0e10cSrcweir             sal_Int32       nDBTypeScale = pInfo->aSimpleType.nMaximumScale;    (void)nDBTypeScale;
554cdf0e10cSrcweir             sal_Int32       nAdoType = pInfo->eType;                            (void)nAdoType;
555cdf0e10cSrcweir 	#endif
556cdf0e10cSrcweir 			if	(	(	!_sTypeName.getLength()
557cdf0e10cSrcweir 					||	(pInfo->aSimpleType.aTypeName.equalsIgnoreAsciiCase(_sTypeName))
558cdf0e10cSrcweir 					)
559cdf0e10cSrcweir 				&&	(pInfo->aSimpleType.nPrecision		>= _nPrecision)
560cdf0e10cSrcweir 				&&	(pInfo->aSimpleType.nMaximumScale	>= _nScale)
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 				)
563cdf0e10cSrcweir 				break;
564cdf0e10cSrcweir 		}
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 		if (aIter == aPair.second)
567cdf0e10cSrcweir 		{
568cdf0e10cSrcweir 			for(aIter = aPair.first; aIter != aPair.second; ++aIter)
569cdf0e10cSrcweir 			{
570cdf0e10cSrcweir 				// search the best matching type (now comparing the local names)
571cdf0e10cSrcweir 				if	(	(aIter->second->aSimpleType.aLocalTypeName.equalsIgnoreAsciiCase(_sTypeName))
572cdf0e10cSrcweir 					&&	(aIter->second->aSimpleType.nPrecision		>= _nPrecision)
573cdf0e10cSrcweir 					&&	(aIter->second->aSimpleType.nMaximumScale	>= _nScale)
574cdf0e10cSrcweir 					)
575cdf0e10cSrcweir 				{
576cdf0e10cSrcweir // we can not assert here because we could be in d&d
577cdf0e10cSrcweir /*
578cdf0e10cSrcweir 					OSL_ENSURE(sal_False,
579cdf0e10cSrcweir 						(	::rtl::OString("getTypeInfoFromType: assuming column type ")
580cdf0e10cSrcweir 						+=	::rtl::OString(aIter->second->aTypeName.getStr(), aIter->second->aTypeName.getLength(), gsl_getSystemTextEncoding())
581cdf0e10cSrcweir 						+=	::rtl::OString("\" (expected type name ")
582cdf0e10cSrcweir 						+=	::rtl::OString(_sTypeName.getStr(), _sTypeName.getLength(), gsl_getSystemTextEncoding())
583cdf0e10cSrcweir 						+=	::rtl::OString(" matches the type's local name).")).getStr());
584cdf0e10cSrcweir */
585cdf0e10cSrcweir 					break;
586cdf0e10cSrcweir 				}
587cdf0e10cSrcweir 			}
588cdf0e10cSrcweir 		}
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 		if (aIter == aPair.second)
591cdf0e10cSrcweir 		{	// no match for the names, no match for the local names
592cdf0e10cSrcweir 			// -> drop the precision and the scale restriction, accept any type with the property
593cdf0e10cSrcweir 			// type id (nType)
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 			// we can not assert here because we could be in d&d
596cdf0e10cSrcweir 			pTypeInfo = aPair.first->second;
597cdf0e10cSrcweir 			_brForceToType = sal_True;
598cdf0e10cSrcweir 		}
599cdf0e10cSrcweir 		else
600cdf0e10cSrcweir 			pTypeInfo = aIter->second;
601cdf0e10cSrcweir 	}
602cdf0e10cSrcweir 	else if ( _sTypeName.getLength() )
603cdf0e10cSrcweir 	{
604cdf0e10cSrcweir 		::comphelper::TStringMixEqualFunctor aCase(sal_False);
605cdf0e10cSrcweir 		// search for typeinfo where the typename is equal _sTypeName
606cdf0e10cSrcweir 		OTypeInfoMap::const_iterator aFind = ::std::find_if(_rTypeInfo.begin(),
607cdf0e10cSrcweir 															_rTypeInfo.end(),
608cdf0e10cSrcweir 															::std::compose1(
609cdf0e10cSrcweir 																::std::bind2nd(aCase, _sTypeName),
610cdf0e10cSrcweir 																::std::compose1(
611cdf0e10cSrcweir 																	::std::mem_fun(&OExtendedTypeInfo::getDBName),
612cdf0e10cSrcweir 																	::std::select2nd<OTypeInfoMap::value_type>())
613cdf0e10cSrcweir 																)
614cdf0e10cSrcweir 															);
615cdf0e10cSrcweir 		if(aFind != _rTypeInfo.end())
616cdf0e10cSrcweir 			pTypeInfo = aFind->second;
617cdf0e10cSrcweir 	}
618cdf0e10cSrcweir 
619cdf0e10cSrcweir // we can not assert here because we could be in d&d
620cdf0e10cSrcweir //	OSL_ENSURE(pTypeInfo, "getTypeInfoFromType: no type info found for this type!");
621cdf0e10cSrcweir 	return pTypeInfo;
622cdf0e10cSrcweir }
623cdf0e10cSrcweir // -----------------------------------------------------------------------------
624cdf0e10cSrcweir 
625cdf0e10cSrcweir 
626cdf0e10cSrcweir 
627