merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / odbcbase / OConnection.cxx
blob23fac14a35eb31687957470f1d7651380732be6e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: OConnection.cxx,v $
10 * $Revision: 1.45 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "odbc/OTools.hxx"
34 #include "odbc/OConnection.hxx"
35 #include "odbc/ODatabaseMetaData.hxx"
36 #include "odbc/OFunctions.hxx"
37 #include "odbc/ODriver.hxx"
38 #include "odbc/OStatement.hxx"
39 #include "odbc/OPreparedStatement.hxx"
40 #include <com/sun/star/sdbc/ColumnValue.hpp>
41 #include <com/sun/star/sdbc/XRow.hpp>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include <connectivity/dbcharset.hxx>
44 #include <connectivity/FValue.hxx>
45 #include <comphelper/extract.hxx>
46 #include "diagnose_ex.h"
47 #include <connectivity/dbexception.hxx>
49 #include <string.h>
51 using namespace connectivity::odbc;
52 using namespace connectivity;
53 using namespace dbtools;
55 //------------------------------------------------------------------------------
56 using namespace com::sun::star::uno;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::beans;
59 using namespace com::sun::star::sdbc;
60 // --------------------------------------------------------------------------------
61 OConnection::OConnection(const SQLHANDLE _pDriverHandle,ODBCDriver* _pDriver)
62 : OSubComponent<OConnection, OConnection_BASE>((::cppu::OWeakObject*)_pDriver, this)
63 ,m_pDriver(_pDriver)
64 ,m_pDriverHandleCopy(_pDriverHandle)
65 ,m_nStatementCount(0)
66 ,m_bClosed(sal_True)
67 ,m_bUseCatalog(sal_False)
68 ,m_bUseOldDateFormat(sal_False)
69 ,m_bParameterSubstitution(sal_False)
70 ,m_bIgnoreDriverPrivileges(sal_False)
71 ,m_bPreventGetVersionColumns(sal_False)
72 ,m_bReadOnly(sal_True)
74 m_pDriver->acquire();
76 //-----------------------------------------------------------------------------
77 OConnection::~OConnection()
79 if(!isClosed( ))
80 close();
82 if ( SQL_NULL_HANDLE != m_aConnectionHandle )
83 N3SQLFreeHandle( SQL_HANDLE_DBC, m_aConnectionHandle );
84 m_aConnectionHandle = SQL_NULL_HANDLE;
86 m_pDriver->release();
87 m_pDriver = NULL;
89 //-----------------------------------------------------------------------------
90 void SAL_CALL OConnection::release() throw()
92 relase_ChildImpl();
94 // -----------------------------------------------------------------------------
95 oslGenericFunction OConnection::getOdbcFunction(sal_Int32 _nIndex) const
97 OSL_ENSURE(m_pDriver,"OConnection::getOdbcFunction: m_pDriver is null!");
98 return m_pDriver->getOdbcFunction(_nIndex);
100 //-----------------------------------------------------------------------------
101 SQLRETURN OConnection::OpenConnection(const ::rtl::OUString& aConnectStr,sal_Int32 nTimeOut, sal_Bool bSilent)
103 ::osl::MutexGuard aGuard( m_aMutex );
105 if (m_aConnectionHandle == SQL_NULL_HANDLE)
106 return -1;
108 SQLRETURN nSQLRETURN = 0;
109 SDB_ODBC_CHAR szConnStrOut[4096];
110 SDB_ODBC_CHAR szConnStrIn[2048];
111 SQLSMALLINT cbConnStrOut;
112 memset(szConnStrOut,'\0',4096);
113 memset(szConnStrIn,'\0',2048);
114 ::rtl::OString aConStr(::rtl::OUStringToOString(aConnectStr,getTextEncoding()));
115 memcpy(szConnStrIn, (SDB_ODBC_CHAR*) aConStr.getStr(), ::std::min<sal_Int32>((sal_Int32)2048,aConStr.getLength()));
117 #ifndef MACOSX
118 N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_LOGIN_TIMEOUT,(SQLPOINTER)nTimeOut,SQL_IS_UINTEGER);
119 // Verbindung aufbauen
120 #endif
122 #ifdef LINUX
123 OSL_UNUSED( bSilent );
124 nSQLRETURN = N3SQLDriverConnect(m_aConnectionHandle,
125 NULL,
126 szConnStrIn,
127 (SQLSMALLINT) ::std::min((sal_Int32)2048,aConStr.getLength()),
128 szConnStrOut,
129 (SQLSMALLINT) (sizeof(szConnStrOut)/sizeof(SDB_ODBC_CHAR)) -1,
130 &cbConnStrOut,
131 SQL_DRIVER_NOPROMPT);
132 if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA || SQL_SUCCESS_WITH_INFO == nSQLRETURN)
133 return nSQLRETURN;
134 #else
136 SQLUSMALLINT nSilent = bSilent ? SQL_DRIVER_NOPROMPT : SQL_DRIVER_COMPLETE;
137 nSQLRETURN = N3SQLDriverConnect(m_aConnectionHandle,
138 NULL,
139 szConnStrIn,
140 (SQLSMALLINT) ::std::min<sal_Int32>((sal_Int32)2048,aConStr.getLength()),
141 szConnStrOut,
142 (SQLSMALLINT) sizeof szConnStrOut,
143 &cbConnStrOut,
144 nSilent);
145 if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA)
146 return nSQLRETURN;
148 m_bClosed = sal_False;
150 #endif //LINUX
154 ::rtl::OUString aVal;
155 OTools::GetInfo(this,m_aConnectionHandle,SQL_DATA_SOURCE_READ_ONLY,aVal,*this,getTextEncoding());
156 m_bReadOnly = !aVal.compareToAscii("Y");
158 catch(Exception&)
160 m_bReadOnly = sal_True;
164 ::rtl::OUString sVersion;
165 OTools::GetInfo(this,m_aConnectionHandle,SQL_DRIVER_ODBC_VER,sVersion,*this,getTextEncoding());
166 m_bUseOldDateFormat = sVersion == ::rtl::OUString::createFromAscii("02.50") || sVersion == ::rtl::OUString::createFromAscii("02.00");
168 catch(Exception&)
173 // autocoomit ist immer default
175 if (!m_bReadOnly)
176 N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON,SQL_IS_INTEGER);
178 return nSQLRETURN;
180 //-----------------------------------------------------------------------------
181 SQLRETURN OConnection::Construct(const ::rtl::OUString& url,const Sequence< PropertyValue >& info) throw(SQLException)
183 m_aConnectionHandle = SQL_NULL_HANDLE;
184 m_sURL = url;
185 setConnectionInfo(info);
187 // Connection allozieren
188 N3SQLAllocHandle(SQL_HANDLE_DBC,m_pDriverHandleCopy,&m_aConnectionHandle);
189 if(m_aConnectionHandle == SQL_NULL_HANDLE)
190 throw SQLException();
192 sal_Int32 nLen = url.indexOf(':');
193 nLen = url.indexOf(':',nLen+1);
194 ::rtl::OUString aDSN(RTL_CONSTASCII_USTRINGPARAM("DSN=")), aUID, aPWD, aSysDrvSettings;
195 aDSN += url.copy(nLen+1);
197 const char* pUser = "user";
198 const char* pTimeout = "Timeout";
199 const char* pSilent = "Silent";
200 const char* pPwd = "password";
201 const char* pUseCatalog = "UseCatalog";
202 const char* pSysDrv = "SystemDriverSettings";
203 const char* pCharSet = "CharSet";
204 const char* pParaName = "ParameterNameSubstitution";
205 const char* pPrivName = "IgnoreDriverPrivileges";
206 const char* pVerColName = "PreventGetVersionColumns"; // #i60273#
207 const char* pRetrieving = "IsAutoRetrievingEnabled";
208 const char* pRetriStmt = "AutoRetrievingStatement";
210 sal_Int32 nTimeout = 20;
211 sal_Bool bSilent = sal_True;
212 const PropertyValue *pBegin = info.getConstArray();
213 const PropertyValue *pEnd = pBegin + info.getLength();
214 for(;pBegin != pEnd;++pBegin)
216 if(!pBegin->Name.compareToAscii(pTimeout))
217 OSL_VERIFY( pBegin->Value >>= nTimeout );
218 else if(!pBegin->Name.compareToAscii(pSilent))
219 OSL_VERIFY( pBegin->Value >>= bSilent );
220 else if(!pBegin->Name.compareToAscii(pPrivName))
221 OSL_VERIFY( pBegin->Value >>= m_bIgnoreDriverPrivileges );
222 else if(!pBegin->Name.compareToAscii(pVerColName))
223 OSL_VERIFY( pBegin->Value >>= m_bPreventGetVersionColumns );
224 else if(!pBegin->Name.compareToAscii(pParaName))
225 OSL_VERIFY( pBegin->Value >>= m_bParameterSubstitution );
226 else if(!pBegin->Name.compareToAscii(pRetrieving))
228 sal_Bool bAutoRetrievingEnabled = sal_False;
229 OSL_VERIFY( pBegin->Value >>= bAutoRetrievingEnabled );
230 enableAutoRetrievingEnabled(bAutoRetrievingEnabled);
232 else if(!pBegin->Name.compareToAscii(pRetriStmt))
234 ::rtl::OUString sGeneratedValueStatement;
235 OSL_VERIFY( pBegin->Value >>= sGeneratedValueStatement );
236 setAutoRetrievingStatement(sGeneratedValueStatement);
238 else if(!pBegin->Name.compareToAscii(pUser))
240 OSL_VERIFY( pBegin->Value >>= aUID );
241 aDSN = aDSN + ::rtl::OUString::createFromAscii(";UID=") + aUID;
243 else if(!pBegin->Name.compareToAscii(pPwd))
245 OSL_VERIFY( pBegin->Value >>= aPWD );
246 aDSN = aDSN + ::rtl::OUString::createFromAscii(";PWD=") + aPWD;
248 else if(!pBegin->Name.compareToAscii(pUseCatalog))
250 OSL_VERIFY( pBegin->Value >>= m_bUseCatalog );
252 else if(!pBegin->Name.compareToAscii(pSysDrv))
254 OSL_VERIFY( pBegin->Value >>= aSysDrvSettings );
255 aDSN += ::rtl::OUString::createFromAscii(";");
256 aDSN += aSysDrvSettings;
258 else if(0 == pBegin->Name.compareToAscii(pCharSet))
260 ::rtl::OUString sIanaName;
261 OSL_VERIFY( pBegin->Value >>= sIanaName );
263 ::dbtools::OCharsetMap aLookupIanaName;
264 ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.find(sIanaName, ::dbtools::OCharsetMap::IANA());
265 if (aLookup != aLookupIanaName.end())
266 m_nTextEncoding = (*aLookup).getEncoding();
267 else
268 m_nTextEncoding = RTL_TEXTENCODING_DONTKNOW;
269 if(m_nTextEncoding == RTL_TEXTENCODING_DONTKNOW)
270 m_nTextEncoding = osl_getThreadTextEncoding();
273 m_sUser = aUID;
275 SQLRETURN nSQLRETURN = OpenConnection(aDSN,nTimeout, bSilent);
276 if (nSQLRETURN == SQL_ERROR || nSQLRETURN == SQL_NO_DATA)
278 OTools::ThrowException(this,nSQLRETURN,m_aConnectionHandle,SQL_HANDLE_DBC,*this,sal_False);
280 return nSQLRETURN;
282 // XServiceInfo
283 // --------------------------------------------------------------------------------
284 IMPLEMENT_SERVICE_INFO(OConnection, "com.sun.star.sdbc.drivers.odbc.OConnection", "com.sun.star.sdbc.Connection")
286 // --------------------------------------------------------------------------------
287 Reference< XStatement > SAL_CALL OConnection::createStatement( ) throw(SQLException, RuntimeException)
289 ::osl::MutexGuard aGuard( m_aMutex );
290 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
292 Reference< XStatement > xReturn = new OStatement(this);
293 m_aStatements.push_back(WeakReferenceHelper(xReturn));
294 return xReturn;
296 // --------------------------------------------------------------------------------
297 Reference< XPreparedStatement > SAL_CALL OConnection::prepareStatement( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
299 ::osl::MutexGuard aGuard( m_aMutex );
300 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
302 Reference< XPreparedStatement > xReturn = new OPreparedStatement(this,sql);
303 m_aStatements.push_back(WeakReferenceHelper(xReturn));
304 return xReturn;
306 // --------------------------------------------------------------------------------
307 Reference< XPreparedStatement > SAL_CALL OConnection::prepareCall( const ::rtl::OUString& /*sql*/ ) throw(SQLException, RuntimeException)
309 ::dbtools::throwFeatureNotImplementedException( "XConnection::prepareCall", *this );
310 return NULL;
312 // --------------------------------------------------------------------------------
313 ::rtl::OUString SAL_CALL OConnection::nativeSQL( const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
315 ::osl::MutexGuard aGuard( m_aMutex );
317 ::rtl::OString aSql(::rtl::OUStringToOString(sql.getStr(),getTextEncoding()));
318 char pOut[2048];
319 SQLINTEGER nOutLen;
320 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);
321 return ::rtl::OUString(pOut,nOutLen,getTextEncoding());
323 // --------------------------------------------------------------------------------
324 void SAL_CALL OConnection::setAutoCommit( sal_Bool autoCommit ) throw(SQLException, RuntimeException)
326 ::osl::MutexGuard aGuard( m_aMutex );
327 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
330 OTools::ThrowException(this,N3SQLSetConnectAttr(m_aConnectionHandle,
331 SQL_ATTR_AUTOCOMMIT,
332 (SQLPOINTER)((autoCommit) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF) ,SQL_IS_INTEGER),
333 m_aConnectionHandle,SQL_HANDLE_DBC,*this);
335 // --------------------------------------------------------------------------------
336 sal_Bool SAL_CALL OConnection::getAutoCommit( ) throw(SQLException, RuntimeException)
338 ::osl::MutexGuard aGuard( m_aMutex );
339 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
342 sal_uInt32 nOption = 0;
343 OTools::ThrowException(this,N3SQLGetConnectAttr(m_aConnectionHandle,
344 SQL_ATTR_AUTOCOMMIT, &nOption,0,0),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
345 return nOption == SQL_AUTOCOMMIT_ON ;
347 // --------------------------------------------------------------------------------
348 void SAL_CALL OConnection::commit( ) throw(SQLException, RuntimeException)
350 ::osl::MutexGuard aGuard( m_aMutex );
351 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
354 OTools::ThrowException(this,N3SQLEndTran(SQL_HANDLE_DBC,m_aConnectionHandle,SQL_COMMIT),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
356 // --------------------------------------------------------------------------------
357 void SAL_CALL OConnection::rollback( ) throw(SQLException, RuntimeException)
359 ::osl::MutexGuard aGuard( m_aMutex );
360 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
363 OTools::ThrowException(this,N3SQLEndTran(SQL_HANDLE_DBC,m_aConnectionHandle,SQL_ROLLBACK),m_aConnectionHandle,SQL_HANDLE_DBC,*this);
365 // --------------------------------------------------------------------------------
366 sal_Bool SAL_CALL OConnection::isClosed( ) throw(SQLException, RuntimeException)
368 ::osl::MutexGuard aGuard( m_aMutex );
370 return OConnection_BASE::rBHelper.bDisposed;
372 // --------------------------------------------------------------------------------
373 Reference< XDatabaseMetaData > SAL_CALL OConnection::getMetaData( ) throw(SQLException, RuntimeException)
375 ::osl::MutexGuard aGuard( m_aMutex );
376 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
378 Reference< XDatabaseMetaData > xMetaData = m_xMetaData;
379 if(!xMetaData.is())
381 xMetaData = new ODatabaseMetaData(m_aConnectionHandle,this);
382 m_xMetaData = xMetaData;
385 return xMetaData;
387 // --------------------------------------------------------------------------------
388 void SAL_CALL OConnection::setReadOnly( sal_Bool readOnly ) throw(SQLException, RuntimeException)
390 ::osl::MutexGuard aGuard( m_aMutex );
391 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
394 OTools::ThrowException(this,
395 N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_ACCESS_MODE,reinterpret_cast< SQLPOINTER >( readOnly ),SQL_IS_INTEGER),
396 m_aConnectionHandle,SQL_HANDLE_DBC,*this);
398 // --------------------------------------------------------------------------------
399 sal_Bool SAL_CALL OConnection::isReadOnly() throw(SQLException, RuntimeException)
401 // const member which will initialized only once
402 return m_bReadOnly;
404 // --------------------------------------------------------------------------------
405 void SAL_CALL OConnection::setCatalog( const ::rtl::OUString& catalog ) throw(SQLException, RuntimeException)
407 ::osl::MutexGuard aGuard( m_aMutex );
408 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
411 ::rtl::OString aCat(::rtl::OUStringToOString(catalog.getStr(),getTextEncoding()));
412 OTools::ThrowException(this,
413 N3SQLSetConnectAttr(m_aConnectionHandle,SQL_ATTR_CURRENT_CATALOG,(SDB_ODBC_CHAR*)aCat.getStr(),SQL_NTS),
414 m_aConnectionHandle,SQL_HANDLE_DBC,*this);
416 // --------------------------------------------------------------------------------
417 ::rtl::OUString SAL_CALL OConnection::getCatalog( ) throw(SQLException, RuntimeException)
419 ::osl::MutexGuard aGuard( m_aMutex );
420 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
423 sal_Int32 nValueLen;
424 char pCat[1024];
425 OTools::ThrowException(this,
426 N3SQLGetConnectAttr(m_aConnectionHandle,SQL_ATTR_CURRENT_CATALOG,(SDB_ODBC_CHAR*)pCat,(sizeof pCat)-1,&nValueLen),
427 m_aConnectionHandle,SQL_HANDLE_DBC,*this);
429 return ::rtl::OUString(pCat,nValueLen,getTextEncoding());
431 // --------------------------------------------------------------------------------
432 void SAL_CALL OConnection::setTransactionIsolation( sal_Int32 level ) throw(SQLException, RuntimeException)
434 ::osl::MutexGuard aGuard( m_aMutex );
435 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
438 OTools::ThrowException(this,N3SQLSetConnectAttr(m_aConnectionHandle,
439 SQL_ATTR_TXN_ISOLATION,
440 (SQLPOINTER)level,SQL_IS_INTEGER),
441 m_aConnectionHandle,SQL_HANDLE_DBC,*this);
443 // --------------------------------------------------------------------------------
444 sal_Int32 SAL_CALL OConnection::getTransactionIsolation( ) throw(SQLException, RuntimeException)
446 ::osl::MutexGuard aGuard( m_aMutex );
447 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
450 sal_Int32 nTxn = 0;
451 SQLINTEGER nValueLen;
452 OTools::ThrowException(this,
453 N3SQLGetConnectAttr(m_aConnectionHandle,SQL_ATTR_TXN_ISOLATION,&nTxn,sizeof nTxn,&nValueLen),
454 m_aConnectionHandle,SQL_HANDLE_DBC,*this);
455 return nTxn;
457 // --------------------------------------------------------------------------------
458 Reference< ::com::sun::star::container::XNameAccess > SAL_CALL OConnection::getTypeMap( ) throw(SQLException, RuntimeException)
460 ::osl::MutexGuard aGuard( m_aMutex );
461 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
464 return NULL;
466 // --------------------------------------------------------------------------------
467 void SAL_CALL OConnection::setTypeMap( const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
469 ::dbtools::throwFeatureNotImplementedException( "XConnection::setTypeMap", *this );
471 // --------------------------------------------------------------------------------
472 // XCloseable
473 void SAL_CALL OConnection::close( ) throw(SQLException, RuntimeException)
476 ::osl::MutexGuard aGuard( m_aMutex );
477 checkDisposed(OConnection_BASE::rBHelper.bDisposed);
480 dispose();
482 // --------------------------------------------------------------------------------
483 // XWarningsSupplier
484 Any SAL_CALL OConnection::getWarnings( ) throw(SQLException, RuntimeException)
486 return Any();
488 // --------------------------------------------------------------------------------
489 void SAL_CALL OConnection::clearWarnings( ) throw(SQLException, RuntimeException)
492 //--------------------------------------------------------------------
493 void OConnection::buildTypeInfo() throw( SQLException)
495 ::osl::MutexGuard aGuard( m_aMutex );
497 Reference< XResultSet> xRs = getMetaData ()->getTypeInfo ();
498 if(xRs.is())
500 Reference< XRow> xRow(xRs,UNO_QUERY);
501 // Information for a single SQL type
503 ::connectivity::ORowSetValue aValue;
504 ::std::vector<sal_Int32> aTypes;
505 Reference<XResultSetMetaData> xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(xRs,UNO_QUERY)->getMetaData();
506 sal_Int32 nCount = xResultSetMetaData->getColumnCount();
507 // Loop on the result set until we reach end of file
508 while (xRs->next ())
510 OTypeInfo aInfo;
511 sal_Int32 nPos = 1;
512 if ( aTypes.empty() )
514 if ( nCount < 1 )
515 nCount = 18;
516 aTypes.reserve(nCount+1);
517 aTypes.push_back(-1);
518 for (sal_Int32 j = 1; j <= nCount ; ++j)
519 aTypes.push_back(xResultSetMetaData->getColumnType(j));
522 aValue.fill(nPos,aTypes[nPos],xRow);
523 aInfo.aTypeName = aValue;
524 ++nPos;
525 aValue.fill(nPos,aTypes[nPos],xRow);
526 aInfo.nType = aValue;
527 ++nPos;
528 aValue.fill(nPos,aTypes[nPos],xRow);
529 aInfo.nPrecision = aValue;
530 ++nPos;
531 aValue.fill(nPos,aTypes[nPos],xRow);
532 aInfo.aLiteralPrefix = aValue;
533 ++nPos;
534 aValue.fill(nPos,aTypes[nPos],xRow);
535 aInfo.aLiteralSuffix = aValue;
536 ++nPos;
537 aValue.fill(nPos,aTypes[nPos],xRow);
538 aInfo.aCreateParams = aValue;
539 ++nPos;
540 aValue.fill(nPos,aTypes[nPos],xRow);
541 aInfo.bNullable = (sal_Int32)aValue == ColumnValue::NULLABLE;
542 ++nPos;
543 aValue.fill(nPos,aTypes[nPos],xRow);
544 aInfo.bCaseSensitive = (sal_Bool)aValue;
545 ++nPos;
546 aValue.fill(nPos,aTypes[nPos],xRow);
547 aInfo.nSearchType = aValue;
548 ++nPos;
549 aValue.fill(nPos,aTypes[nPos],xRow);
550 aInfo.bUnsigned = (sal_Bool)aValue;
551 ++nPos;
552 aValue.fill(nPos,aTypes[nPos],xRow);
553 aInfo.bCurrency = (sal_Bool)aValue;
554 ++nPos;
555 aValue.fill(nPos,aTypes[nPos],xRow);
556 aInfo.bAutoIncrement = (sal_Bool)aValue;
557 ++nPos;
558 aValue.fill(nPos,aTypes[nPos],xRow);
559 aInfo.aLocalTypeName = aValue;
560 ++nPos;
561 aValue.fill(nPos,aTypes[nPos],xRow);
562 aInfo.nMinimumScale = aValue;
563 ++nPos;
564 aValue.fill(nPos,aTypes[nPos],xRow);
565 aInfo.nMaximumScale = aValue;
566 if ( nCount >= 18 )
568 nPos = 18;
569 aValue.fill(nPos,aTypes[nPos],xRow);
570 aInfo.nNumPrecRadix = aValue;
573 // check if values are less than zero like it happens in a oracle jdbc driver
574 if( aInfo.nPrecision < 0)
575 aInfo.nPrecision = 0;
576 if( aInfo.nMinimumScale < 0)
577 aInfo.nMinimumScale = 0;
578 if( aInfo.nMaximumScale < 0)
579 aInfo.nMaximumScale = 0;
580 if( aInfo.nNumPrecRadix < 0)
581 aInfo.nNumPrecRadix = 10;
583 // Now that we have the type info, save it
584 // in the Hashtable if we don't already have an
585 // entry for this SQL type.
587 m_aTypeInfo.push_back(aInfo);
590 // Close the result set/statement.
592 Reference< XCloseable> xClose(xRs,UNO_QUERY);
593 if(xClose.is())
594 xClose->close();
597 //------------------------------------------------------------------------------
598 void OConnection::disposing()
600 ::osl::MutexGuard aGuard(m_aMutex);
602 OConnection_BASE::disposing();
604 for (::std::map< SQLHANDLE,OConnection*>::iterator aConIter = m_aConnections.begin();aConIter != m_aConnections.end();++aConIter )
605 aConIter->second->dispose();
607 ::std::map< SQLHANDLE,OConnection*>().swap(m_aConnections);
609 if(!m_bClosed)
610 N3SQLDisconnect(m_aConnectionHandle);
611 m_bClosed = sal_True;
613 dispose_ChildImpl();
615 // -----------------------------------------------------------------------------
616 OConnection* OConnection::cloneConnection()
618 return new OConnection(m_pDriverHandleCopy,m_pDriver);
620 // -----------------------------------------------------------------------------
621 SQLHANDLE OConnection::createStatementHandle()
623 OConnection* pConnectionTemp = this;
624 sal_Bool bNew = sal_False;
627 sal_Int32 nMaxStatements = getMetaData()->getMaxStatements();
628 if(nMaxStatements && nMaxStatements <= m_nStatementCount)
630 OConnection* pConnection = cloneConnection();
631 pConnection->acquire();
632 pConnection->Construct(m_sURL,getConnectionInfo());
633 pConnectionTemp = pConnection;
634 bNew = sal_True;
637 catch(SQLException&)
641 SQLHANDLE aStatementHandle = SQL_NULL_HANDLE;
642 SQLRETURN nRetcode = N3SQLAllocHandle(SQL_HANDLE_STMT,pConnectionTemp->getConnection(),&aStatementHandle);
643 OSL_UNUSED( nRetcode );
644 ++m_nStatementCount;
645 if(bNew)
646 m_aConnections.insert(::std::map< SQLHANDLE,OConnection*>::value_type(aStatementHandle,pConnectionTemp));
648 return aStatementHandle;
651 // -----------------------------------------------------------------------------
652 void OConnection::freeStatementHandle(SQLHANDLE& _pHandle)
654 ::std::map< SQLHANDLE,OConnection*>::iterator aFind = m_aConnections.find(_pHandle);
656 N3SQLFreeStmt(_pHandle,SQL_RESET_PARAMS);
657 N3SQLFreeStmt(_pHandle,SQL_UNBIND);
658 N3SQLFreeStmt(_pHandle,SQL_CLOSE);
659 N3SQLFreeHandle(SQL_HANDLE_STMT,_pHandle);
661 _pHandle = SQL_NULL_HANDLE;
663 if(aFind != m_aConnections.end())
665 aFind->second->dispose();
666 m_aConnections.erase(aFind);
668 --m_nStatementCount;
670 // -----------------------------------------------------------------------------