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