xref: /trunk/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