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 "odbc/OTools.hxx"
27cdf0e10cSrcweir #include "odbc/OConnection.hxx"
28cdf0e10cSrcweir #include "odbc/ODatabaseMetaData.hxx"
29cdf0e10cSrcweir #include "odbc/OFunctions.hxx"
30cdf0e10cSrcweir #include "odbc/ODriver.hxx"
31cdf0e10cSrcweir #include "odbc/OStatement.hxx"
32cdf0e10cSrcweir #include "odbc/OPreparedStatement.hxx"
33cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
34cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
35cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
36cdf0e10cSrcweir #include <connectivity/dbcharset.hxx>
37cdf0e10cSrcweir #include <connectivity/FValue.hxx>
38cdf0e10cSrcweir #include <comphelper/extract.hxx>
39cdf0e10cSrcweir #include "diagnose_ex.h"
40cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
41cdf0e10cSrcweir
42cdf0e10cSrcweir #include <string.h>
43cdf0e10cSrcweir
44cdf0e10cSrcweir using namespace connectivity::odbc;
45cdf0e10cSrcweir using namespace connectivity;
46cdf0e10cSrcweir using namespace dbtools;
47cdf0e10cSrcweir
48cdf0e10cSrcweir //------------------------------------------------------------------------------
49cdf0e10cSrcweir using namespace com::sun::star::uno;
50cdf0e10cSrcweir using namespace com::sun::star::lang;
51cdf0e10cSrcweir using namespace com::sun::star::beans;
52cdf0e10cSrcweir using namespace com::sun::star::sdbc;
53cdf0e10cSrcweir // --------------------------------------------------------------------------------
OConnection(const SQLHANDLE _pDriverHandle,ODBCDriver * _pDriver)54cdf0e10cSrcweir OConnection::OConnection(const SQLHANDLE _pDriverHandle,ODBCDriver* _pDriver)
55cdf0e10cSrcweir : OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)_pDriver, this)
56cdf0e10cSrcweir ,m_pDriver(_pDriver)
57cdf0e10cSrcweir ,m_pDriverHandleCopy(_pDriverHandle)
58cdf0e10cSrcweir ,m_nStatementCount(0)
59cdf0e10cSrcweir ,m_bClosed(sal_True)
60cdf0e10cSrcweir ,m_bUseCatalog(sal_False)
61cdf0e10cSrcweir ,m_bUseOldDateFormat(sal_False)
62cdf0e10cSrcweir ,m_bParameterSubstitution(sal_False)
63cdf0e10cSrcweir ,m_bIgnoreDriverPrivileges(sal_False)
64cdf0e10cSrcweir ,m_bPreventGetVersionColumns(sal_False)
65cdf0e10cSrcweir ,m_bReadOnly(sal_True)
66cdf0e10cSrcweir {
67cdf0e10cSrcweir m_pDriver->acquire();
68cdf0e10cSrcweir }
69cdf0e10cSrcweir //-----------------------------------------------------------------------------
~OConnection()70cdf0e10cSrcweir OConnection::~OConnection()
71cdf0e10cSrcweir {
72cdf0e10cSrcweir if(!isClosed( ))
73cdf0e10cSrcweir close();
74cdf0e10cSrcweir
75cdf0e10cSrcweir if ( SQL_NULL_HANDLE != m_aConnectionHandle )
76cdf0e10cSrcweir N3SQLFreeHandle( SQL_HANDLE_DBC, m_aConnectionHandle );
77cdf0e10cSrcweir m_aConnectionHandle = SQL_NULL_HANDLE;
78cdf0e10cSrcweir
79cdf0e10cSrcweir m_pDriver->release();
80cdf0e10cSrcweir m_pDriver = NULL;
81cdf0e10cSrcweir }
82cdf0e10cSrcweir //-----------------------------------------------------------------------------
release()83cdf0e10cSrcweir void SAL_CALL OConnection::release() throw()
84cdf0e10cSrcweir {
85cdf0e10cSrcweir relase_ChildImpl();
86cdf0e10cSrcweir }
87cdf0e10cSrcweir // -----------------------------------------------------------------------------
getOdbcFunction(sal_Int32 _nIndex) const88cdf0e10cSrcweir oslGenericFunction OConnection::getOdbcFunction(sal_Int32 _nIndex) const
89cdf0e10cSrcweir {
90cdf0e10cSrcweir OSL_ENSURE(m_pDriver,"OConnection::getOdbcFunction: m_pDriver is null!");
91cdf0e10cSrcweir return m_pDriver->getOdbcFunction(_nIndex);
92cdf0e10cSrcweir }
93cdf0e10cSrcweir //-----------------------------------------------------------------------------
OpenConnection(const::rtl::OUString & aConnectStr,sal_Int32 nTimeOut,sal_Bool bSilent)94cdf0e10cSrcweir SQLRETURN OConnection::OpenConnection(const ::rtl::OUString& aConnectStr,sal_Int32 nTimeOut, sal_Bool bSilent)
95cdf0e10cSrcweir {
96cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
97cdf0e10cSrcweir
98cdf0e10cSrcweir if (m_aConnectionHandle == SQL_NULL_HANDLE)
99cdf0e10cSrcweir return -1;
100cdf0e10cSrcweir
101cdf0e10cSrcweir SQLRETURN nSQLRETURN = 0;
102cdf0e10cSrcweir SDB_ODBC_CHAR szConnStrOut[4096];
103cdf0e10cSrcweir SDB_ODBC_CHAR szConnStrIn[2048];
104cdf0e10cSrcweir SQLSMALLINT cbConnStrOut;
105cdf0e10cSrcweir memset(szConnStrOut,'\0',4096);
106cdf0e10cSrcweir memset(szConnStrIn,'\0',2048);
107cdf0e10cSrcweir ::rtl::OString aConStr(::rtl::OUStringToOString(aConnectStr,getTextEncoding()));
108cdf0e10cSrcweir memcpy(szConnStrIn, (SDB_ODBC_CHAR*) aConStr.getStr(), ::std::min<sal_Int32>((sal_Int32)2048,aConStr.getLength()));
109cdf0e10cSrcweir
110cdf0e10cSrcweir #ifndef MACOSX
111cdf0e10cSrcweir N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_LOGIN_TIMEOUT,(SQLPOINTER)nTimeOut,SQL_IS_UINTEGER);
112cdf0e10cSrcweir // Verbindung aufbauen
113cdf0e10cSrcweir #endif
114cdf0e10cSrcweir
115cdf0e10cSrcweir #ifdef LINUX
116cdf0e10cSrcweir OSL_UNUSED( bSilent );
117cdf0e10cSrcweir nSQLRETURN = N3SQLDriverConnect(m_aConnectionHandle,
118cdf0e10cSrcweir NULL,
119cdf0e10cSrcweir szConnStrIn,
120cdf0e10cSrcweir (SQLSMALLINT) ::std::min((sal_Int32)2048,aConStr.getLength()),
121cdf0e10cSrcweir szConnStrOut,
122cdf0e10cSrcweir (SQLSMALLINT) (sizeof(szConnStrOut)/sizeof(SDB_ODBC_CHAR)) -1,
123cdf0e10cSrcweir &cbConnStrOut,
124cdf0e10cSrcweir SQL_DRIVER_NOPROMPT);
125cdf0e10cSrcweir if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA || SQL_SUCCESS_WITH_INFO == nSQLRETURN)
126cdf0e10cSrcweir return nSQLRETURN;
127cdf0e10cSrcweir #else
128cdf0e10cSrcweir
129cdf0e10cSrcweir SQLUSMALLINT nSilent = bSilent ? SQL_DRIVER_NOPROMPT : SQL_DRIVER_COMPLETE;
130cdf0e10cSrcweir nSQLRETURN = N3SQLDriverConnect(m_aConnectionHandle,
131cdf0e10cSrcweir NULL,
132cdf0e10cSrcweir szConnStrIn,
133cdf0e10cSrcweir (SQLSMALLINT) ::std::min<sal_Int32>((sal_Int32)2048,aConStr.getLength()),
134cdf0e10cSrcweir szConnStrOut,
135cdf0e10cSrcweir (SQLSMALLINT) sizeof szConnStrOut,
136cdf0e10cSrcweir &cbConnStrOut,
137cdf0e10cSrcweir nSilent);
138cdf0e10cSrcweir if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA)
139cdf0e10cSrcweir return nSQLRETURN;
140cdf0e10cSrcweir
141cdf0e10cSrcweir m_bClosed = sal_False;
142cdf0e10cSrcweir
143cdf0e10cSrcweir #endif //LINUX
144cdf0e10cSrcweir
145cdf0e10cSrcweir try
146cdf0e10cSrcweir {
147cdf0e10cSrcweir ::rtl::OUString aVal;
148cdf0e10cSrcweir OTools::GetInfo(this,m_aConnectionHandle,SQL_DATA_SOURCE_READ_ONLY,aVal,*this,getTextEncoding());
149cdf0e10cSrcweir m_bReadOnly = !aVal.compareToAscii("Y");
150cdf0e10cSrcweir }
151cdf0e10cSrcweir catch(Exception&)
152cdf0e10cSrcweir {
153cdf0e10cSrcweir m_bReadOnly = sal_True;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir try
156cdf0e10cSrcweir {
157cdf0e10cSrcweir ::rtl::OUString sVersion;
158cdf0e10cSrcweir OTools::GetInfo(this,m_aConnectionHandle,SQL_DRIVER_ODBC_VER,sVersion,*this,getTextEncoding());
159cdf0e10cSrcweir m_bUseOldDateFormat = sVersion == ::rtl::OUString::createFromAscii("02.50") || sVersion == ::rtl::OUString::createFromAscii("02.00");
160cdf0e10cSrcweir }
161cdf0e10cSrcweir catch(Exception&)
162cdf0e10cSrcweir {
163cdf0e10cSrcweir }
164cdf0e10cSrcweir
165cdf0e10cSrcweir
166cdf0e10cSrcweir // autocoomit ist immer default
167cdf0e10cSrcweir
168cdf0e10cSrcweir if (!m_bReadOnly)
169cdf0e10cSrcweir N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON,SQL_IS_INTEGER);
170cdf0e10cSrcweir
171cdf0e10cSrcweir return nSQLRETURN;
172cdf0e10cSrcweir }
173cdf0e10cSrcweir //-----------------------------------------------------------------------------
Construct(const::rtl::OUString & url,const Sequence<PropertyValue> & info)174cdf0e10cSrcweir SQLRETURN OConnection::Construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) throw(SQLException)
175cdf0e10cSrcweir {
176cdf0e10cSrcweir m_aConnectionHandle = SQL_NULL_HANDLE;
177cdf0e10cSrcweir m_sURL = url;
178cdf0e10cSrcweir setConnectionInfo(info);
179cdf0e10cSrcweir
180cdf0e10cSrcweir // Connection allozieren
181cdf0e10cSrcweir N3SQLAllocHandle(SQL_HANDLE_DBC,m_pDriverHandleCopy,&m_aConnectionHandle);
182cdf0e10cSrcweir if(m_aConnectionHandle == SQL_NULL_HANDLE)
183cdf0e10cSrcweir throw SQLException();
184cdf0e10cSrcweir
185cdf0e10cSrcweir sal_Int32 nLen = url.indexOf(':');
186cdf0e10cSrcweir nLen = url.indexOf(':',nLen+1);
187cdf0e10cSrcweir ::rtl::OUString aDSN(RTL_CONSTASCII_USTRINGPARAM("DSN=")), aUID, aPWD, aSysDrvSettings;
188cdf0e10cSrcweir aDSN += url.copy(nLen+1);
189cdf0e10cSrcweir
190cdf0e10cSrcweir const char* pUser = "user";
191cdf0e10cSrcweir const char* pTimeout = "Timeout";
192cdf0e10cSrcweir const char* pSilent = "Silent";
193cdf0e10cSrcweir const char* pPwd = "password";
194cdf0e10cSrcweir const char* pUseCatalog = "UseCatalog";
195cdf0e10cSrcweir const char* pSysDrv = "SystemDriverSettings";
196cdf0e10cSrcweir const char* pCharSet = "CharSet";
197cdf0e10cSrcweir const char* pParaName = "ParameterNameSubstitution";
198cdf0e10cSrcweir const char* pPrivName = "IgnoreDriverPrivileges";
199cdf0e10cSrcweir const char* pVerColName = "PreventGetVersionColumns"; // #i60273#
200cdf0e10cSrcweir const char* pRetrieving = "IsAutoRetrievingEnabled";
201cdf0e10cSrcweir const char* pRetriStmt = "AutoRetrievingStatement";
202cdf0e10cSrcweir
203cdf0e10cSrcweir sal_Int32 nTimeout = 20;
204cdf0e10cSrcweir sal_Bool bSilent = sal_True;
205cdf0e10cSrcweir const PropertyValue *pBegin = info.getConstArray();
206cdf0e10cSrcweir const PropertyValue *pEnd = pBegin + info.getLength();
207cdf0e10cSrcweir for(;pBegin != pEnd;++pBegin)
208cdf0e10cSrcweir {
209cdf0e10cSrcweir if(!pBegin->Name.compareToAscii(pTimeout))
210cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= nTimeout );
211cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pSilent))
212cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= bSilent );
213cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pPrivName))
214cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= m_bIgnoreDriverPrivileges );
215cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pVerColName))
216cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= m_bPreventGetVersionColumns );
217cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pParaName))
218cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= m_bParameterSubstitution );
219cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pRetrieving))
220cdf0e10cSrcweir {
221cdf0e10cSrcweir sal_Bool bAutoRetrievingEnabled = sal_False;
222cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= bAutoRetrievingEnabled );
223cdf0e10cSrcweir enableAutoRetrievingEnabled(bAutoRetrievingEnabled);
224cdf0e10cSrcweir }
225cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pRetriStmt))
226cdf0e10cSrcweir {
227cdf0e10cSrcweir ::rtl::OUString sGeneratedValueStatement;
228cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= sGeneratedValueStatement );
229cdf0e10cSrcweir setAutoRetrievingStatement(sGeneratedValueStatement);
230cdf0e10cSrcweir }
231cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pUser))
232cdf0e10cSrcweir {
233cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= aUID );
234cdf0e10cSrcweir aDSN = aDSN + ::rtl::OUString::createFromAscii(";UID=") + aUID;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pPwd))
237cdf0e10cSrcweir {
238cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= aPWD );
239cdf0e10cSrcweir aDSN = aDSN + ::rtl::OUString::createFromAscii(";PWD=") + aPWD;
240cdf0e10cSrcweir }
241cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pUseCatalog))
242cdf0e10cSrcweir {
243cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= m_bUseCatalog );
244cdf0e10cSrcweir }
245cdf0e10cSrcweir else if(!pBegin->Name.compareToAscii(pSysDrv))
246cdf0e10cSrcweir {
247cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= aSysDrvSettings );
248cdf0e10cSrcweir aDSN += ::rtl::OUString::createFromAscii(";");
249cdf0e10cSrcweir aDSN += aSysDrvSettings;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir else if(0 == pBegin->Name.compareToAscii(pCharSet))
252cdf0e10cSrcweir {
253cdf0e10cSrcweir ::rtl::OUString sIanaName;
254cdf0e10cSrcweir OSL_VERIFY( pBegin->Value >>= sIanaName );
255cdf0e10cSrcweir
256cdf0e10cSrcweir ::dbtools::OCharsetMap aLookupIanaName;
257cdf0e10cSrcweir ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.find(sIanaName, ::dbtools::OCharsetMap::IANA());
258cdf0e10cSrcweir if (aLookup != aLookupIanaName.end())
259cdf0e10cSrcweir m_nTextEncoding = (*aLookup).getEncoding();
260cdf0e10cSrcweir else
261cdf0e10cSrcweir m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW;
262cdf0e10cSrcweir if(m_nTextEncoding == RTL_TEXTENCODING_DONTKNOW)
263cdf0e10cSrcweir m_nTextEncoding = osl_getThreadTextEncoding();
264cdf0e10cSrcweir }
265cdf0e10cSrcweir }
266cdf0e10cSrcweir m_sUser = aUID;
267cdf0e10cSrcweir
268cdf0e10cSrcweir SQLRETURN nSQLRETURN = OpenConnection(aDSN,nTimeout, bSilent);
269cdf0e10cSrcweir if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA)
270cdf0e10cSrcweir {
271cdf0e10cSrcweir OTools::ThrowException(this,nSQLRETURN,m_aConnectionHandle,SQL_HANDLE_DBC,*this,sal_False);
272cdf0e10cSrcweir }
273cdf0e10cSrcweir return nSQLRETURN;
274cdf0e10cSrcweir }
275cdf0e10cSrcweir // XServiceInfo
276cdf0e10cSrcweir // --------------------------------------------------------------------------------
277cdf0e10cSrcweir IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.odbc.OConnection", "com.sun.star.sdbc.Connection")
278cdf0e10cSrcweir
279cdf0e10cSrcweir // --------------------------------------------------------------------------------
createStatement()280cdf0e10cSrcweir Reference< XStatement > SAL_CALL OConnection::createStatement( ) throw(SQLException, RuntimeException)
281cdf0e10cSrcweir {
282cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
283cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
284cdf0e10cSrcweir
285cdf0e10cSrcweir Reference< XStatement > xReturn = new OStatement(this);
286cdf0e10cSrcweir m_aStatements.push_back(WeakReferenceHelper(xReturn));
287cdf0e10cSrcweir return xReturn;
288cdf0e10cSrcweir }
289cdf0e10cSrcweir // --------------------------------------------------------------------------------
prepareStatement(const::rtl::OUString & sql)290cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
293cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
294cdf0e10cSrcweir
295cdf0e10cSrcweir Reference< XPreparedStatement > xReturn = new OPreparedStatement(this,sql);
296cdf0e10cSrcweir m_aStatements.push_back(WeakReferenceHelper(xReturn));
297cdf0e10cSrcweir return xReturn;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir // --------------------------------------------------------------------------------
prepareCall(const::rtl::OUString &)300cdf0e10cSrcweir Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) throw(SQLException, RuntimeException)
301cdf0e10cSrcweir {
302cdf0e10cSrcweir ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
303cdf0e10cSrcweir return NULL;
304cdf0e10cSrcweir }
305cdf0e10cSrcweir // --------------------------------------------------------------------------------
nativeSQL(const::rtl::OUString & sql)306cdf0e10cSrcweir ::rtl::OUString SAL_CALL OConnection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
307cdf0e10cSrcweir {
308cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
309cdf0e10cSrcweir
310cdf0e10cSrcweir ::rtl::OString aSql(::rtl::OUStringToOString(sql.getStr(),getTextEncoding()));
311cdf0e10cSrcweir char pOut[2048];
312cdf0e10cSrcweir SQLINTEGER nOutLen;
313cdf0e10cSrcweir OTools::ThrowException(this,N3SQLNativeSql(m_aConnectionHandle,(SDB_ODBC_CHAR*)aSql.getStr(),aSql.getLength(),(SDB_ODBC_CHAR*)pOut,sizeof pOut - 1,&nOutLen),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
314cdf0e10cSrcweir return ::rtl::OUString(pOut,nOutLen,getTextEncoding());
315cdf0e10cSrcweir }
316cdf0e10cSrcweir // --------------------------------------------------------------------------------
setAutoCommit(sal_Bool autoCommit)317cdf0e10cSrcweir void SAL_CALL OConnection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException)
318cdf0e10cSrcweir {
319cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
320cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
321cdf0e10cSrcweir
322cdf0e10cSrcweir
323cdf0e10cSrcweir OTools::ThrowException(this,N3SQLSetConnectAttr(m_aConnectionHandle,
324cdf0e10cSrcweir SQL_ATTR_AUTOCOMMIT,
325cdf0e10cSrcweir (SQLPOINTER)((autoCommit) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF) ,SQL_IS_INTEGER),
326cdf0e10cSrcweir m_aConnectionHandle,SQL_HANDLE_DBC,*this);
327cdf0e10cSrcweir }
328cdf0e10cSrcweir // --------------------------------------------------------------------------------
getAutoCommit()329cdf0e10cSrcweir sal_Bool SAL_CALL OConnection::getAutoCommit( ) throw(SQLException, RuntimeException)
330cdf0e10cSrcweir {
331cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
332cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
333cdf0e10cSrcweir
334cdf0e10cSrcweir
335cdf0e10cSrcweir sal_uInt32 nOption = 0;
336cdf0e10cSrcweir OTools::ThrowException(this,N3SQLGetConnectAttr(m_aConnectionHandle,
337cdf0e10cSrcweir SQL_ATTR_AUTOCOMMIT, &nOption,0,0),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
338cdf0e10cSrcweir return nOption == SQL_AUTOCOMMIT_ON ;
339cdf0e10cSrcweir }
340cdf0e10cSrcweir // --------------------------------------------------------------------------------
commit()341cdf0e10cSrcweir void SAL_CALL OConnection::commit( ) throw(SQLException, RuntimeException)
342cdf0e10cSrcweir {
343cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
344cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
345cdf0e10cSrcweir
346cdf0e10cSrcweir
347cdf0e10cSrcweir OTools::ThrowException(this,N3SQLEndTran(SQL_HANDLE_DBC,m_aConnectionHandle,SQL_COMMIT),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
348cdf0e10cSrcweir }
349cdf0e10cSrcweir // --------------------------------------------------------------------------------
rollback()350cdf0e10cSrcweir void SAL_CALL OConnection::rollback( ) throw(SQLException, RuntimeException)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
353cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
354cdf0e10cSrcweir
355cdf0e10cSrcweir
356cdf0e10cSrcweir OTools::ThrowException(this,N3SQLEndTran(SQL_HANDLE_DBC,m_aConnectionHandle,SQL_ROLLBACK),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
357cdf0e10cSrcweir }
358cdf0e10cSrcweir // --------------------------------------------------------------------------------
isClosed()359cdf0e10cSrcweir sal_Bool SAL_CALL OConnection::isClosed( ) throw(SQLException, RuntimeException)
360cdf0e10cSrcweir {
361cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
362cdf0e10cSrcweir
363cdf0e10cSrcweir return OConnection_BASE::rBHelper.bDisposed;
364cdf0e10cSrcweir }
365cdf0e10cSrcweir // --------------------------------------------------------------------------------
getMetaData()366cdf0e10cSrcweir Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData( ) throw(SQLException, RuntimeException)
367cdf0e10cSrcweir {
368cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
369cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
370cdf0e10cSrcweir
371cdf0e10cSrcweir Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
372cdf0e10cSrcweir if(!xMetaData.is())
373cdf0e10cSrcweir {
374cdf0e10cSrcweir xMetaData = new ODatabaseMetaData(m_aConnectionHandle,this);
375cdf0e10cSrcweir m_xMetaData = xMetaData;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir
378cdf0e10cSrcweir return xMetaData;
379cdf0e10cSrcweir }
380cdf0e10cSrcweir // --------------------------------------------------------------------------------
setReadOnly(sal_Bool readOnly)381cdf0e10cSrcweir void SAL_CALL OConnection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException)
382cdf0e10cSrcweir {
383cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
384cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
385cdf0e10cSrcweir
386cdf0e10cSrcweir
387cdf0e10cSrcweir OTools::ThrowException(this,
388cdf0e10cSrcweir N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_ACCESS_MODE,reinterpret_cast< SQLPOINTER >( readOnly ),SQL_IS_INTEGER),
389cdf0e10cSrcweir m_aConnectionHandle,SQL_HANDLE_DBC,*this);
390cdf0e10cSrcweir }
391cdf0e10cSrcweir // --------------------------------------------------------------------------------
isReadOnly()392cdf0e10cSrcweir sal_Bool SAL_CALL OConnection::isReadOnly() throw(SQLException, RuntimeException)
393cdf0e10cSrcweir {
394cdf0e10cSrcweir // const member which will initialized only once
395cdf0e10cSrcweir return m_bReadOnly;
396cdf0e10cSrcweir }
397cdf0e10cSrcweir // --------------------------------------------------------------------------------
setCatalog(const::rtl::OUString & catalog)398cdf0e10cSrcweir void SAL_CALL OConnection::setCatalog( const ::rtl::OUString& catalog ) throw(SQLException, RuntimeException)
399cdf0e10cSrcweir {
400cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
401cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
402cdf0e10cSrcweir
403cdf0e10cSrcweir
404cdf0e10cSrcweir ::rtl::OString aCat(::rtl::OUStringToOString(catalog.getStr(),getTextEncoding()));
405cdf0e10cSrcweir OTools::ThrowException(this,
406cdf0e10cSrcweir N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_CURRENT_CATALOG,(SDB_ODBC_CHAR*)aCat.getStr(),SQL_NTS),
407cdf0e10cSrcweir m_aConnectionHandle,SQL_HANDLE_DBC,*this);
408cdf0e10cSrcweir }
409cdf0e10cSrcweir // --------------------------------------------------------------------------------
getCatalog()410cdf0e10cSrcweir ::rtl::OUString SAL_CALL OConnection::getCatalog( ) throw(SQLException, RuntimeException)
411cdf0e10cSrcweir {
412cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
413cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
414cdf0e10cSrcweir
415cdf0e10cSrcweir
416cdf0e10cSrcweir sal_Int32 nValueLen;
417cdf0e10cSrcweir char pCat[1024];
418cdf0e10cSrcweir OTools::ThrowException(this,
419cdf0e10cSrcweir N3SQLGetConnectAttr(m_aConnectionHandle,SQL_ATTR_CURRENT_CATALOG,(SDB_ODBC_CHAR*)pCat,(sizeof pCat)-1,&nValueLen),
420cdf0e10cSrcweir m_aConnectionHandle,SQL_HANDLE_DBC,*this);
421cdf0e10cSrcweir
422cdf0e10cSrcweir return ::rtl::OUString(pCat,nValueLen,getTextEncoding());
423cdf0e10cSrcweir }
424cdf0e10cSrcweir // --------------------------------------------------------------------------------
setTransactionIsolation(sal_Int32 level)425cdf0e10cSrcweir void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 level ) throw(SQLException, RuntimeException)
426cdf0e10cSrcweir {
427cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
428cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
429cdf0e10cSrcweir
430cdf0e10cSrcweir
431cdf0e10cSrcweir OTools::ThrowException(this,N3SQLSetConnectAttr(m_aConnectionHandle,
432cdf0e10cSrcweir SQL_ATTR_TXN_ISOLATION,
433cdf0e10cSrcweir (SQLPOINTER)level,SQL_IS_INTEGER),
434cdf0e10cSrcweir m_aConnectionHandle,SQL_HANDLE_DBC,*this);
435cdf0e10cSrcweir }
436cdf0e10cSrcweir // --------------------------------------------------------------------------------
getTransactionIsolation()437cdf0e10cSrcweir sal_Int32 SAL_CALL OConnection::getTransactionIsolation( ) throw(SQLException, RuntimeException)
438cdf0e10cSrcweir {
439cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
440cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
441cdf0e10cSrcweir
442cdf0e10cSrcweir
443cdf0e10cSrcweir sal_Int32 nTxn = 0;
444cdf0e10cSrcweir SQLINTEGER nValueLen;
445cdf0e10cSrcweir OTools::ThrowException(this,
446cdf0e10cSrcweir N3SQLGetConnectAttr(m_aConnectionHandle,SQL_ATTR_TXN_ISOLATION,&nTxn,sizeof nTxn,&nValueLen),
447cdf0e10cSrcweir m_aConnectionHandle,SQL_HANDLE_DBC,*this);
448cdf0e10cSrcweir return nTxn;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir // --------------------------------------------------------------------------------
getTypeMap()451cdf0e10cSrcweir Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getTypeMap( ) throw(SQLException, RuntimeException)
452cdf0e10cSrcweir {
453cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
454cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
455cdf0e10cSrcweir
456cdf0e10cSrcweir
457cdf0e10cSrcweir return NULL;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir // --------------------------------------------------------------------------------
setTypeMap(const Reference<::com::sun::star::container::XNameAccess> &)460cdf0e10cSrcweir void SAL_CALL OConnection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
461cdf0e10cSrcweir {
462cdf0e10cSrcweir ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
463cdf0e10cSrcweir }
464cdf0e10cSrcweir // --------------------------------------------------------------------------------
465cdf0e10cSrcweir // XCloseable
close()466cdf0e10cSrcweir void SAL_CALL OConnection::close( ) throw(SQLException, RuntimeException)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir {
469cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
470cdf0e10cSrcweir checkDisposed(OConnection_BASE::rBHelper.bDisposed);
471cdf0e10cSrcweir
472cdf0e10cSrcweir }
473cdf0e10cSrcweir dispose();
474cdf0e10cSrcweir }
475cdf0e10cSrcweir // --------------------------------------------------------------------------------
476cdf0e10cSrcweir // XWarningsSupplier
getWarnings()477cdf0e10cSrcweir Any SAL_CALL OConnection::getWarnings( ) throw(SQLException, RuntimeException)
478cdf0e10cSrcweir {
479cdf0e10cSrcweir return Any();
480cdf0e10cSrcweir }
481cdf0e10cSrcweir // --------------------------------------------------------------------------------
clearWarnings()482cdf0e10cSrcweir void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException)
483cdf0e10cSrcweir {
484cdf0e10cSrcweir }
485cdf0e10cSrcweir //--------------------------------------------------------------------
buildTypeInfo()486cdf0e10cSrcweir void OConnection::buildTypeInfo() throw( SQLException)
487cdf0e10cSrcweir {
488cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex );
489cdf0e10cSrcweir
490cdf0e10cSrcweir Reference< XResultSet> xRs = getMetaData ()->getTypeInfo ();
491cdf0e10cSrcweir if(xRs.is())
492cdf0e10cSrcweir {
493cdf0e10cSrcweir Reference< XRow> xRow(xRs,UNO_QUERY);
494cdf0e10cSrcweir // Information for a single SQL type
495cdf0e10cSrcweir
496cdf0e10cSrcweir ::connectivity::ORowSetValue aValue;
497cdf0e10cSrcweir ::std::vector<sal_Int32> aTypes;
498cdf0e10cSrcweir Reference<XResultSetMetaData> xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(xRs,UNO_QUERY)->getMetaData();
499cdf0e10cSrcweir sal_Int32 nCount = xResultSetMetaData->getColumnCount();
500cdf0e10cSrcweir // Loop on the result set until we reach end of file
501cdf0e10cSrcweir while (xRs->next ())
502cdf0e10cSrcweir {
503cdf0e10cSrcweir OTypeInfo aInfo;
504cdf0e10cSrcweir sal_Int32 nPos = 1;
505cdf0e10cSrcweir if ( aTypes.empty() )
506cdf0e10cSrcweir {
507cdf0e10cSrcweir if ( nCount < 1 )
508cdf0e10cSrcweir nCount = 18;
509cdf0e10cSrcweir aTypes.reserve(nCount+1);
510cdf0e10cSrcweir aTypes.push_back(-1);
511cdf0e10cSrcweir for (sal_Int32 j = 1; j <= nCount ; ++j)
512cdf0e10cSrcweir aTypes.push_back(xResultSetMetaData->getColumnType(j));
513cdf0e10cSrcweir }
514cdf0e10cSrcweir
515cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
516cdf0e10cSrcweir aInfo.aTypeName = aValue;
517cdf0e10cSrcweir ++nPos;
518cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
519cdf0e10cSrcweir aInfo.nType = aValue;
520cdf0e10cSrcweir ++nPos;
521cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
522cdf0e10cSrcweir aInfo.nPrecision = aValue;
523cdf0e10cSrcweir ++nPos;
524cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
525cdf0e10cSrcweir aInfo.aLiteralPrefix = aValue;
526cdf0e10cSrcweir ++nPos;
527cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
528cdf0e10cSrcweir aInfo.aLiteralSuffix = aValue;
529cdf0e10cSrcweir ++nPos;
530cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
531cdf0e10cSrcweir aInfo.aCreateParams = aValue;
532cdf0e10cSrcweir ++nPos;
533cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
534cdf0e10cSrcweir aInfo.bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
535cdf0e10cSrcweir ++nPos;
536cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
537cdf0e10cSrcweir aInfo.bCaseSensitive = (sal_Bool)aValue;
538cdf0e10cSrcweir ++nPos;
539cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
540cdf0e10cSrcweir aInfo.nSearchType = aValue;
541cdf0e10cSrcweir ++nPos;
542cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
543cdf0e10cSrcweir aInfo.bUnsigned = (sal_Bool)aValue;
544cdf0e10cSrcweir ++nPos;
545cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
546cdf0e10cSrcweir aInfo.bCurrency = (sal_Bool)aValue;
547cdf0e10cSrcweir ++nPos;
548cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
549cdf0e10cSrcweir aInfo.bAutoIncrement = (sal_Bool)aValue;
550cdf0e10cSrcweir ++nPos;
551cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
552cdf0e10cSrcweir aInfo.aLocalTypeName = aValue;
553cdf0e10cSrcweir ++nPos;
554cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
555cdf0e10cSrcweir aInfo.nMinimumScale = aValue;
556cdf0e10cSrcweir ++nPos;
557cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
558cdf0e10cSrcweir aInfo.nMaximumScale = aValue;
559cdf0e10cSrcweir if ( nCount >= 18 )
560cdf0e10cSrcweir {
561cdf0e10cSrcweir nPos = 18;
562cdf0e10cSrcweir aValue.fill(nPos,aTypes[nPos],xRow);
563cdf0e10cSrcweir aInfo.nNumPrecRadix = aValue;
564cdf0e10cSrcweir }
565cdf0e10cSrcweir
566cdf0e10cSrcweir // check if values are less than zero like it happens in a oracle jdbc driver
567cdf0e10cSrcweir if( aInfo.nPrecision < 0)
568cdf0e10cSrcweir aInfo.nPrecision = 0;
569cdf0e10cSrcweir if( aInfo.nMinimumScale < 0)
570cdf0e10cSrcweir aInfo.nMinimumScale = 0;
571cdf0e10cSrcweir if( aInfo.nMaximumScale < 0)
572cdf0e10cSrcweir aInfo.nMaximumScale = 0;
573cdf0e10cSrcweir if( aInfo.nNumPrecRadix < 0)
574cdf0e10cSrcweir aInfo.nNumPrecRadix = 10;
575cdf0e10cSrcweir
576cdf0e10cSrcweir // Now that we have the type info, save it
577cdf0e10cSrcweir // in the Hashtable if we don't already have an
578cdf0e10cSrcweir // entry for this SQL type.
579cdf0e10cSrcweir
580cdf0e10cSrcweir m_aTypeInfo.push_back(aInfo);
581cdf0e10cSrcweir }
582cdf0e10cSrcweir
583cdf0e10cSrcweir // Close the result set/statement.
584cdf0e10cSrcweir
585cdf0e10cSrcweir Reference< XCloseable> xClose(xRs,UNO_QUERY);
586cdf0e10cSrcweir if(xClose.is())
587cdf0e10cSrcweir xClose->close();
588cdf0e10cSrcweir }
589cdf0e10cSrcweir }
590cdf0e10cSrcweir //------------------------------------------------------------------------------
disposing()591cdf0e10cSrcweir void OConnection::disposing()
592cdf0e10cSrcweir {
593cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex);
594cdf0e10cSrcweir
595cdf0e10cSrcweir OConnection_BASE::disposing();
596cdf0e10cSrcweir
597cdf0e10cSrcweir for (::std::map< SQLHANDLE,OConnection*>::iterator aConIter = m_aConnections.begin();aConIter != m_aConnections.end();++aConIter )
598cdf0e10cSrcweir aConIter->second->dispose();
599cdf0e10cSrcweir
600cdf0e10cSrcweir ::std::map< SQLHANDLE,OConnection*>().swap(m_aConnections);
601cdf0e10cSrcweir
602cdf0e10cSrcweir if(!m_bClosed)
603cdf0e10cSrcweir N3SQLDisconnect(m_aConnectionHandle);
604cdf0e10cSrcweir m_bClosed = sal_True;
605cdf0e10cSrcweir
606cdf0e10cSrcweir dispose_ChildImpl();
607cdf0e10cSrcweir }
608cdf0e10cSrcweir // -----------------------------------------------------------------------------
cloneConnection()609cdf0e10cSrcweir OConnection* OConnection::cloneConnection()
610cdf0e10cSrcweir {
611cdf0e10cSrcweir return new OConnection(m_pDriverHandleCopy,m_pDriver);
612cdf0e10cSrcweir }
613cdf0e10cSrcweir // -----------------------------------------------------------------------------
createStatementHandle()614cdf0e10cSrcweir SQLHANDLE OConnection::createStatementHandle()
615cdf0e10cSrcweir {
616cdf0e10cSrcweir OConnection* pConnectionTemp = this;
617cdf0e10cSrcweir sal_Bool bNew = sal_False;
618cdf0e10cSrcweir try
619cdf0e10cSrcweir {
620cdf0e10cSrcweir sal_Int32 nMaxStatements = getMetaData()->getMaxStatements();
621cdf0e10cSrcweir if(nMaxStatements && nMaxStatements <= m_nStatementCount)
622cdf0e10cSrcweir {
623cdf0e10cSrcweir OConnection* pConnection = cloneConnection();
624cdf0e10cSrcweir pConnection->acquire();
625cdf0e10cSrcweir pConnection->Construct(m_sURL,getConnectionInfo());
626cdf0e10cSrcweir pConnectionTemp = pConnection;
627cdf0e10cSrcweir bNew = sal_True;
628cdf0e10cSrcweir }
629cdf0e10cSrcweir }
630cdf0e10cSrcweir catch(SQLException&)
631cdf0e10cSrcweir {
632cdf0e10cSrcweir }
633cdf0e10cSrcweir
634cdf0e10cSrcweir SQLHANDLE aStatementHandle = SQL_NULL_HANDLE;
635cdf0e10cSrcweir SQLRETURN nRetcode = N3SQLAllocHandle(SQL_HANDLE_STMT,pConnectionTemp->getConnection(),&aStatementHandle);
636cdf0e10cSrcweir OSL_UNUSED( nRetcode );
637cdf0e10cSrcweir ++m_nStatementCount;
638cdf0e10cSrcweir if(bNew)
639cdf0e10cSrcweir m_aConnections.insert(::std::map< SQLHANDLE,OConnection*>::value_type(aStatementHandle,pConnectionTemp));
640cdf0e10cSrcweir
641cdf0e10cSrcweir return aStatementHandle;
642cdf0e10cSrcweir
643cdf0e10cSrcweir }
644cdf0e10cSrcweir // -----------------------------------------------------------------------------
freeStatementHandle(SQLHANDLE & _pHandle)645cdf0e10cSrcweir void OConnection::freeStatementHandle(SQLHANDLE& _pHandle)
646cdf0e10cSrcweir {
647cdf0e10cSrcweir ::std::map< SQLHANDLE,OConnection*>::iterator aFind = m_aConnections.find(_pHandle);
648cdf0e10cSrcweir
649cdf0e10cSrcweir N3SQLFreeStmt(_pHandle,SQL_RESET_PARAMS);
650cdf0e10cSrcweir N3SQLFreeStmt(_pHandle,SQL_UNBIND);
651cdf0e10cSrcweir N3SQLFreeStmt(_pHandle,SQL_CLOSE);
652cdf0e10cSrcweir N3SQLFreeHandle(SQL_HANDLE_STMT,_pHandle);
653cdf0e10cSrcweir
654cdf0e10cSrcweir _pHandle = SQL_NULL_HANDLE;
655cdf0e10cSrcweir
656cdf0e10cSrcweir if(aFind != m_aConnections.end())
657cdf0e10cSrcweir {
658cdf0e10cSrcweir aFind->second->dispose();
659cdf0e10cSrcweir m_aConnections.erase(aFind);
660cdf0e10cSrcweir }
661cdf0e10cSrcweir --m_nStatementCount;
662cdf0e10cSrcweir }
663cdf0e10cSrcweir // -----------------------------------------------------------------------------
664cdf0e10cSrcweir
665cdf0e10cSrcweir
666cdf0e10cSrcweir
667