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