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