cid#1640468 Dereference after null check
[LibreOffice.git] / connectivity / source / drivers / evoab2 / NResultSet.cxx
blob95a25d6646021cd99cdb6af3df7299882ba306ee
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 <comphelper/diagnose_ex.hxx>
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::container;
55 using namespace com::sun::star::io;
56 namespace ErrorCondition = ::com::sun::star::sdb::ErrorCondition;
59 OUString SAL_CALL OEvoabResultSet::getImplementationName( )
61 return u"com.sun.star.sdbcx.evoab.ResultSet"_ustr;
64 Sequence< OUString > SAL_CALL OEvoabResultSet::getSupportedServiceNames( )
66 return { u"com.sun.star.sdbc.ResultSet"_ustr };
69 sal_Bool SAL_CALL OEvoabResultSet::supportsService( const OUString& _rServiceName )
71 return cppu::supportsService(this, _rServiceName);
74 struct ComparisonData
76 const SortDescriptor& rSortOrder;
77 IntlWrapper aIntlWrapper;
79 ComparisonData(const SortDescriptor& _rSortOrder)
80 : rSortOrder(_rSortOrder)
81 , aIntlWrapper(SvtSysLocale().GetUILanguageTag())
86 static OUString
87 valueToOUString( GValue& _rValue )
89 const char *pStr = g_value_get_string( &_rValue );
90 std::string_view aStr( pStr ? pStr : "" );
91 OUString sResult( OStringToOUString( aStr, RTL_TEXTENCODING_UTF8 ) );
92 g_value_unset( &_rValue );
93 return sResult;
96 static bool
97 valueToBool( GValue& _rValue )
99 bool bResult = g_value_get_boolean( &_rValue );
100 g_value_unset( &_rValue );
101 return bResult;
104 static int
105 whichAddress(int value)
107 int fieldEnum;
108 switch (value)
110 case HOME_ADDR_LINE1:
111 case HOME_ADDR_LINE2:
112 case HOME_CITY:
113 case HOME_STATE:
114 case HOME_COUNTRY:
115 case HOME_ZIP:
116 fieldEnum = e_contact_field_id("address_home");
117 break;
119 case WORK_ADDR_LINE1:
120 case WORK_ADDR_LINE2:
121 case WORK_CITY:
122 case WORK_STATE:
123 case WORK_COUNTRY:
124 case WORK_ZIP:
125 fieldEnum = e_contact_field_id("address_work");
126 break;
128 case OTHER_ADDR_LINE1:
129 case OTHER_ADDR_LINE2:
130 case OTHER_CITY:
131 case OTHER_STATE:
132 case OTHER_COUNTRY:
133 case OTHER_ZIP:
134 fieldEnum = e_contact_field_id("address_other");
135 break;
137 default: fieldEnum = e_contact_field_id("address_home");
139 return fieldEnum;
143 * This function decides the default column values based on the first field of EContactAddress.
144 * The search order is Work->Home->other(defaults).
146 static EContactAddress *
147 getDefaultContactAddress( EContact *pContact,int *value )
149 EContactAddress *ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(WORK_ADDR_LINE1)));
150 if ( ec && (ec->street[0]!='\0') )
152 *value= *value +WORK_ADDR_LINE1 -1;
153 return ec;
155 else
157 ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(HOME_ADDR_LINE1)));
158 if ( ec && (ec->street[0]!='\0') )
160 *value=*value+HOME_ADDR_LINE1-1;
161 return ec;
165 *value=*value+OTHER_ADDR_LINE1-1;
166 return static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(OTHER_ADDR_LINE1)));
169 static EContactAddress*
170 getContactAddress( EContact *pContact, int * address_enum )
172 EContactAddress *ec = nullptr;
173 switch (*address_enum) {
175 case DEFAULT_ADDR_LINE1:
176 case DEFAULT_ADDR_LINE2:
177 case DEFAULT_CITY:
178 case DEFAULT_STATE:
179 case DEFAULT_COUNTRY:
180 case DEFAULT_ZIP:
181 ec = getDefaultContactAddress(pContact,address_enum);break;
182 default:
183 ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(*address_enum)));
185 return ec;
188 static bool
189 handleSplitAddress( EContact *pContact,GValue *pStackValue, int value )
191 EContactAddress *ec = getContactAddress(pContact,&value) ;
193 if (ec==nullptr)
194 return true;
196 switch (value) {
197 case WORK_ADDR_LINE1:
198 g_value_set_string(pStackValue,ec->street ); break;
199 case WORK_ADDR_LINE2:
200 g_value_set_string(pStackValue,ec->po ); break;
201 case WORK_CITY:
202 g_value_set_string(pStackValue,ec->locality ); break;
203 case WORK_STATE:
204 g_value_set_string(pStackValue,ec->region ); break;
205 case WORK_COUNTRY:
206 g_value_set_string(pStackValue,ec->country ); break;
207 case WORK_ZIP:
208 g_value_set_string(pStackValue,ec->code ); break;
210 case HOME_ADDR_LINE1:
211 g_value_set_string(pStackValue,ec->street ); break;
212 case HOME_ADDR_LINE2:
213 g_value_set_string(pStackValue,ec->po ); break;
214 case HOME_CITY:
215 g_value_set_string(pStackValue,ec->locality ); break;
216 case HOME_STATE:
217 g_value_set_string(pStackValue,ec->region ); break;
218 case HOME_COUNTRY:
219 g_value_set_string(pStackValue,ec->country ); break;
220 case HOME_ZIP:
221 g_value_set_string(pStackValue,ec->code ); break;
223 case OTHER_ADDR_LINE1:
224 g_value_set_string(pStackValue,ec->street ); break;
225 case OTHER_ADDR_LINE2:
226 g_value_set_string(pStackValue,ec->po ); break;
227 case OTHER_CITY:
228 g_value_set_string(pStackValue,ec->locality ); break;
229 case OTHER_STATE:
230 g_value_set_string(pStackValue,ec->region ); break;
231 case OTHER_COUNTRY:
232 g_value_set_string(pStackValue,ec->country ); break;
233 case OTHER_ZIP:
234 g_value_set_string(pStackValue,ec->code ); break;
238 return false;
241 static bool
242 getValue( EContact* pContact, sal_Int32 nColumnNum, GType nType, GValue* pStackValue, bool& _out_rWasNull )
244 const ColumnProperty * pSpecs = evoab::getField( nColumnNum );
245 if ( !pSpecs )
246 return false;
248 GParamSpec* pSpec = pSpecs->pField;
249 bool bIsSplittedColumn = pSpecs->bIsSplittedValue;
251 _out_rWasNull = true;
252 if ( !pSpec || !pContact)
253 return false;
255 if ( G_PARAM_SPEC_VALUE_TYPE (pSpec) != nType )
257 SAL_WARN("connectivity.evoab2", "Wrong type (0x" << std::hex << static_cast<int>(G_PARAM_SPEC_VALUE_TYPE(pSpec)) << ") (0x"
258 << std::hex << static_cast<int>(nType) << ") " << (pSpec->name ? pSpec->name : "<noname>"));
259 return false;
262 g_value_init( pStackValue, nType );
263 if ( bIsSplittedColumn )
265 const SplitEvoColumns* evo_addr( get_evo_addr() );
266 for (int i=0;i<OTHER_ZIP;i++)
268 if (0 == strcmp (g_param_spec_get_name (pSpec), evo_addr[i].pColumnName))
270 _out_rWasNull = handleSplitAddress( pContact, pStackValue, evo_addr[i].value );
271 return true;
275 else
277 g_object_get_property( G_OBJECT (pContact),
278 g_param_spec_get_name (pSpec),
279 pStackValue );
280 if ( G_VALUE_TYPE( pStackValue ) != nType )
282 SAL_WARN("connectivity.evoab2", "Fetched type mismatch" );
283 g_value_unset( pStackValue );
284 return false;
287 _out_rWasNull = false;
288 return true;
291 extern "C" {
293 static int CompareContacts( gconstpointer _lhs, gconstpointer _rhs, gpointer _userData )
295 EContact* lhs = const_cast< gpointer >( _lhs );
296 EContact* rhs = const_cast< gpointer >( _rhs );
298 GValue aLhsValue = { 0, { { 0 } } };
299 GValue aRhsValue = { 0, { { 0 } } };
300 bool bLhsNull = true;
301 bool bRhsNull = true;
303 OUString sLhs, sRhs;
304 bool bLhs(false), bRhs(false);
306 const ComparisonData& rCompData = *static_cast< const ComparisonData* >( _userData );
307 for ( const auto& sortCol : rCompData.rSortOrder )
309 sal_Int32 nField = sortCol.nField;
310 int nOrder = 1;
311 // if descending sort, reverse order
312 if (!sortCol.bAscending)
313 nOrder = -1;
314 GType eFieldType = evoab::getGFieldType( nField );
316 bool success = getValue( lhs, nField, eFieldType, &aLhsValue, bLhsNull )
317 && getValue( rhs, nField, eFieldType, &aRhsValue, bRhsNull );
318 OSL_ENSURE( success, "CompareContacts: could not retrieve both values!" );
319 if ( !success )
320 return 0;
322 if ( bLhsNull && !bRhsNull )
323 return -1 * nOrder;
324 if ( !bLhsNull && bRhsNull )
325 return 1 * nOrder;
326 if ( bLhsNull && bRhsNull )
327 continue;
329 if ( eFieldType == G_TYPE_STRING )
331 sLhs = valueToOUString( aLhsValue );
332 sRhs = valueToOUString( aRhsValue );
333 sal_Int32 nCompResult = rCompData.aIntlWrapper.getCaseCollator()->compareString( sLhs, sRhs );
334 if ( nCompResult != 0 )
335 return nCompResult * nOrder;
336 continue;
339 bLhs = valueToBool( aLhsValue );
340 bRhs = valueToBool( aRhsValue );
341 if ( bLhs && !bRhs )
342 return -1 * nOrder;
343 if ( !bLhs && bRhs )
344 return 1 * nOrder;
345 continue;
348 return 0;
353 OString OEvoabVersionHelper::getUserName( EBook *pBook )
355 OString aName;
356 if( isLDAP( pBook ) )
357 aName = e_source_get_property( e_book_get_source( pBook ), "binddn" );
358 else
359 aName = e_source_get_property( e_book_get_source( pBook ), "user" );
360 return aName;
363 namespace {
365 bool isBookBackend( EBookClient *pBook, const char *backendname)
367 if (!pBook)
368 return false;
369 ESource *pSource = e_client_get_source (reinterpret_cast<EClient *>(pBook));
370 return isSourceBackend(pSource, backendname);
373 class OEvoabVersion36Helper : public OEvoabVersionHelper
375 private:
376 GSList *m_pContacts;
377 public:
378 OEvoabVersion36Helper()
379 : m_pContacts(nullptr)
383 virtual ~OEvoabVersion36Helper() override
385 freeContacts();
388 virtual EBook* openBook(const char *abname) override
390 //It would be better if here we had id to begin with, see
391 //NDatabaseMetaData.cxx
392 const char *id = nullptr;
393 GList *pSources = e_source_registry_list_sources(get_e_source_registry(), E_SOURCE_EXTENSION_ADDRESS_BOOK);
394 for (GList* liter = pSources; liter; liter = liter->next)
396 ESource *pSource = E_SOURCE (liter->data);
398 if (strcmp(abname, e_source_get_display_name( pSource )) == 0)
400 id = e_source_get_uid( pSource );
401 break;
404 g_list_foreach (pSources, object_unref, nullptr);
405 g_list_free (pSources);
406 if (!id)
407 return nullptr;
409 ESource *pSource = e_source_registry_ref_source(get_e_source_registry(), id);
410 EBookClient *pBook = pSource ? createClient (pSource) : nullptr;
411 if (pBook && !e_client_open_sync (pBook, true, nullptr, nullptr))
413 g_object_unref (G_OBJECT (pBook));
414 pBook = nullptr;
416 if (pSource)
417 g_object_unref (pSource);
418 return pBook;
421 virtual bool isLDAP( EBook *pBook ) override
423 return isBookBackend(pBook, "ldap");
426 virtual bool isLocal( EBook *pBook ) override
428 return isBookBackend(pBook, "local");
431 virtual void freeContacts() override final
433 e_client_util_free_object_slist(m_pContacts);
434 m_pContacts = nullptr;
437 virtual void executeQuery (EBook* pBook, EBookQuery* pQuery) override
439 freeContacts();
440 char *sexp = e_book_query_to_string( pQuery );
441 e_book_client_get_contacts_sync( pBook, sexp, &m_pContacts, nullptr, nullptr );
442 g_free (sexp);
445 virtual EContact *getContact(sal_Int32 nIndex) override
447 gpointer pData = g_slist_nth_data (m_pContacts, nIndex);
448 return pData ? E_CONTACT (pData) : nullptr;
451 virtual sal_Int32 getNumContacts() override
453 return g_slist_length( m_pContacts );
456 virtual bool hasContacts() override
458 return m_pContacts != nullptr;
461 virtual void sortContacts( const ComparisonData& _rCompData ) override
463 OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" );
464 ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" );
466 m_pContacts = g_slist_sort_with_data( m_pContacts, &CompareContacts,
467 const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) );
470 protected:
471 virtual EBookClient * createClient( ESource *pSource )
473 return e_book_client_new (pSource, nullptr);
477 class OEvoabVersion38Helper : public OEvoabVersion36Helper
479 protected:
480 virtual EBookClient * createClient( ESource *pSource ) override
482 return e_book_client_connect_direct_sync (get_e_source_registry (), pSource, 10, nullptr, nullptr);
488 OEvoabResultSet::OEvoabResultSet( OCommonStatement* pStmt, OEvoabConnection *pConnection )
489 :OResultSet_BASE(m_aMutex)
490 ,::comphelper::OPropertyContainer( OResultSet_BASE::rBHelper )
491 ,m_pStatement(pStmt)
492 ,m_pConnection(pConnection)
493 ,m_bWasNull(true)
494 ,m_nFetchSize(0)
495 ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE)
496 ,m_nFetchDirection(FetchDirection::FORWARD)
497 ,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY)
498 ,m_nIndex(-1)
499 ,m_nLength(0)
501 m_pVersionHelper = std::make_unique<OEvoabVersion38Helper>();
503 registerProperty(
504 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
505 PROPERTY_ID_FETCHSIZE,
506 PropertyAttribute::READONLY,
507 &m_nFetchSize,
508 cppu::UnoType<decltype(m_nFetchSize)>::get()
510 registerProperty(
511 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
512 PROPERTY_ID_RESULTSETTYPE,
513 PropertyAttribute::READONLY,
514 &m_nResultSetType,
515 cppu::UnoType<decltype(m_nResultSetType)>::get()
517 registerProperty(
518 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
519 PROPERTY_ID_FETCHDIRECTION,
520 PropertyAttribute::READONLY,
521 &m_nFetchDirection,
522 cppu::UnoType<decltype(m_nFetchDirection)>::get()
524 registerProperty(
525 OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
526 PROPERTY_ID_RESULTSETCONCURRENCY,
527 PropertyAttribute::READONLY,
528 &m_nResultSetConcurrency,
529 cppu::UnoType<decltype(m_nResultSetConcurrency)>::get()
533 OEvoabResultSet::~OEvoabResultSet()
536 void OEvoabResultSet::construct( const QueryData& _rData )
538 ENSURE_OR_THROW( _rData.getQuery(), "internal error: no EBookQuery" );
540 EBook *pBook = m_pVersionHelper->openBook(OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr());
541 if ( !pBook )
542 m_pConnection->throwGenericSQLException( STR_CANNOT_OPEN_BOOK, *this );
544 m_pVersionHelper->freeContacts();
545 bool bExecuteQuery = true;
546 switch ( _rData.eFilterType )
548 case eFilterNone:
549 if ( !m_pVersionHelper->isLocal( pBook ) )
551 SQLError aErrorFactory;
552 SQLException aAsException = aErrorFactory.getSQLException( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED, *this );
553 m_aWarnings.appendWarning( SQLWarning(
554 aAsException.Message,
555 aAsException.Context,
556 aAsException.SQLState,
557 aAsException.ErrorCode,
558 aAsException.NextException
559 ) );
560 bExecuteQuery = false;
562 break;
563 case eFilterAlwaysFalse:
564 bExecuteQuery = false;
565 break;
566 case eFilterOther:
567 bExecuteQuery = true;
568 break;
570 if ( bExecuteQuery )
572 m_pVersionHelper->executeQuery(pBook, _rData.getQuery());
574 if ( m_pVersionHelper->hasContacts() && !_rData.aSortOrder.empty() )
576 ComparisonData aCompData(_rData.aSortOrder);
577 m_pVersionHelper->sortContacts(aCompData);
580 m_nLength = m_pVersionHelper->getNumContacts();
581 SAL_INFO("connectivity.evoab2", "Query return " << m_nLength << " records");
582 m_nIndex = -1;
584 // create our meta data (need the EBookQuery for this)
585 m_xMetaData = new OEvoabResultSetMetaData( _rData.sTable );
587 m_xMetaData->setEvoabFields( _rData.xSelectColumns );
591 void OEvoabResultSet::disposing()
593 ::comphelper::OPropertyContainer::disposing();
595 ::osl::MutexGuard aGuard(m_aMutex);
596 m_pVersionHelper.reset();
597 m_pStatement = nullptr;
598 m_xMetaData.clear();
601 Any SAL_CALL OEvoabResultSet::queryInterface( const Type & rType )
603 Any aRet = ::comphelper::OPropertyContainer::queryInterface(rType);
604 if(!aRet.hasValue())
605 aRet = OResultSet_BASE::queryInterface(rType);
606 return aRet;
609 Sequence< Type > SAL_CALL OEvoabResultSet::getTypes( )
611 return ::comphelper::concatSequences(
612 OResultSet_BASE::getTypes(),
613 getBaseTypes()
618 // XRow Interface
621 * getString:
622 * @nColumnNum: The column index from the table.
624 * If the equivalent NResultSetMetaData.cxx marks the columntype of
625 * nColumnNum as DataType::VARCHAR this accessor is used.
627 OUString SAL_CALL OEvoabResultSet::getString( sal_Int32 nColumnNum )
629 ::osl::MutexGuard aGuard( m_aMutex );
630 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
631 OUString aResult;
632 if ( m_xMetaData.is())
634 sal_Int32 nFieldNumber = m_xMetaData->fieldAtColumn(nColumnNum);
635 GValue aValue = { 0, { { 0 } } };
636 if ( getValue( getCur(), nFieldNumber, G_TYPE_STRING, &aValue, m_bWasNull ) )
637 aResult = valueToOUString( aValue );
639 return aResult;
642 sal_Bool SAL_CALL OEvoabResultSet::getBoolean( sal_Int32 nColumnNum )
644 ::osl::MutexGuard aGuard( m_aMutex );
645 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
646 bool bResult = false;
648 if ( m_xMetaData.is())
650 sal_Int32 nFieldNumber = m_xMetaData->fieldAtColumn(nColumnNum);
651 GValue aValue = { 0, { { 0 } } };
652 if ( getValue( getCur(), nFieldNumber, G_TYPE_BOOLEAN, &aValue, m_bWasNull ) )
653 bResult = valueToBool( aValue );
655 return bResult;
658 sal_Int64 SAL_CALL OEvoabResultSet::getLong( sal_Int32 /*nColumnNum*/ )
660 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getLong"_ustr, *this );
661 return sal_Int64();
664 Reference< XArray > SAL_CALL OEvoabResultSet::getArray( sal_Int32 /*nColumnNum*/ )
666 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getArray"_ustr, *this );
667 return nullptr;
670 Reference< XClob > SAL_CALL OEvoabResultSet::getClob( sal_Int32 /*nColumnNum*/ )
672 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getClob"_ustr, *this );
673 return nullptr;
676 Reference< XBlob > SAL_CALL OEvoabResultSet::getBlob( sal_Int32 /*nColumnNum*/ )
678 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getBlob"_ustr, *this );
679 return nullptr;
682 Reference< XRef > SAL_CALL OEvoabResultSet::getRef( sal_Int32 /*nColumnNum*/ )
684 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getRef"_ustr, *this );
685 return nullptr;
688 Any SAL_CALL OEvoabResultSet::getObject( sal_Int32 /*nColumnNum*/, const Reference< css::container::XNameAccess >& /*typeMap*/ )
690 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getObject"_ustr, *this );
691 return Any();
694 sal_Int16 SAL_CALL OEvoabResultSet::getShort( sal_Int32 /*nColumnNum*/ )
696 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getShort"_ustr, *this );
697 return 0;
700 css::util::Time SAL_CALL OEvoabResultSet::getTime( sal_Int32 /*nColumnNum*/ )
702 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getTime"_ustr, *this );
703 return css::util::Time();
706 util::DateTime SAL_CALL OEvoabResultSet::getTimestamp( sal_Int32 /*nColumnNum*/ )
708 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getTimestamp"_ustr, *this );
709 return css::util::DateTime();
712 Reference< XInputStream > SAL_CALL OEvoabResultSet::getBinaryStream( sal_Int32 /*nColumnNum*/ )
714 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getBinaryStream"_ustr, *this );
715 return nullptr;
718 Reference< XInputStream > SAL_CALL OEvoabResultSet::getCharacterStream( sal_Int32 /*nColumnNum*/ )
720 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getCharacterStream"_ustr, *this );
721 return nullptr;
724 sal_Int8 SAL_CALL OEvoabResultSet::getByte( sal_Int32 /*nColumnNum*/ )
726 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getByte"_ustr, *this );
727 return 0;
730 Sequence< sal_Int8 > SAL_CALL OEvoabResultSet::getBytes( sal_Int32 /*nColumnNum*/ )
732 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getBytes"_ustr, *this );
733 return Sequence< sal_Int8 >();
736 css::util::Date SAL_CALL OEvoabResultSet::getDate( sal_Int32 /*nColumnNum*/ )
738 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getDate"_ustr, *this );
739 return css::util::Date();
742 double SAL_CALL OEvoabResultSet::getDouble( sal_Int32 /*nColumnNum*/ )
744 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getDouble"_ustr, *this );
745 return 0;
748 float SAL_CALL OEvoabResultSet::getFloat( sal_Int32 /*nColumnNum*/ )
750 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getFloat"_ustr, *this );
751 return 0;
754 sal_Int32 SAL_CALL OEvoabResultSet::getInt( sal_Int32 /*nColumnNum*/ )
756 ::dbtools::throwFunctionNotSupportedSQLException( u"XRow::getInt"_ustr, *this );
757 return 0;
759 // XRow Interface Ends
762 // XResultSetMetaDataSupplier Interface
763 Reference< XResultSetMetaData > SAL_CALL OEvoabResultSet::getMetaData( )
765 ::osl::MutexGuard aGuard( m_aMutex );
766 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
768 // the meta data should have been created at construction time
769 ENSURE_OR_THROW( m_xMetaData.is(), "internal error: no meta data" );
770 return m_xMetaData;
772 // XResultSetMetaDataSupplier Interface Ends
775 // XResultSet Interface
776 sal_Bool SAL_CALL OEvoabResultSet::next( )
778 ::osl::MutexGuard aGuard( m_aMutex );
779 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
780 if (m_nIndex+1 < m_nLength) {
781 ++m_nIndex ;
782 return true;
784 else
785 return false;
788 sal_Bool SAL_CALL OEvoabResultSet::wasNull( )
790 ::osl::MutexGuard aGuard( m_aMutex );
791 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
793 return m_bWasNull;
796 sal_Bool SAL_CALL OEvoabResultSet::isBeforeFirst( )
798 ::osl::MutexGuard aGuard( m_aMutex );
799 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
801 return m_nIndex < 0;
804 sal_Int32 SAL_CALL OEvoabResultSet::getRow( )
806 ::osl::MutexGuard aGuard( m_aMutex );
807 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
809 return m_nIndex;
812 sal_Bool SAL_CALL OEvoabResultSet::isAfterLast( )
814 ::osl::MutexGuard aGuard( m_aMutex );
815 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
817 return m_nIndex >= m_nLength;
820 sal_Bool SAL_CALL OEvoabResultSet::isFirst( )
822 ::osl::MutexGuard aGuard( m_aMutex );
823 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
825 return m_nIndex == 0;
828 sal_Bool SAL_CALL OEvoabResultSet::isLast( )
830 ::osl::MutexGuard aGuard( m_aMutex );
831 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
833 return m_nIndex == m_nLength - 1;
836 void SAL_CALL OEvoabResultSet::beforeFirst( )
838 ::osl::MutexGuard aGuard( m_aMutex );
839 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
841 m_nIndex = -1;
844 void SAL_CALL OEvoabResultSet::afterLast( )
846 ::osl::MutexGuard aGuard( m_aMutex );
847 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
849 m_nIndex = m_nLength;
853 sal_Bool SAL_CALL OEvoabResultSet::first( )
855 ::osl::MutexGuard aGuard( m_aMutex );
856 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
858 m_nIndex = 0;
859 return true;
863 sal_Bool SAL_CALL OEvoabResultSet::last( )
865 ::osl::MutexGuard aGuard( m_aMutex );
866 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
868 m_nIndex = m_nLength - 1;
869 return true;
872 sal_Bool SAL_CALL OEvoabResultSet::absolute( sal_Int32 row )
874 ::osl::MutexGuard aGuard( m_aMutex );
875 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
876 if (row < m_nLength) {
877 m_nIndex = row;
878 return true;
880 else
881 return false;
884 sal_Bool SAL_CALL OEvoabResultSet::relative( sal_Int32 row )
886 ::osl::MutexGuard aGuard( m_aMutex );
887 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
889 if ((m_nIndex+row) < m_nLength) {
890 m_nIndex += row;
891 return true;
893 else
894 return false;
897 sal_Bool SAL_CALL OEvoabResultSet::previous( )
899 ::osl::MutexGuard aGuard( m_aMutex );
900 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
902 if(m_nIndex > 0) {
903 m_nIndex--;
904 return true;
906 else
907 return false;
910 Reference< XInterface > SAL_CALL OEvoabResultSet::getStatement( )
912 ::osl::MutexGuard aGuard( m_aMutex );
913 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
914 return cppu::getXWeak(m_pStatement);
918 sal_Bool SAL_CALL OEvoabResultSet::rowDeleted( )
920 ::osl::MutexGuard aGuard( m_aMutex );
921 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
923 return false;
926 sal_Bool SAL_CALL OEvoabResultSet::rowInserted( )
928 ::osl::MutexGuard aGuard( m_aMutex );
929 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
931 return false;
934 sal_Bool SAL_CALL OEvoabResultSet::rowUpdated( )
936 ::osl::MutexGuard aGuard( m_aMutex );
937 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
939 return false;
942 void SAL_CALL OEvoabResultSet::refreshRow( )
944 ::osl::MutexGuard aGuard( m_aMutex );
945 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
947 //XResult Interface ends
949 // XCancellable
951 void SAL_CALL OEvoabResultSet::cancel( )
953 ::osl::MutexGuard aGuard( m_aMutex );
954 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
957 //XCloseable
958 void SAL_CALL OEvoabResultSet::close( )
961 ::osl::MutexGuard aGuard( m_aMutex );
962 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
964 dispose();
967 // XWarningsSupplier
969 void SAL_CALL OEvoabResultSet::clearWarnings( )
971 m_aWarnings.clearWarnings();
974 Any SAL_CALL OEvoabResultSet::getWarnings( )
976 return m_aWarnings.getWarnings();
979 //XColumnLocate Interface
980 sal_Int32 SAL_CALL OEvoabResultSet::findColumn( const OUString& columnName )
982 ::osl::MutexGuard aGuard( m_aMutex );
983 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
985 // find the first column with the name columnName
986 Reference< XResultSetMetaData > xMeta = getMetaData();
987 sal_Int32 nLen = xMeta->getColumnCount();
988 sal_Int32 i = 1;
989 for(;i<=nLen;++i)
991 if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
992 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
993 return i;
996 ::dbtools::throwInvalidColumnException( columnName, *this );
997 assert(false);
998 return 0; // Never reached
1001 //XColumnLocate interface ends
1004 ::cppu::IPropertyArrayHelper* OEvoabResultSet::createArrayHelper( ) const
1006 Sequence< Property > aProps;
1007 describeProperties( aProps );
1008 return new ::cppu::OPropertyArrayHelper( aProps );
1011 ::cppu::IPropertyArrayHelper & OEvoabResultSet::getInfoHelper()
1013 return *getArrayHelper();
1016 void SAL_CALL OEvoabResultSet::acquire() noexcept
1018 OResultSet_BASE::acquire();
1021 void SAL_CALL OEvoabResultSet::release() noexcept
1023 OResultSet_BASE::release();
1026 css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL
1027 OEvoabResultSet::getPropertySetInfo( )
1029 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1033 } // connectivity::evoab
1035 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */