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