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