bump product version to 7.2.5.1
[LibreOffice.git] / connectivity / source / drivers / evoab2 / NResultSet.cxx
blob9c9e1f302a059918d128102e1b291f03be96ca77
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "NDatabaseMetaData.hxx"
22 #include "NConnection.hxx"
23 #include "NResultSet.hxx"
24 #include <propertyids.hxx>
25 #include <strings.hrc>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <com/sun/star/sdb/ErrorCondition.hpp>
29 #include <com/sun/star/sdbc/FetchDirection.hpp>
30 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
31 #include <com/sun/star/sdbc/ResultSetType.hpp>
33 #include <comphelper/sequence.hxx>
34 #include <cppuhelper/supportsservice.hxx>
35 #include <connectivity/dbexception.hxx>
36 #include <connectivity/sqlerror.hxx>
37 #include <rtl/string.hxx>
38 #include <sal/log.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <unotools/syslocale.hxx>
41 #include <unotools/intlwrapper.hxx>
42 #include <unotools/collatorwrapper.hxx>
44 #include <cstring>
46 namespace connectivity::evoab {
48 using namespace ::comphelper;
49 using namespace com::sun::star;
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::beans;
53 using namespace com::sun::star::sdbc;
54 using namespace com::sun::star::sdbcx;
55 using namespace com::sun::star::container;
56 using namespace com::sun::star::io;
57 namespace ErrorCondition = ::com::sun::star::sdb::ErrorCondition;
60 OUString SAL_CALL OEvoabResultSet::getImplementationName( )
62 return "com.sun.star.sdbcx.evoab.ResultSet";
65 Sequence< OUString > SAL_CALL OEvoabResultSet::getSupportedServiceNames( )
67 return { "com.sun.star.sdbc.ResultSet" };
70 sal_Bool SAL_CALL OEvoabResultSet::supportsService( const OUString& _rServiceName )
72 return cppu::supportsService(this, _rServiceName);
75 struct ComparisonData
77 const SortDescriptor& rSortOrder;
78 IntlWrapper aIntlWrapper;
80 ComparisonData(const SortDescriptor& _rSortOrder)
81 : rSortOrder(_rSortOrder)
82 , aIntlWrapper(SvtSysLocale().GetUILanguageTag())
87 static OUString
88 valueToOUString( GValue& _rValue )
90 const char *pStr = g_value_get_string( &_rValue );
91 OString aStr( pStr ? pStr : "" );
92 OUString sResult( OStringToOUString( aStr, RTL_TEXTENCODING_UTF8 ) );
93 g_value_unset( &_rValue );
94 return sResult;
97 static bool
98 valueToBool( GValue& _rValue )
100 bool bResult = g_value_get_boolean( &_rValue );
101 g_value_unset( &_rValue );
102 return bResult;
105 static int
106 whichAddress(int value)
108 int fieldEnum;
109 switch (value)
111 case HOME_ADDR_LINE1:
112 case HOME_ADDR_LINE2:
113 case HOME_CITY:
114 case HOME_STATE:
115 case HOME_COUNTRY:
116 case HOME_ZIP:
117 fieldEnum = e_contact_field_id("address_home");
118 break;
120 case WORK_ADDR_LINE1:
121 case WORK_ADDR_LINE2:
122 case WORK_CITY:
123 case WORK_STATE:
124 case WORK_COUNTRY:
125 case WORK_ZIP:
126 fieldEnum = e_contact_field_id("address_work");
127 break;
129 case OTHER_ADDR_LINE1:
130 case OTHER_ADDR_LINE2:
131 case OTHER_CITY:
132 case OTHER_STATE:
133 case OTHER_COUNTRY:
134 case OTHER_ZIP:
135 fieldEnum = e_contact_field_id("address_other");
136 break;
138 default: fieldEnum = e_contact_field_id("address_home");
140 return fieldEnum;
144 * This function decides the default column values based on the first field of EContactAddress.
145 * The search order is Work->Home->other(defaults).
147 static EContactAddress *
148 getDefaultContactAddress( EContact *pContact,int *value )
150 EContactAddress *ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(WORK_ADDR_LINE1)));
151 if ( ec && (ec->street[0]!='\0') )
153 *value= *value +WORK_ADDR_LINE1 -1;
154 return ec;
156 else
158 ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(HOME_ADDR_LINE1)));
159 if ( ec && (ec->street[0]!='\0') )
161 *value=*value+HOME_ADDR_LINE1-1;
162 return ec;
166 *value=*value+OTHER_ADDR_LINE1-1;
167 return static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(OTHER_ADDR_LINE1)));
170 static EContactAddress*
171 getContactAddress( EContact *pContact, int * address_enum )
173 EContactAddress *ec = nullptr;
174 switch (*address_enum) {
176 case DEFAULT_ADDR_LINE1:
177 case DEFAULT_ADDR_LINE2:
178 case DEFAULT_CITY:
179 case DEFAULT_STATE:
180 case DEFAULT_COUNTRY:
181 case DEFAULT_ZIP:
182 ec = getDefaultContactAddress(pContact,address_enum);break;
183 default:
184 ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(*address_enum)));
186 return ec;
189 static bool
190 handleSplitAddress( EContact *pContact,GValue *pStackValue, int value )
192 EContactAddress *ec = getContactAddress(pContact,&value) ;
194 if (ec==nullptr)
195 return true;
197 switch (value) {
198 case WORK_ADDR_LINE1:
199 g_value_set_string(pStackValue,ec->street ); break;
200 case WORK_ADDR_LINE2:
201 g_value_set_string(pStackValue,ec->po ); break;
202 case WORK_CITY:
203 g_value_set_string(pStackValue,ec->locality ); break;
204 case WORK_STATE:
205 g_value_set_string(pStackValue,ec->region ); break;
206 case WORK_COUNTRY:
207 g_value_set_string(pStackValue,ec->country ); break;
208 case WORK_ZIP:
209 g_value_set_string(pStackValue,ec->code ); break;
211 case HOME_ADDR_LINE1:
212 g_value_set_string(pStackValue,ec->street ); break;
213 case HOME_ADDR_LINE2:
214 g_value_set_string(pStackValue,ec->po ); break;
215 case HOME_CITY:
216 g_value_set_string(pStackValue,ec->locality ); break;
217 case HOME_STATE:
218 g_value_set_string(pStackValue,ec->region ); break;
219 case HOME_COUNTRY:
220 g_value_set_string(pStackValue,ec->country ); break;
221 case HOME_ZIP:
222 g_value_set_string(pStackValue,ec->code ); break;
224 case OTHER_ADDR_LINE1:
225 g_value_set_string(pStackValue,ec->street ); break;
226 case OTHER_ADDR_LINE2:
227 g_value_set_string(pStackValue,ec->po ); break;
228 case OTHER_CITY:
229 g_value_set_string(pStackValue,ec->locality ); break;
230 case OTHER_STATE:
231 g_value_set_string(pStackValue,ec->region ); break;
232 case OTHER_COUNTRY:
233 g_value_set_string(pStackValue,ec->country ); break;
234 case OTHER_ZIP:
235 g_value_set_string(pStackValue,ec->code ); break;
239 return false;
242 static bool
243 getValue( EContact* pContact, sal_Int32 nColumnNum, GType nType, GValue* pStackValue, bool& _out_rWasNull )
245 const ColumnProperty * pSpecs = evoab::getField( nColumnNum );
246 if ( !pSpecs )
247 return false;
249 GParamSpec* pSpec = pSpecs->pField;
250 bool bIsSplittedColumn = pSpecs->bIsSplittedValue;
252 _out_rWasNull = true;
253 if ( !pSpec || !pContact)
254 return false;
256 if ( G_PARAM_SPEC_VALUE_TYPE (pSpec) != nType )
258 SAL_WARN("connectivity.evoab2", "Wrong type (0x" << std::hex << static_cast<int>(G_PARAM_SPEC_VALUE_TYPE(pSpec)) << ") (0x"
259 << std::hex << static_cast<int>(nType) << ") " << (pSpec->name ? pSpec->name : "<noname>"));
260 return false;
263 g_value_init( pStackValue, nType );
264 if ( bIsSplittedColumn )
266 const SplitEvoColumns* evo_addr( get_evo_addr() );
267 for (int i=0;i<OTHER_ZIP;i++)
269 if (0 == strcmp (g_param_spec_get_name (pSpec), evo_addr[i].pColumnName))
271 _out_rWasNull = handleSplitAddress( pContact, pStackValue, evo_addr[i].value );
272 return true;
276 else
278 g_object_get_property( G_OBJECT (pContact),
279 g_param_spec_get_name (pSpec),
280 pStackValue );
281 if ( G_VALUE_TYPE( pStackValue ) != nType )
283 SAL_WARN("connectivity.evoab2", "Fetched type mismatch" );
284 g_value_unset( pStackValue );
285 return false;
288 _out_rWasNull = false;
289 return true;
292 extern "C" {
294 static int CompareContacts( gconstpointer _lhs, gconstpointer _rhs, gpointer _userData )
296 EContact* lhs = const_cast< gpointer >( _lhs );
297 EContact* rhs = const_cast< gpointer >( _rhs );
299 GValue aLhsValue = { 0, { { 0 } } };
300 GValue aRhsValue = { 0, { { 0 } } };
301 bool bLhsNull = true;
302 bool bRhsNull = true;
304 OUString sLhs, sRhs;
305 bool bLhs(false), bRhs(false);
307 const ComparisonData& rCompData = *static_cast< const ComparisonData* >( _userData );
308 for ( const auto& sortCol : rCompData.rSortOrder )
310 sal_Int32 nField = sortCol.nField;
311 GType eFieldType = evoab::getGFieldType( nField );
313 bool success = getValue( lhs, nField, eFieldType, &aLhsValue, bLhsNull )
314 && getValue( rhs, nField, eFieldType, &aRhsValue, bRhsNull );
315 OSL_ENSURE( success, "CompareContacts: could not retrieve both values!" );
316 if ( !success )
317 return 0;
319 if ( bLhsNull && !bRhsNull )
320 return -1;
321 if ( !bLhsNull && bRhsNull )
322 return 1;
323 if ( bLhsNull && bRhsNull )
324 continue;
326 if ( eFieldType == G_TYPE_STRING )
328 sLhs = valueToOUString( aLhsValue );
329 sRhs = valueToOUString( aRhsValue );
330 sal_Int32 nCompResult = rCompData.aIntlWrapper.getCaseCollator()->compareString( sLhs, sRhs );
331 if ( nCompResult != 0 )
332 return nCompResult;
333 continue;
336 bLhs = valueToBool( aLhsValue );
337 bRhs = valueToBool( aRhsValue );
338 if ( bLhs && !bRhs )
339 return -1;
340 if ( !bLhs && bRhs )
341 return 1;
342 continue;
345 return 0;
350 OString OEvoabVersionHelper::getUserName( EBook *pBook )
352 OString aName;
353 if( isLDAP( pBook ) )
354 aName = e_source_get_property( e_book_get_source( pBook ), "binddn" );
355 else
356 aName = e_source_get_property( e_book_get_source( pBook ), "user" );
357 return aName;
360 namespace {
362 bool isBookBackend( EBookClient *pBook, const char *backendname)
364 if (!pBook)
365 return false;
366 ESource *pSource = e_client_get_source (reinterpret_cast<EClient *>(pBook));
367 return isSourceBackend(pSource, backendname);
370 class OEvoabVersion36Helper : public OEvoabVersionHelper
372 private:
373 GSList *m_pContacts;
374 public:
375 OEvoabVersion36Helper()
376 : m_pContacts(nullptr)
380 virtual ~OEvoabVersion36Helper() override
382 freeContacts();
385 virtual EBook* openBook(const char *abname) override
387 //It would be better if here we had id to begin with, see
388 //NDatabaseMetaData.cxx
389 const char *id = nullptr;
390 GList *pSources = e_source_registry_list_sources(get_e_source_registry(), E_SOURCE_EXTENSION_ADDRESS_BOOK);
391 for (GList* liter = pSources; liter; liter = liter->next)
393 ESource *pSource = E_SOURCE (liter->data);
395 if (strcmp(abname, e_source_get_display_name( pSource )) == 0)
397 id = e_source_get_uid( pSource );
398 break;
401 g_list_foreach (pSources, reinterpret_cast<GFunc>(g_object_unref), nullptr);
402 g_list_free (pSources);
403 if (!id)
404 return nullptr;
406 ESource *pSource = e_source_registry_ref_source(get_e_source_registry(), id);
407 EBookClient *pBook = pSource ? createClient (pSource) : nullptr;
408 if (pBook && !e_client_open_sync (pBook, true, nullptr, nullptr))
410 g_object_unref (G_OBJECT (pBook));
411 pBook = nullptr;
413 if (pSource)
414 g_object_unref (pSource);
415 return pBook;
418 virtual bool isLDAP( EBook *pBook ) override
420 return isBookBackend(pBook, "ldap");
423 virtual bool isLocal( EBook *pBook ) override
425 return isBookBackend(pBook, "local");
428 virtual void freeContacts() override final
430 e_client_util_free_object_slist(m_pContacts);
431 m_pContacts = nullptr;
434 virtual void executeQuery (EBook* pBook, EBookQuery* pQuery, OString &/*rPassword*/) override
436 freeContacts();
437 char *sexp = e_book_query_to_string( pQuery );
438 e_book_client_get_contacts_sync( pBook, sexp, &m_pContacts, nullptr, nullptr );
439 g_free (sexp);
442 virtual EContact *getContact(sal_Int32 nIndex) override
444 gpointer pData = g_slist_nth_data (m_pContacts, nIndex);
445 return pData ? E_CONTACT (pData) : nullptr;
448 virtual sal_Int32 getNumContacts() override
450 return g_slist_length( m_pContacts );
453 virtual bool hasContacts() override
455 return m_pContacts != nullptr;
458 virtual void sortContacts( const ComparisonData& _rCompData ) override
460 OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" );
461 ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" );
463 m_pContacts = g_slist_sort_with_data( m_pContacts, &CompareContacts,
464 const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) );
467 protected:
468 virtual EBookClient * createClient( ESource *pSource )
470 return e_book_client_new (pSource, nullptr);
474 class OEvoabVersion38Helper : public OEvoabVersion36Helper
476 protected:
477 virtual EBookClient * createClient( ESource *pSource ) override
479 return e_book_client_connect_direct_sync (get_e_source_registry (), pSource, nullptr, nullptr);
483 ESource * findSource( const char *id )
485 ESourceList *pSourceList = nullptr;
487 g_return_val_if_fail (id != nullptr, nullptr);
489 if (!e_book_get_addressbooks (&pSourceList, nullptr))
490 pSourceList = nullptr;
492 for ( GSList *g = e_source_list_peek_groups (pSourceList); g; g = g->next)
494 for (GSList *s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next)
496 ESource *pSource = E_SOURCE (s->data);
497 if (!strcmp (e_source_peek_name (pSource), id))
498 return pSource;
501 return nullptr;
504 bool isAuthRequired( EBook *pBook )
506 return e_source_get_property( e_book_get_source( pBook ),
507 "auth" ) != nullptr;
510 class OEvoabVersion35Helper : public OEvoabVersionHelper
512 private:
513 GList *m_pContacts;
515 public:
516 OEvoabVersion35Helper()
517 : m_pContacts(nullptr)
521 virtual ~OEvoabVersion35Helper() override
523 freeContacts();
526 virtual EBook* openBook(const char *abname) override
528 ESource *pSource = findSource (abname);
529 EBook *pBook = pSource ? e_book_new (pSource, nullptr) : nullptr;
530 if (pBook && !e_book_open (pBook, true, nullptr))
532 g_object_unref (G_OBJECT (pBook));
533 pBook = nullptr;
535 return pBook;
538 virtual bool isLDAP( EBook *pBook ) override
540 return pBook && !strncmp( "ldap://", e_book_get_uri( pBook ), 6 );
543 virtual bool isLocal( EBook *pBook ) override
545 return pBook && ( !strncmp( "file://", e_book_get_uri( pBook ), 6 ) ||
546 !strncmp( "local:", e_book_get_uri( pBook ), 6 ) );
549 virtual void freeContacts() override final
551 g_list_free(m_pContacts);
552 m_pContacts = nullptr;
555 virtual void executeQuery (EBook* pBook, EBookQuery* pQuery, OString &rPassword) override
557 freeContacts();
559 ESource *pSource = e_book_get_source( pBook );
560 bool bAuthSuccess = true;
562 if( isAuthRequired( pBook ) )
564 OString aUser( getUserName( pBook ) );
565 const char *pAuth = e_source_get_property( pSource, "auth" );
566 bAuthSuccess = e_book_authenticate_user( pBook, aUser.getStr(), rPassword.getStr(), pAuth, nullptr );
569 if (bAuthSuccess)
570 e_book_get_contacts( pBook, pQuery, &m_pContacts, nullptr );
573 virtual EContact *getContact(sal_Int32 nIndex) override
575 gpointer pData = g_list_nth_data (m_pContacts, nIndex);
576 return pData ? E_CONTACT (pData) : nullptr;
579 virtual sal_Int32 getNumContacts() override
581 return g_list_length( m_pContacts );
584 virtual bool hasContacts() override
586 return m_pContacts != nullptr;
589 virtual void sortContacts( const ComparisonData& _rCompData ) override
591 OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" );
592 ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" );
594 m_pContacts = g_list_sort_with_data( m_pContacts, &CompareContacts,
595 const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) );
601 OEvoabResultSet::OEvoabResultSet( OCommonStatement* pStmt, OEvoabConnection *pConnection )
602 :OResultSet_BASE(m_aMutex)
603 ,::comphelper::OPropertyContainer( OResultSet_BASE::rBHelper )
604 ,m_pStatement(pStmt)
605 ,m_pConnection(pConnection)
606 ,m_bWasNull(true)
607 ,m_nFetchSize(0)
608 ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE)
609 ,m_nFetchDirection(FetchDirection::FORWARD)
610 ,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY)
611 ,m_nIndex(-1)
612 ,m_nLength(0)
614 if (eds_check_version( 3, 7, 6 ) == nullptr)
615 m_pVersionHelper = std::make_unique<OEvoabVersion38Helper>();
616 else if (eds_check_version( 3, 6, 0 ) == nullptr)
617 m_pVersionHelper = std::make_unique<OEvoabVersion36Helper>();
618 else
619 m_pVersionHelper = std::make_unique<OEvoabVersion35Helper>();
621 #define REGISTER_PROP( id, member ) \
622 registerProperty( \
623 OMetaConnection::getPropMap().getNameByIndex( id ), \
624 id, \
625 PropertyAttribute::READONLY, \
626 &member, \
627 cppu::UnoType<decltype(member)>::get() \
630 REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize );
631 REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType );
632 REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection );
633 REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency );
636 OEvoabResultSet::~OEvoabResultSet()
639 void OEvoabResultSet::construct( const QueryData& _rData )
641 ENSURE_OR_THROW( _rData.getQuery(), "internal error: no EBookQuery" );
643 EBook *pBook = m_pVersionHelper->openBook(OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr());
644 if ( !pBook )
645 m_pConnection->throwGenericSQLException( STR_CANNOT_OPEN_BOOK, *this );
647 m_pVersionHelper->freeContacts();
648 bool bExecuteQuery = true;
649 switch ( _rData.eFilterType )
651 case eFilterNone:
652 if ( !m_pVersionHelper->isLocal( pBook ) )
654 SQLError aErrorFactory;
655 SQLException aAsException = aErrorFactory.getSQLException( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED, *this );
656 m_aWarnings.appendWarning( SQLWarning(
657 aAsException.Message,
658 aAsException.Context,
659 aAsException.SQLState,
660 aAsException.ErrorCode,
661 aAsException.NextException
662 ) );
663 bExecuteQuery = false;
665 break;
666 case eFilterAlwaysFalse:
667 bExecuteQuery = false;
668 break;
669 case eFilterOther:
670 bExecuteQuery = true;
671 break;
673 if ( bExecuteQuery )
675 OString aPassword = m_pConnection->getPassword();
676 m_pVersionHelper->executeQuery(pBook, _rData.getQuery(), aPassword);
677 m_pConnection->setPassword( aPassword );
679 if ( m_pVersionHelper->hasContacts() && !_rData.aSortOrder.empty() )
681 ComparisonData aCompData(_rData.aSortOrder);
682 m_pVersionHelper->sortContacts(aCompData);
685 m_nLength = m_pVersionHelper->getNumContacts();
686 SAL_INFO("connectivity.evoab2", "Query return " << m_nLength << " records");
687 m_nIndex = -1;
689 // create our meta data (need the EBookQuery for this)
690 m_xMetaData = new OEvoabResultSetMetaData( _rData.sTable );
692 m_xMetaData->setEvoabFields( _rData.xSelectColumns );
696 void OEvoabResultSet::disposing()
698 ::comphelper::OPropertyContainer::disposing();
700 ::osl::MutexGuard aGuard(m_aMutex);
701 m_pVersionHelper.reset();
702 m_pStatement = nullptr;
703 m_xMetaData.clear();
706 Any SAL_CALL OEvoabResultSet::queryInterface( const Type & rType )
708 Any aRet = ::comphelper::OPropertyContainer::queryInterface(rType);
709 if(!aRet.hasValue())
710 aRet = OResultSet_BASE::queryInterface(rType);
711 return aRet;
714 Sequence< Type > SAL_CALL OEvoabResultSet::getTypes( )
716 return ::comphelper::concatSequences(
717 OResultSet_BASE::getTypes(),
718 getBaseTypes()
723 // XRow Interface
726 * getString:
727 * @nColumnNum: The column index from the table.
729 * If the equivalent NResultSetMetaData.cxx marks the columntype of
730 * nColumnNum as DataType::VARCHAR this accessor is used.
732 OUString SAL_CALL OEvoabResultSet::getString( sal_Int32 nColumnNum )
734 ::osl::MutexGuard aGuard( m_aMutex );
735 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
736 OUString aResult;
737 if ( m_xMetaData.is())
739 sal_Int32 nFieldNumber = m_xMetaData->fieldAtColumn(nColumnNum);
740 GValue aValue = { 0, { { 0 } } };
741 if ( getValue( getCur(), nFieldNumber, G_TYPE_STRING, &aValue, m_bWasNull ) )
742 aResult = valueToOUString( aValue );
744 return aResult;
747 sal_Bool SAL_CALL OEvoabResultSet::getBoolean( sal_Int32 nColumnNum )
749 ::osl::MutexGuard aGuard( m_aMutex );
750 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
751 bool bResult = false;
753 if ( m_xMetaData.is())
755 sal_Int32 nFieldNumber = m_xMetaData->fieldAtColumn(nColumnNum);
756 GValue aValue = { 0, { { 0 } } };
757 if ( getValue( getCur(), nFieldNumber, G_TYPE_BOOLEAN, &aValue, m_bWasNull ) )
758 bResult = valueToBool( aValue );
760 return bResult;
763 sal_Int64 SAL_CALL OEvoabResultSet::getLong( sal_Int32 /*nColumnNum*/ )
765 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getLong", *this );
766 return sal_Int64();
769 Reference< XArray > SAL_CALL OEvoabResultSet::getArray( sal_Int32 /*nColumnNum*/ )
771 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getArray", *this );
772 return nullptr;
775 Reference< XClob > SAL_CALL OEvoabResultSet::getClob( sal_Int32 /*nColumnNum*/ )
777 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getClob", *this );
778 return nullptr;
781 Reference< XBlob > SAL_CALL OEvoabResultSet::getBlob( sal_Int32 /*nColumnNum*/ )
783 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBlob", *this );
784 return nullptr;
787 Reference< XRef > SAL_CALL OEvoabResultSet::getRef( sal_Int32 /*nColumnNum*/ )
789 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getRef", *this );
790 return nullptr;
793 Any SAL_CALL OEvoabResultSet::getObject( sal_Int32 /*nColumnNum*/, const Reference< css::container::XNameAccess >& /*typeMap*/ )
795 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getObject", *this );
796 return Any();
799 sal_Int16 SAL_CALL OEvoabResultSet::getShort( sal_Int32 /*nColumnNum*/ )
801 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getShort", *this );
802 return 0;
805 css::util::Time SAL_CALL OEvoabResultSet::getTime( sal_Int32 /*nColumnNum*/ )
807 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getTime", *this );
808 return css::util::Time();
811 util::DateTime SAL_CALL OEvoabResultSet::getTimestamp( sal_Int32 /*nColumnNum*/ )
813 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getTimestamp", *this );
814 return css::util::DateTime();
817 Reference< XInputStream > SAL_CALL OEvoabResultSet::getBinaryStream( sal_Int32 /*nColumnNum*/ )
819 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBinaryStream", *this );
820 return nullptr;
823 Reference< XInputStream > SAL_CALL OEvoabResultSet::getCharacterStream( sal_Int32 /*nColumnNum*/ )
825 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getCharacterStream", *this );
826 return nullptr;
829 sal_Int8 SAL_CALL OEvoabResultSet::getByte( sal_Int32 /*nColumnNum*/ )
831 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getByte", *this );
832 return 0;
835 Sequence< sal_Int8 > SAL_CALL OEvoabResultSet::getBytes( sal_Int32 /*nColumnNum*/ )
837 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBytes", *this );
838 return Sequence< sal_Int8 >();
841 css::util::Date SAL_CALL OEvoabResultSet::getDate( sal_Int32 /*nColumnNum*/ )
843 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getDate", *this );
844 return css::util::Date();
847 double SAL_CALL OEvoabResultSet::getDouble( sal_Int32 /*nColumnNum*/ )
849 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getDouble", *this );
850 return 0;
853 float SAL_CALL OEvoabResultSet::getFloat( sal_Int32 /*nColumnNum*/ )
855 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getFloat", *this );
856 return 0;
859 sal_Int32 SAL_CALL OEvoabResultSet::getInt( sal_Int32 /*nColumnNum*/ )
861 ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getInt", *this );
862 return 0;
864 // XRow Interface Ends
867 // XResultSetMetaDataSupplier Interface
868 Reference< XResultSetMetaData > SAL_CALL OEvoabResultSet::getMetaData( )
870 ::osl::MutexGuard aGuard( m_aMutex );
871 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
873 // the meta data should have been created at construction time
874 ENSURE_OR_THROW( m_xMetaData.is(), "internal error: no meta data" );
875 return m_xMetaData;
877 // XResultSetMetaDataSupplier Interface Ends
880 // XResultSet Interface
881 sal_Bool SAL_CALL OEvoabResultSet::next( )
883 ::osl::MutexGuard aGuard( m_aMutex );
884 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
885 if (m_nIndex+1 < m_nLength) {
886 ++m_nIndex ;
887 return true;
889 else
890 return false;
893 sal_Bool SAL_CALL OEvoabResultSet::wasNull( )
895 ::osl::MutexGuard aGuard( m_aMutex );
896 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
898 return m_bWasNull;
901 sal_Bool SAL_CALL OEvoabResultSet::isBeforeFirst( )
903 ::osl::MutexGuard aGuard( m_aMutex );
904 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
906 return m_nIndex < 0;
909 sal_Int32 SAL_CALL OEvoabResultSet::getRow( )
911 ::osl::MutexGuard aGuard( m_aMutex );
912 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
914 return m_nIndex;
917 sal_Bool SAL_CALL OEvoabResultSet::isAfterLast( )
919 ::osl::MutexGuard aGuard( m_aMutex );
920 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
922 return m_nIndex >= m_nLength;
925 sal_Bool SAL_CALL OEvoabResultSet::isFirst( )
927 ::osl::MutexGuard aGuard( m_aMutex );
928 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
930 return m_nIndex == 0;
933 sal_Bool SAL_CALL OEvoabResultSet::isLast( )
935 ::osl::MutexGuard aGuard( m_aMutex );
936 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
938 return m_nIndex == m_nLength - 1;
941 void SAL_CALL OEvoabResultSet::beforeFirst( )
943 ::osl::MutexGuard aGuard( m_aMutex );
944 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
946 m_nIndex = -1;
949 void SAL_CALL OEvoabResultSet::afterLast( )
951 ::osl::MutexGuard aGuard( m_aMutex );
952 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
954 m_nIndex = m_nLength;
958 sal_Bool SAL_CALL OEvoabResultSet::first( )
960 ::osl::MutexGuard aGuard( m_aMutex );
961 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
963 m_nIndex = 0;
964 return true;
968 sal_Bool SAL_CALL OEvoabResultSet::last( )
970 ::osl::MutexGuard aGuard( m_aMutex );
971 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
973 m_nIndex = m_nLength - 1;
974 return true;
977 sal_Bool SAL_CALL OEvoabResultSet::absolute( sal_Int32 row )
979 ::osl::MutexGuard aGuard( m_aMutex );
980 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
981 if (row < m_nLength) {
982 m_nIndex = row;
983 return true;
985 else
986 return false;
989 sal_Bool SAL_CALL OEvoabResultSet::relative( sal_Int32 row )
991 ::osl::MutexGuard aGuard( m_aMutex );
992 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
994 if ((m_nIndex+row) < m_nLength) {
995 m_nIndex += row;
996 return true;
998 else
999 return false;
1002 sal_Bool SAL_CALL OEvoabResultSet::previous( )
1004 ::osl::MutexGuard aGuard( m_aMutex );
1005 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1007 if(m_nIndex > 0) {
1008 m_nIndex--;
1009 return true;
1011 else
1012 return false;
1015 Reference< XInterface > SAL_CALL OEvoabResultSet::getStatement( )
1017 ::osl::MutexGuard aGuard( m_aMutex );
1018 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1019 css::uno::WeakReferenceHelper aStatement(static_cast<OWeakObject*>(m_pStatement));
1020 return aStatement.get();
1024 sal_Bool SAL_CALL OEvoabResultSet::rowDeleted( )
1026 ::osl::MutexGuard aGuard( m_aMutex );
1027 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1029 return false;
1032 sal_Bool SAL_CALL OEvoabResultSet::rowInserted( )
1034 ::osl::MutexGuard aGuard( m_aMutex );
1035 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1037 return false;
1040 sal_Bool SAL_CALL OEvoabResultSet::rowUpdated( )
1042 ::osl::MutexGuard aGuard( m_aMutex );
1043 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1045 return false;
1048 void SAL_CALL OEvoabResultSet::refreshRow( )
1050 ::osl::MutexGuard aGuard( m_aMutex );
1051 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1053 //XResult Interface ends
1055 // XCancellable
1057 void SAL_CALL OEvoabResultSet::cancel( )
1059 ::osl::MutexGuard aGuard( m_aMutex );
1060 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1063 //XCloseable
1064 void SAL_CALL OEvoabResultSet::close( )
1067 ::osl::MutexGuard aGuard( m_aMutex );
1068 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1070 dispose();
1073 // XWarningsSupplier
1075 void SAL_CALL OEvoabResultSet::clearWarnings( )
1077 m_aWarnings.clearWarnings();
1080 Any SAL_CALL OEvoabResultSet::getWarnings( )
1082 return m_aWarnings.getWarnings();
1085 //XColumnLocate Interface
1086 sal_Int32 SAL_CALL OEvoabResultSet::findColumn( const OUString& columnName )
1088 ::osl::MutexGuard aGuard( m_aMutex );
1089 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1091 // find the first column with the name columnName
1092 Reference< XResultSetMetaData > xMeta = getMetaData();
1093 sal_Int32 nLen = xMeta->getColumnCount();
1094 sal_Int32 i = 1;
1095 for(;i<=nLen;++i)
1097 if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
1098 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
1099 return i;
1102 ::dbtools::throwInvalidColumnException( columnName, *this );
1103 assert(false);
1104 return 0; // Never reached
1107 //XColumnLocate interface ends
1110 ::cppu::IPropertyArrayHelper* OEvoabResultSet::createArrayHelper( ) const
1112 Sequence< Property > aProps;
1113 describeProperties( aProps );
1114 return new ::cppu::OPropertyArrayHelper( aProps );
1117 ::cppu::IPropertyArrayHelper & OEvoabResultSet::getInfoHelper()
1119 return *getArrayHelper();
1122 void SAL_CALL OEvoabResultSet::acquire() noexcept
1124 OResultSet_BASE::acquire();
1127 void SAL_CALL OEvoabResultSet::release() noexcept
1129 OResultSet_BASE::release();
1132 css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
1133 OEvoabResultSet::getPropertySetInfo( )
1135 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1139 } // connectivity::evoab
1141 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */