xref: /AOO41X/main/connectivity/source/drivers/evoab2/NResultSet.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 
31 #include "NDatabaseMetaData.hxx"
32 #include "NConnection.hxx"
33 #include "NResultSet.hxx"
34 #include "propertyids.hxx"
35 #include "resource/evoab2_res.hrc"
36 #include "TSortIndex.hxx"
37 #include <algorithm>
38 
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <com/sun/star/lang/DisposedException.hpp>
41 #include <com/sun/star/sdb/ErrorCondition.hpp>
42 #include <com/sun/star/sdbc/DataType.hpp>
43 #include <com/sun/star/sdbc/FetchDirection.hpp>
44 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
45 #include <com/sun/star/sdbc/ResultSetType.hpp>
46 
47 #include <comphelper/componentcontext.hxx>
48 #include <comphelper/extract.hxx>
49 #include <comphelper/property.hxx>
50 #include <comphelper/sequence.hxx>
51 #include <comphelper/types.hxx>
52 #include <connectivity/dbexception.hxx>
53 #include <connectivity/sqlerror.hxx>
54 #include <cppuhelper/typeprovider.hxx>
55 #include <rtl/string.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <unotools/syslocale.hxx>
58 #include <unotools/intlwrapper.hxx>
59 
60 #include <cstring>
61 #include <vector>
62 
63 namespace connectivity { namespace evoab {
64 
65 using namespace ::comphelper;
66 using namespace com::sun::star;
67 using namespace com::sun::star::uno;
68 using namespace com::sun::star::lang;
69 using namespace com::sun::star::beans;
70 using namespace com::sun::star::sdbc;
71 using namespace com::sun::star::sdbcx;
72 using namespace com::sun::star::container;
73 using namespace com::sun::star::io;
74 namespace ErrorCondition = ::com::sun::star::sdb::ErrorCondition;
75 
76 //------------------------------------------------------------------------------
77 ::rtl::OUString SAL_CALL OEvoabResultSet::getImplementationName(  ) throw ( RuntimeException)	\
78 {
79 	return ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.evoab.ResultSet");
80 }
81 // -------------------------------------------------------------------------
82  Sequence< ::rtl::OUString > SAL_CALL OEvoabResultSet::getSupportedServiceNames(  ) throw( RuntimeException)
83 {
84 	 Sequence< ::rtl::OUString > aSupported(1);
85 	aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ResultSet");
86 	return aSupported;
87 }
88 // -------------------------------------------------------------------------
89 sal_Bool SAL_CALL OEvoabResultSet::supportsService( const ::rtl::OUString& _rServiceName ) throw( RuntimeException)
90 {
91 	Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
92 	const ::rtl::OUString* pSupported = aSupported.getConstArray();
93 	const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
94 	for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
95 		;
96 
97 	return pSupported != pEnd;
98 }
99 
100 // -------------------------------------------------------------------------
101 OEvoabResultSet::OEvoabResultSet( OCommonStatement* pStmt, OEvoabConnection *pConnection )
102 	:OResultSet_BASE(m_aMutex)
103     ,::comphelper::OPropertyContainer( OResultSet_BASE::rBHelper )
104 	,m_pStatement(pStmt)
105 	,m_pConnection(pConnection)
106     ,m_xMetaData(NULL)
107 	,m_bWasNull(sal_True)
108 	,m_nFetchSize(0)
109 	,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE)
110 	,m_nFetchDirection(FetchDirection::FORWARD)
111 	,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY)
112     ,m_pContacts(NULL)
113 	,m_nIndex(-1)
114 	,m_nLength(0)
115 {
116     #define REGISTER_PROP( id, member ) \
117         registerProperty( \
118             OMetaConnection::getPropMap().getNameByIndex( id ), \
119             id, \
120             PropertyAttribute::READONLY, \
121             &member, \
122             ::getCppuType( &member ) \
123         );
124 
125     REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize );
126     REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType );
127 	REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection );
128     REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency );
129 }
130 
131 // -------------------------------------------------------------------------
132 OEvoabResultSet::~OEvoabResultSet()
133 {
134 }
135 
136 // -------------------------------------------------------------------------
137 
138 static ESource *
139 findSource( const char *name )
140 {
141 	ESourceList *pSourceList = NULL;
142 
143 	g_return_val_if_fail (name != NULL, NULL);
144 
145 	if (!e_book_get_addressbooks (&pSourceList, NULL))
146 		pSourceList = NULL;
147 
148 	for ( GSList *g = e_source_list_peek_groups (pSourceList); g; g = g->next)
149 	{
150 		for (GSList *s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next)
151 		{
152 			ESource *pSource = E_SOURCE (s->data);
153 			if (!strcmp (e_source_peek_name (pSource), name))
154 				return pSource;
155 		}
156 	}
157 	return NULL;
158 }
159 
160 static EBook *
161 openBook( const char *abname )
162 {
163 	ESource *pSource = findSource (abname);
164 	EBook *pBook = NULL;
165 	if (pSource)
166 			pBook = e_book_new (pSource, NULL);
167 
168 	if (pBook && !e_book_open (pBook, TRUE, NULL))
169 	{
170 		g_object_unref (G_OBJECT (pBook));
171 		pBook = NULL;
172 	}
173 
174 	return pBook;
175 }
176 
177 static bool isLDAP( EBook *pBook )
178 {
179 	return pBook && !strncmp( "ldap://", e_book_get_uri( pBook ), 6 );
180 }
181 
182 static bool isLocal( EBook *pBook )
183 {
184 	return pBook && !strncmp( "file://", e_book_get_uri( pBook ), 6 );
185 }
186 
187 static bool isAuthRequired( EBook *pBook )
188 {
189 	return e_source_get_property( e_book_get_source( pBook ),
190 								  "auth" ) != NULL;
191 }
192 
193 static rtl::OString getUserName( EBook *pBook )
194 {
195 	rtl::OString aName;
196 	if( isLDAP( pBook ) )
197 		aName = e_source_get_property( e_book_get_source( pBook ), "binddn" );
198 	else
199 		aName = e_source_get_property( e_book_get_source( pBook ), "user" );
200 	return aName;
201 }
202 
203 static ::rtl::OUString
204 valueToOUString( GValue& _rValue )
205 {
206 	const char *pStr = g_value_get_string( &_rValue );
207 	rtl::OString aStr( pStr ? pStr : "" );
208     ::rtl::OUString sResult( ::rtl::OStringToOUString( aStr, RTL_TEXTENCODING_UTF8 ) );
209 	g_value_unset( &_rValue );
210     return sResult;
211 }
212 
213 static bool
214 valueToBool( GValue& _rValue )
215 {
216 	bool bResult = g_value_get_boolean( &_rValue );
217 	g_value_unset( &_rValue );
218     return bResult;
219 }
220 
221 static bool
222 executeQuery (EBook* pBook, EBookQuery* pQuery, GList **ppList,
223 			  rtl::OString &rPassword, GError **pError)
224 {
225 	ESource *pSource = e_book_get_source( pBook );
226 	bool bSuccess = false;
227 	bool bAuthSuccess = true;
228 
229 	*ppList = NULL;
230 
231 	if( isAuthRequired( pBook ) )
232 	{
233 		rtl::OString aUser( getUserName( pBook ) );
234 		const char *pAuth = e_source_get_property( pSource, "auth" );
235 		bAuthSuccess = e_book_authenticate_user( pBook, aUser, rPassword, pAuth, pError );
236 	}
237 
238 	if (bAuthSuccess)
239 		bSuccess = e_book_get_contacts( pBook, pQuery, ppList, pError );
240 
241 	return bSuccess;
242 }
243 
244 static int
245 whichAddress(int value)
246 {
247 	int fieldEnum;
248 	switch (value)
249 	{
250 		case HOME_ADDR_LINE1:
251 		case HOME_ADDR_LINE2:
252 		case HOME_CITY:
253 		case HOME_STATE:
254 		case HOME_COUNTRY:
255 		case HOME_ZIP:
256 			fieldEnum = e_contact_field_id("address_home");
257 			break;
258 
259 		case WORK_ADDR_LINE1:
260 		case WORK_ADDR_LINE2:
261 		case WORK_CITY:
262 		case WORK_STATE:
263 		case WORK_COUNTRY:
264 		case WORK_ZIP:
265 			fieldEnum = e_contact_field_id("address_work");
266 			break;
267 
268 		case OTHER_ADDR_LINE1:
269 		case OTHER_ADDR_LINE2:
270 		case OTHER_CITY:
271 		case OTHER_STATE:
272 		case OTHER_COUNTRY:
273 		case OTHER_ZIP:
274 			fieldEnum = e_contact_field_id("address_other");
275 			break;
276 
277 	    	default: fieldEnum = e_contact_field_id("address_home");
278 	  }
279 	return fieldEnum;
280 }
281 
282 /*
283 * This function decides the default column values based on the first field of EContactAddress.
284 * The search order is Work->Home->other(defaults).
285 */
286 static EContactAddress *
287 getDefaultContactAddress( EContact *pContact,int *value )
288 {
289 	EContactAddress *ec = (EContactAddress *)e_contact_get(pContact,whichAddress(WORK_ADDR_LINE1));
290 	if ( ec && (strlen(ec->street)>0) )
291 	{
292 		*value= *value +WORK_ADDR_LINE1 -1;
293 		return ec;
294 	}
295 	else
296 		{
297 			ec = (EContactAddress *)e_contact_get(pContact,whichAddress(HOME_ADDR_LINE1));
298 			if ( ec && (strlen(ec->street)>0) )
299 			{
300 				*value=*value+HOME_ADDR_LINE1-1;
301 				return ec;
302 			}
303 		}
304 
305 	*value=*value+OTHER_ADDR_LINE1-1;
306 	return (EContactAddress *)e_contact_get(pContact,whichAddress(OTHER_ADDR_LINE1));
307 }
308 
309 static EContactAddress*
310 getContactAddress( EContact *pContact, int * address_enum )
311 {
312 	EContactAddress *ec = NULL;
313     switch (*address_enum) {
314 
315         case DEFAULT_ADDR_LINE1:
316         case DEFAULT_ADDR_LINE2:
317         case DEFAULT_CITY:
318         case DEFAULT_STATE:
319         case DEFAULT_COUNTRY:
320         case DEFAULT_ZIP:
321 			ec = getDefaultContactAddress(pContact,address_enum);break;
322    		default:
323 			ec = (EContactAddress *)e_contact_get(pContact,whichAddress(*address_enum));
324     }
325 	return ec;
326 }
327 
328 static bool
329 handleSplitAddress( EContact *pContact,GValue *pStackValue, int value )
330 {
331 	EContactAddress *ec = getContactAddress(pContact,&value) ;
332 
333 	if (ec==NULL)
334 		return true;
335 
336 	switch (value) {
337     	case WORK_ADDR_LINE1:
338 		    g_value_set_string(pStackValue,ec->street ); break;
339 	    case WORK_ADDR_LINE2:
340 		    g_value_set_string(pStackValue,ec->po ); break;
341     	case WORK_CITY:
342 	    	g_value_set_string(pStackValue,ec->locality ); break;
343     	case WORK_STATE:
344  	    	g_value_set_string(pStackValue,ec->region ); break;
345     	case WORK_COUNTRY:
346 	    	g_value_set_string(pStackValue,ec->country ); break;
347     	case WORK_ZIP:
348 	    	g_value_set_string(pStackValue,ec->code ); break;
349 
350         case HOME_ADDR_LINE1:
351 			g_value_set_string(pStackValue,ec->street ); break;
352         case HOME_ADDR_LINE2:
353 			g_value_set_string(pStackValue,ec->po ); break;
354         case HOME_CITY:
355 			g_value_set_string(pStackValue,ec->locality ); break;
356         case HOME_STATE:
357 			g_value_set_string(pStackValue,ec->region ); break;
358         case HOME_COUNTRY:
359 			g_value_set_string(pStackValue,ec->country ); break;
360         case HOME_ZIP:
361 			g_value_set_string(pStackValue,ec->code ); break;
362 
363         case OTHER_ADDR_LINE1:
364 			g_value_set_string(pStackValue,ec->street ); break;
365         case OTHER_ADDR_LINE2:
366 			g_value_set_string(pStackValue,ec->po ); break;
367         case OTHER_CITY:
368 			g_value_set_string(pStackValue,ec->locality ); break;
369         case OTHER_STATE:
370 			g_value_set_string(pStackValue,ec->region ); break;
371         case OTHER_COUNTRY:
372 			g_value_set_string(pStackValue,ec->country ); break;
373         case OTHER_ZIP:
374 			g_value_set_string(pStackValue,ec->code ); break;
375 
376 	}
377 
378     return false;
379 }
380 static bool
381 getValue( EContact* pContact, sal_Int32 nColumnNum, GType nType, GValue* pStackValue, bool& _out_rWasNull )
382 {
383 	const ColumnProperty * pSpecs = evoab::getField( nColumnNum );
384 	if ( !pSpecs )
385 		return false;
386 
387 	GParamSpec* pSpec = pSpecs->pField;
388 	gboolean bIsSplittedColumn = pSpecs->bIsSplittedValue;
389 
390 	_out_rWasNull = true;
391 	if ( !pSpec || !pContact)
392 		return false;
393 
394 	if ( G_PARAM_SPEC_VALUE_TYPE (pSpec) != nType )
395 	{
396 
397 		OSL_TRACE( "Wrong type (0x%x) (0x%x) '%s'",
398 				   (int)G_PARAM_SPEC_VALUE_TYPE (pSpec), (int) nType,
399 				   pSpec->name ? pSpec->name : "<noname>");
400 		return false;
401 	}
402 
403     g_value_init( pStackValue, nType );
404 	if ( bIsSplittedColumn )
405 	{
406         const SplitEvoColumns* evo_addr( get_evo_addr() );
407 		for (int i=0;i<OTHER_ZIP;i++)
408 		{
409 			if (0 == strcmp (g_param_spec_get_name ((GParamSpec *)pSpec), evo_addr[i].pColumnName))
410 			{
411 				_out_rWasNull = handleSplitAddress( pContact, pStackValue, evo_addr[i].value );
412 				return true;
413 			}
414 		}
415 	}
416 	else
417 	{
418 		g_object_get_property( G_OBJECT (pContact),
419 							   g_param_spec_get_name ((GParamSpec *) pSpec),
420 							   pStackValue );
421 		if ( G_VALUE_TYPE( pStackValue ) != nType )
422 		{
423 			OSL_TRACE( "Fetched type mismatch" );
424 			g_value_unset( pStackValue );
425 			return false;
426 		}
427 	}
428 	_out_rWasNull = false;
429 	return true;
430 }
431 
432 namespace
433 {
434     struct ComparisonData
435     {
436         const SortDescriptor&   rSortOrder;
437         IntlWrapper             aIntlWrapper;
438 
439         ComparisonData( const SortDescriptor& _rSortOrder, const Reference< XMultiServiceFactory >& _rxFactory )
440             :rSortOrder( _rSortOrder )
441             ,aIntlWrapper( _rxFactory, SvtSysLocale().GetLocaleData().getLocale() )
442         {
443         }
444     };
445 }
446 
447 extern "C"
448 int CompareContacts( gconstpointer _lhs, gconstpointer _rhs, gpointer _userData )
449 {
450     EContact* lhs = static_cast< EContact* >( const_cast< gpointer >( _lhs ) );
451     EContact* rhs = static_cast< EContact* >( const_cast< gpointer >( _rhs ) );
452 
453     GValue aLhsValue = { 0, { { 0 } } };
454     GValue aRhsValue = { 0, { { 0 } } };
455     bool bLhsNull = true;
456     bool bRhsNull = true;
457 
458     ::rtl::OUString sLhs, sRhs;
459     bool bLhs(false), bRhs(false);
460 
461     const ComparisonData& rCompData = *static_cast< const ComparisonData* >( _userData );
462     for (   SortDescriptor::const_iterator sortCol = rCompData.rSortOrder.begin();
463             sortCol != rCompData.rSortOrder.end();
464             ++sortCol
465         )
466     {
467         sal_Int32 nField = sortCol->nField;
468         GType eFieldType = evoab::getGFieldType( nField );
469 
470         bool success =  getValue( lhs, nField, eFieldType, &aLhsValue, bLhsNull )
471                     &&  getValue( rhs, nField, eFieldType, &aRhsValue, bRhsNull );
472         OSL_ENSURE( success, "CompareContacts: could not retrieve both values!" );
473         if ( !success )
474             return 0;
475 
476         if ( bLhsNull && !bRhsNull )
477             return -1;
478         if ( !bLhsNull && bRhsNull )
479             return 1;
480         if ( bLhsNull && bRhsNull )
481             continue;
482 
483         if ( eFieldType == G_TYPE_STRING )
484         {
485             sLhs = valueToOUString( aLhsValue );
486             sRhs = valueToOUString( aRhsValue );
487             sal_Int32 nCompResult = rCompData.aIntlWrapper.getCaseCollator()->compareString( sLhs, sRhs );
488             if ( nCompResult != 0 )
489                 return nCompResult;
490             continue;
491         }
492 
493         bLhs = valueToBool( aLhsValue );
494         bRhs = valueToBool( aRhsValue );
495         if ( bLhs && !bRhs )
496             return -1;
497         if ( !bLhs && bRhs )
498             return 1;
499         continue;
500     }
501 
502     return 0;
503 }
504 
505 static GList*
506 sortContacts( GList* _pContactList, const ComparisonData& _rCompData )
507 {
508     OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" );
509     ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" );
510 
511     return g_list_sort_with_data( _pContactList, &CompareContacts, const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) );
512 }
513 
514 // -------------------------------------------------------------------------
515 void OEvoabResultSet::construct( const QueryData& _rData )
516 {
517     ENSURE_OR_THROW( _rData.getQuery(), "internal error: no EBookQuery" );
518 
519     EBook *pBook = openBook( ::rtl::OUStringToOString( _rData.sTable, RTL_TEXTENCODING_UTF8 ) );
520     if ( !pBook )
521         m_pConnection->throwGenericSQLException( STR_CANNOT_OPEN_BOOK, *this );
522 
523 	g_list_free(m_pContacts);
524 	m_pContacts = NULL;
525     bool bExecuteQuery = true;
526     switch ( _rData.eFilterType )
527     {
528         case eFilterNone:
529             if ( !isLocal( pBook ) )
530             {
531                 SQLError aErrorFactory( m_pConnection->getDriver().getMSFactory() );
532                 SQLException aAsException = aErrorFactory.getSQLException( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED, *this );
533                 m_aWarnings.appendWarning( SQLWarning(
534                     aAsException.Message,
535                     aAsException.Context,
536                     aAsException.SQLState,
537                     aAsException.ErrorCode,
538                     aAsException.NextException
539                 ) );
540                 bExecuteQuery = false;
541             }
542             break;
543         case eFilterAlwaysFalse:
544             bExecuteQuery = false;
545             break;
546         case eFilterOther:
547             bExecuteQuery = true;
548             break;
549     }
550     if ( bExecuteQuery )
551 	{
552 		rtl::OString aPassword = m_pConnection->getPassword();
553 		executeQuery( pBook, _rData.getQuery(), &m_pContacts, aPassword, NULL );
554 		m_pConnection->setPassword( aPassword );
555 
556         if ( m_pContacts && !_rData.aSortOrder.empty() )
557         {
558             ComparisonData aCompData( _rData.aSortOrder, getConnection()->getDriver().getMSFactory() );
559             m_pContacts = sortContacts( m_pContacts, aCompData );
560         }
561 	}
562 	m_nLength = g_list_length( m_pContacts );
563 	OSL_TRACE( "Query return %d records", m_nLength );
564 	m_nIndex = -1;
565 
566     // create our meta data (need the EBookQuery for this)
567     OEvoabResultSetMetaData* pMeta = new OEvoabResultSetMetaData( _rData.sTable );
568 	m_xMetaData = pMeta;
569 
570 	pMeta->setEvoabFields( _rData.xSelectColumns );
571 }
572 
573 // -------------------------------------------------------------------------
574 void OEvoabResultSet::disposing(void)
575 {
576 	::comphelper::OPropertyContainer::disposing();
577 
578 	::osl::MutexGuard aGuard(m_aMutex);
579 	g_list_free(m_pContacts);
580 	m_pContacts = NULL;
581 	m_pStatement = NULL;
582 m_xMetaData.clear();
583 }
584 // -------------------------------------------------------------------------
585 Any SAL_CALL OEvoabResultSet::queryInterface( const Type & rType ) throw(RuntimeException)
586 {
587 	Any aRet = ::comphelper::OPropertyContainer::queryInterface(rType);
588 	if(!aRet.hasValue())
589 		aRet = OResultSet_BASE::queryInterface(rType);
590 	return aRet;
591 }
592 // -------------------------------------------------------------------------
593 Sequence< Type > SAL_CALL OEvoabResultSet::getTypes(  ) throw( RuntimeException)
594 {
595 	return ::comphelper::concatSequences(
596         OResultSet_BASE::getTypes(),
597         ::comphelper::OPropertyContainer::getTypes()
598     );
599 }
600 
601 // -------------------------------------------------------------------------
602 // XRow Interface
603 
604 /**
605  * getString:
606  * @nColumnNum: The column index from the table.
607  *
608  * If the equivalent NResultSetMetaData.cxx marks the columntype of
609  * nColumnNum as DataType::VARCHAR this accessor is used.
610  */
611 ::rtl::OUString SAL_CALL OEvoabResultSet::getString( sal_Int32 nColumnNum ) throw(SQLException, RuntimeException)
612 {
613 	::osl::MutexGuard aGuard( m_aMutex );
614 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
615 	rtl::OUString aResult;
616 	if ( m_xMetaData.is())
617     {
618         OEvoabResultSetMetaData *pMeta = (OEvoabResultSetMetaData *) m_xMetaData.get();
619         sal_Int32 nFieldNumber = pMeta->fieldAtColumn(nColumnNum);
620 		GValue aValue = { 0, { { 0 } } };
621 		if ( getValue( getCur(), nFieldNumber, G_TYPE_STRING, &aValue, m_bWasNull ) )
622             aResult = valueToOUString( aValue );
623 	}
624 	return aResult;
625 }
626 // -------------------------------------------------------------------------
627 sal_Bool SAL_CALL OEvoabResultSet::getBoolean( sal_Int32 nColumnNum ) throw(SQLException, RuntimeException)
628 {
629 	::osl::MutexGuard aGuard( m_aMutex );
630 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
631 	sal_Bool bResult = sal_False;
632 
633 	if ( m_xMetaData.is())
634     {
635         OEvoabResultSetMetaData *pMeta = (OEvoabResultSetMetaData *) m_xMetaData.get();
636         sal_Int32 nFieldNumber = pMeta->fieldAtColumn(nColumnNum);
637 		GValue aValue = { 0, { { 0 } } };
638 		if ( getValue( getCur(), nFieldNumber, G_TYPE_BOOLEAN, &aValue, m_bWasNull ) )
639             bResult = valueToBool( aValue );
640 	}
641 	return bResult ? sal_True : sal_False;
642 }
643 // -------------------------------------------------------------------------
644 sal_Int64 SAL_CALL OEvoabResultSet::getLong( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
645 {
646     ::dbtools::throwFunctionNotSupportedException( "XRow::getLong", *this );
647 	return sal_Int64();
648 }
649 // -------------------------------------------------------------------------
650 Reference< XArray > SAL_CALL OEvoabResultSet::getArray( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
651 {
652     ::dbtools::throwFunctionNotSupportedException( "XRow::getArray", *this );
653 	return NULL;
654 }
655 // -------------------------------------------------------------------------
656 Reference< XClob > SAL_CALL OEvoabResultSet::getClob( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
657 {
658     ::dbtools::throwFunctionNotSupportedException( "XRow::getClob", *this );
659 	return NULL;
660 }
661 // -------------------------------------------------------------------------
662 Reference< XBlob > SAL_CALL OEvoabResultSet::getBlob( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
663 {
664     ::dbtools::throwFunctionNotSupportedException( "XRow::getBlob", *this );
665 	return NULL;
666 }
667 // -------------------------------------------------------------------------
668 Reference< XRef > SAL_CALL OEvoabResultSet::getRef( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
669 {
670     ::dbtools::throwFunctionNotSupportedException( "XRow::getRef", *this );
671 	return NULL;
672 }
673 // -------------------------------------------------------------------------
674 Any SAL_CALL OEvoabResultSet::getObject( sal_Int32 /*nColumnNum*/, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
675 {
676     ::dbtools::throwFunctionNotSupportedException( "XRow::getObject", *this );
677 	return Any();
678 }
679 // -------------------------------------------------------------------------
680 sal_Int16 SAL_CALL OEvoabResultSet::getShort( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
681 {
682     ::dbtools::throwFunctionNotSupportedException( "XRow::getShort", *this );
683 	return 0;
684 }
685 // -------------------------------------------------------------------------
686 ::com::sun::star::util::Time SAL_CALL OEvoabResultSet::getTime( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
687 {
688     ::dbtools::throwFunctionNotSupportedException( "XRow::getTime", *this );
689 	return ::com::sun::star::util::Time();
690 }
691 // -------------------------------------------------------------------------
692 util::DateTime SAL_CALL OEvoabResultSet::getTimestamp( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
693 {
694     ::dbtools::throwFunctionNotSupportedException( "XRow::getTimestamp", *this );
695 	return ::com::sun::star::util::DateTime();
696 }
697 // -------------------------------------------------------------------------
698 Reference< XInputStream > SAL_CALL OEvoabResultSet::getBinaryStream( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
699 {
700     ::dbtools::throwFunctionNotSupportedException( "XRow::getBinaryStream", *this );
701 	return NULL;
702 }
703 // -------------------------------------------------------------------------
704 Reference< XInputStream > SAL_CALL OEvoabResultSet::getCharacterStream( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
705 {
706     ::dbtools::throwFunctionNotSupportedException( "XRow::getCharacterStream", *this );
707 	return NULL;
708 }
709 // -------------------------------------------------------------------------
710 sal_Int8 SAL_CALL OEvoabResultSet::getByte( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
711 {
712     ::dbtools::throwFunctionNotSupportedException( "XRow::getByte", *this );
713 	return 0;
714 }
715 // -------------------------------------------------------------------------
716 Sequence< sal_Int8 > SAL_CALL OEvoabResultSet::getBytes( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
717 {
718     ::dbtools::throwFunctionNotSupportedException( "XRow::getBytes", *this );
719 	return Sequence< sal_Int8 >();
720 }
721 // -------------------------------------------------------------------------
722 ::com::sun::star::util::Date SAL_CALL OEvoabResultSet::getDate( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
723 {
724     ::dbtools::throwFunctionNotSupportedException( "XRow::getDate", *this );
725 	return ::com::sun::star::util::Date();
726 }
727 // -------------------------------------------------------------------------
728 double SAL_CALL OEvoabResultSet::getDouble( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
729 {
730     ::dbtools::throwFunctionNotSupportedException( "XRow::getDouble", *this );
731 	return 0;
732 }
733 // -------------------------------------------------------------------------
734 float SAL_CALL OEvoabResultSet::getFloat( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
735 {
736     ::dbtools::throwFunctionNotSupportedException( "XRow::getFloat", *this );
737 	return 0;
738 }
739 // -------------------------------------------------------------------------
740 sal_Int32 SAL_CALL OEvoabResultSet::getInt( sal_Int32 /*nColumnNum*/ ) throw(SQLException, RuntimeException)
741 {
742     ::dbtools::throwFunctionNotSupportedException( "XRow::getInt", *this );
743 	return 0;
744 }
745 // XRow Interface Ends
746 // -------------------------------------------------------------------------
747 
748 // XResultSetMetaDataSupplier Interface
749 Reference< XResultSetMetaData > SAL_CALL OEvoabResultSet::getMetaData(  ) throw(SQLException, RuntimeException)
750 {
751 	::osl::MutexGuard aGuard( m_aMutex );
752 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
753 
754     // the meta data should have been created at construction time
755     ENSURE_OR_THROW( m_xMetaData.is(), "internal error: no meta data" );
756 	return m_xMetaData;
757 }
758 // XResultSetMetaDataSupplier Interface Ends
759 // -------------------------------------------------------------------------
760 
761 // XResultSet Interface
762 sal_Bool SAL_CALL OEvoabResultSet::next(  ) throw(SQLException, RuntimeException)
763 {
764 	::osl::MutexGuard aGuard( m_aMutex );
765 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
766 	if (m_nIndex+1 < m_nLength) {
767 		++m_nIndex ;
768 		return true;
769 	}
770 	else
771 		return false;
772 }
773 // -------------------------------------------------------------------------
774 sal_Bool SAL_CALL OEvoabResultSet::wasNull(  ) throw(SQLException, RuntimeException)
775 {
776 	::osl::MutexGuard aGuard( m_aMutex );
777 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
778 
779 	return m_bWasNull;
780 }
781 // -------------------------------------------------------------------------
782 sal_Bool SAL_CALL OEvoabResultSet::isBeforeFirst(  ) throw(SQLException, RuntimeException)
783 {
784 	::osl::MutexGuard aGuard( m_aMutex );
785 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
786 
787 	return m_nIndex < 0;
788 }
789 // -------------------------------------------------------------------------
790 sal_Int32 SAL_CALL OEvoabResultSet::getRow(  ) throw(SQLException, RuntimeException)
791 {
792 	::osl::MutexGuard aGuard( m_aMutex );
793 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
794 
795 	return m_nIndex;
796 }
797 // -------------------------------------------------------------------------
798 sal_Bool SAL_CALL OEvoabResultSet::isAfterLast(  ) throw(SQLException, RuntimeException)
799 {
800 	::osl::MutexGuard aGuard( m_aMutex );
801 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
802 
803 	return m_nIndex >= m_nLength;
804 }
805 // -------------------------------------------------------------------------
806 sal_Bool SAL_CALL OEvoabResultSet::isFirst(  ) throw(SQLException, RuntimeException)
807 {
808 	::osl::MutexGuard aGuard( m_aMutex );
809 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
810 
811 	return m_nIndex == 0;
812 }
813 // -------------------------------------------------------------------------
814 sal_Bool SAL_CALL OEvoabResultSet::isLast(  ) throw(SQLException, RuntimeException)
815 {
816 	::osl::MutexGuard aGuard( m_aMutex );
817 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
818 
819 	return m_nIndex == m_nLength - 1;
820 }
821 // -------------------------------------------------------------------------
822 void SAL_CALL OEvoabResultSet::beforeFirst(  ) throw(SQLException, RuntimeException)
823 {
824 	::osl::MutexGuard aGuard( m_aMutex );
825 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
826 
827 	m_nIndex = -1;
828 }
829 // -------------------------------------------------------------------------
830 void SAL_CALL OEvoabResultSet::afterLast(  ) throw(SQLException, RuntimeException)
831 {
832 	::osl::MutexGuard aGuard( m_aMutex );
833 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
834 
835 	m_nIndex = m_nLength;
836 }
837 // -------------------------------------------------------------------------
838 
839 sal_Bool SAL_CALL OEvoabResultSet::first(  ) throw(SQLException, RuntimeException)
840 {
841 	::osl::MutexGuard aGuard( m_aMutex );
842 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
843 
844 	m_nIndex = 0;
845 	return true;
846 }
847 // -------------------------------------------------------------------------
848 
849 sal_Bool SAL_CALL OEvoabResultSet::last(  ) throw(SQLException, RuntimeException)
850 {
851 	::osl::MutexGuard aGuard( m_aMutex );
852 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
853 
854 	m_nIndex = m_nLength - 1;
855 	return true;
856 }
857 // -------------------------------------------------------------------------
858 sal_Bool SAL_CALL OEvoabResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
859 {
860 	::osl::MutexGuard aGuard( m_aMutex );
861 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
862 	if (row < m_nLength) {
863 		m_nIndex = row;
864 		return true;
865 	}
866 	else
867 		return false;
868 }
869 // -------------------------------------------------------------------------
870 sal_Bool SAL_CALL OEvoabResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException)
871 {
872 	::osl::MutexGuard aGuard( m_aMutex );
873 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
874 
875 	if ((m_nIndex+row) < m_nLength) {
876 		m_nIndex += row;
877 		return true;
878 	}
879 	else
880 		return false;
881 }
882 // -------------------------------------------------------------------------
883 sal_Bool SAL_CALL OEvoabResultSet::previous(  ) throw(SQLException, RuntimeException)
884 {
885 	::osl::MutexGuard aGuard( m_aMutex );
886 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
887 
888 	if(m_nIndex > 0) {
889 		m_nIndex--;
890 		return true;
891 	}
892         else
893 		return false;
894 }
895 // -------------------------------------------------------------------------
896 Reference< XInterface > SAL_CALL OEvoabResultSet::getStatement(  ) throw(SQLException, RuntimeException)
897 {
898 	::osl::MutexGuard aGuard( m_aMutex );
899 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
900 ::com::sun::star::uno::WeakReferenceHelper      aStatement((OWeakObject*)m_pStatement);
901 	return aStatement.get();
902 }
903 // -------------------------------------------------------------------------
904 
905 sal_Bool SAL_CALL OEvoabResultSet::rowDeleted(  ) throw(SQLException, RuntimeException)
906 {
907 	::osl::MutexGuard aGuard( m_aMutex );
908 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
909 
910 	return sal_False;
911 }
912 // -------------------------------------------------------------------------
913 sal_Bool SAL_CALL OEvoabResultSet::rowInserted(  ) throw(SQLException, RuntimeException)
914 {
915 	::osl::MutexGuard aGuard( m_aMutex );
916 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
917 
918 	return sal_False;
919 }
920 // -------------------------------------------------------------------------
921 sal_Bool SAL_CALL OEvoabResultSet::rowUpdated(  ) throw(SQLException, RuntimeException)
922 {
923 	::osl::MutexGuard aGuard( m_aMutex );
924 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
925 
926 	return sal_False;
927 }
928 // -------------------------------------------------------------------------
929 void SAL_CALL OEvoabResultSet::refreshRow(  ) throw(SQLException, RuntimeException)
930 {
931 	::osl::MutexGuard aGuard( m_aMutex );
932 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
933 }
934 //XResult Interface ends
935 // -------------------------------------------------------------------------
936 // XCancellable
937 
938 void SAL_CALL OEvoabResultSet::cancel(  ) throw(RuntimeException)
939 {
940 	::osl::MutexGuard aGuard( m_aMutex );
941 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
942 	OSL_TRACE("In/Out: OEvoabResultSet::cancel" );
943 
944 }
945 
946 //XCloseable
947 void SAL_CALL OEvoabResultSet::close(  ) throw(SQLException, RuntimeException)
948 {
949 	{
950 		::osl::MutexGuard aGuard( m_aMutex );
951 		checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
952 	}
953 	OSL_TRACE("In/Out: OEvoabResultSet::close" );
954 	dispose();
955 }
956 
957 // XWarningsSupplier
958 // -------------------------------------------------------------------------
959 void SAL_CALL OEvoabResultSet::clearWarnings(  ) throw(SQLException, RuntimeException)
960 {
961 	OSL_TRACE("In/Out: OEvoabResultSet::clearWarnings" );
962     m_aWarnings.clearWarnings();
963 }
964 // -------------------------------------------------------------------------
965 Any SAL_CALL OEvoabResultSet::getWarnings(  ) throw(SQLException, RuntimeException)
966 {
967 	OSL_TRACE("In/Out: OEvoabResultSet::getWarnings" );
968     return m_aWarnings.getWarnings();
969 }
970 // -------------------------------------------------------------------------
971 //XColumnLocate Interface
972 sal_Int32 SAL_CALL OEvoabResultSet::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
973 {
974 	::osl::MutexGuard aGuard( m_aMutex );
975 	checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
976 
977 	// find the first column with the name columnName
978 	Reference< XResultSetMetaData > xMeta = getMetaData();
979 	sal_Int32 nLen = xMeta->getColumnCount();
980 	sal_Int32 i = 1;
981 	for(;i<=nLen;++i)
982 		if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
983 				columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
984 			break;
985 	return i;
986 }
987 // -------------------------------------------------------------------------
988 //XColumnLocate interface ends
989 
990 // -------------------------------------------------------------------------
991 ::cppu::IPropertyArrayHelper* OEvoabResultSet::createArrayHelper( ) const
992 {
993     Sequence< Property > aProps;
994     describeProperties( aProps );
995     return new ::cppu::OPropertyArrayHelper( aProps );
996 }
997 // -------------------------------------------------------------------------
998 ::cppu::IPropertyArrayHelper & OEvoabResultSet::getInfoHelper()
999 {
1000 	return *const_cast<OEvoabResultSet*>(this)->getArrayHelper();
1001 }
1002 // -----------------------------------------------------------------------------
1003 void SAL_CALL OEvoabResultSet::acquire() throw()
1004 {
1005 	OResultSet_BASE::acquire();
1006 }
1007 // -----------------------------------------------------------------------------
1008 void SAL_CALL OEvoabResultSet::release() throw()
1009 {
1010 	OResultSet_BASE::release();
1011 }
1012 // -----------------------------------------------------------------------------
1013 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
1014 OEvoabResultSet::getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException)
1015 {
1016 	return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1017 }
1018 // -----------------------------------------------------------------------------
1019 
1020 } } // connectivity::evoab
1021