diff options
Diffstat (limited to 'connectivity/source/drivers/evoab2/NResultSet.cxx')
-rw-r--r-- | connectivity/source/drivers/evoab2/NResultSet.cxx | 1142 |
1 files changed, 1142 insertions, 0 deletions
diff --git a/connectivity/source/drivers/evoab2/NResultSet.cxx b/connectivity/source/drivers/evoab2/NResultSet.cxx new file mode 100644 index 000000000..77d53939c --- /dev/null +++ b/connectivity/source/drivers/evoab2/NResultSet.cxx @@ -0,0 +1,1142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include "NDatabaseMetaData.hxx" +#include "NConnection.hxx" +#include "NResultSet.hxx" +#include <propertyids.hxx> +#include <strings.hrc> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/sdb/ErrorCondition.hpp> +#include <com/sun/star/sdbc/FetchDirection.hpp> +#include <com/sun/star/sdbc/ResultSetConcurrency.hpp> +#include <com/sun/star/sdbc/ResultSetType.hpp> + +#include <comphelper/sequence.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <connectivity/dbexception.hxx> +#include <connectivity/sqlerror.hxx> +#include <rtl/string.hxx> +#include <sal/log.hxx> +#include <tools/diagnose_ex.h> +#include <unotools/syslocale.hxx> +#include <unotools/intlwrapper.hxx> +#include <unotools/collatorwrapper.hxx> + +#include <cstring> + +namespace connectivity::evoab { + +using namespace ::comphelper; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::sdbcx; +using namespace com::sun::star::container; +using namespace com::sun::star::io; +namespace ErrorCondition = ::com::sun::star::sdb::ErrorCondition; + + +OUString SAL_CALL OEvoabResultSet::getImplementationName( ) +{ + return "com.sun.star.sdbcx.evoab.ResultSet"; +} + + Sequence< OUString > SAL_CALL OEvoabResultSet::getSupportedServiceNames( ) +{ + Sequence< OUString > aSupported { "com.sun.star.sdbc.ResultSet" }; + return aSupported; +} + +sal_Bool SAL_CALL OEvoabResultSet::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +struct ComparisonData +{ + const SortDescriptor& rSortOrder; + IntlWrapper aIntlWrapper; + + ComparisonData(const SortDescriptor& _rSortOrder) + : rSortOrder(_rSortOrder) + , aIntlWrapper(SvtSysLocale().GetUILanguageTag()) + { + } +}; + +static OUString +valueToOUString( GValue& _rValue ) +{ + const char *pStr = g_value_get_string( &_rValue ); + OString aStr( pStr ? pStr : "" ); + OUString sResult( OStringToOUString( aStr, RTL_TEXTENCODING_UTF8 ) ); + g_value_unset( &_rValue ); + return sResult; +} + +static bool +valueToBool( GValue& _rValue ) +{ + bool bResult = g_value_get_boolean( &_rValue ); + g_value_unset( &_rValue ); + return bResult; +} + +static int +whichAddress(int value) +{ + int fieldEnum; + switch (value) + { + case HOME_ADDR_LINE1: + case HOME_ADDR_LINE2: + case HOME_CITY: + case HOME_STATE: + case HOME_COUNTRY: + case HOME_ZIP: + fieldEnum = e_contact_field_id("address_home"); + break; + + case WORK_ADDR_LINE1: + case WORK_ADDR_LINE2: + case WORK_CITY: + case WORK_STATE: + case WORK_COUNTRY: + case WORK_ZIP: + fieldEnum = e_contact_field_id("address_work"); + break; + + case OTHER_ADDR_LINE1: + case OTHER_ADDR_LINE2: + case OTHER_CITY: + case OTHER_STATE: + case OTHER_COUNTRY: + case OTHER_ZIP: + fieldEnum = e_contact_field_id("address_other"); + break; + + default: fieldEnum = e_contact_field_id("address_home"); + } + return fieldEnum; +} + +/* +* This function decides the default column values based on the first field of EContactAddress. +* The search order is Work->Home->other(defaults). +*/ +static EContactAddress * +getDefaultContactAddress( EContact *pContact,int *value ) +{ + EContactAddress *ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(WORK_ADDR_LINE1))); + if ( ec && (ec->street[0]!='\0') ) + { + *value= *value +WORK_ADDR_LINE1 -1; + return ec; + } + else + { + ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(HOME_ADDR_LINE1))); + if ( ec && (ec->street[0]!='\0') ) + { + *value=*value+HOME_ADDR_LINE1-1; + return ec; + } + } + + *value=*value+OTHER_ADDR_LINE1-1; + return static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(OTHER_ADDR_LINE1))); +} + +static EContactAddress* +getContactAddress( EContact *pContact, int * address_enum ) +{ + EContactAddress *ec = nullptr; + switch (*address_enum) { + + case DEFAULT_ADDR_LINE1: + case DEFAULT_ADDR_LINE2: + case DEFAULT_CITY: + case DEFAULT_STATE: + case DEFAULT_COUNTRY: + case DEFAULT_ZIP: + ec = getDefaultContactAddress(pContact,address_enum);break; + default: + ec = static_cast<EContactAddress *>(e_contact_get(pContact,whichAddress(*address_enum))); + } + return ec; +} + +static bool +handleSplitAddress( EContact *pContact,GValue *pStackValue, int value ) +{ + EContactAddress *ec = getContactAddress(pContact,&value) ; + + if (ec==nullptr) + return true; + + switch (value) { + case WORK_ADDR_LINE1: + g_value_set_string(pStackValue,ec->street ); break; + case WORK_ADDR_LINE2: + g_value_set_string(pStackValue,ec->po ); break; + case WORK_CITY: + g_value_set_string(pStackValue,ec->locality ); break; + case WORK_STATE: + g_value_set_string(pStackValue,ec->region ); break; + case WORK_COUNTRY: + g_value_set_string(pStackValue,ec->country ); break; + case WORK_ZIP: + g_value_set_string(pStackValue,ec->code ); break; + + case HOME_ADDR_LINE1: + g_value_set_string(pStackValue,ec->street ); break; + case HOME_ADDR_LINE2: + g_value_set_string(pStackValue,ec->po ); break; + case HOME_CITY: + g_value_set_string(pStackValue,ec->locality ); break; + case HOME_STATE: + g_value_set_string(pStackValue,ec->region ); break; + case HOME_COUNTRY: + g_value_set_string(pStackValue,ec->country ); break; + case HOME_ZIP: + g_value_set_string(pStackValue,ec->code ); break; + + case OTHER_ADDR_LINE1: + g_value_set_string(pStackValue,ec->street ); break; + case OTHER_ADDR_LINE2: + g_value_set_string(pStackValue,ec->po ); break; + case OTHER_CITY: + g_value_set_string(pStackValue,ec->locality ); break; + case OTHER_STATE: + g_value_set_string(pStackValue,ec->region ); break; + case OTHER_COUNTRY: + g_value_set_string(pStackValue,ec->country ); break; + case OTHER_ZIP: + g_value_set_string(pStackValue,ec->code ); break; + + } + + return false; +} + +static bool +getValue( EContact* pContact, sal_Int32 nColumnNum, GType nType, GValue* pStackValue, bool& _out_rWasNull ) +{ + const ColumnProperty * pSpecs = evoab::getField( nColumnNum ); + if ( !pSpecs ) + return false; + + GParamSpec* pSpec = pSpecs->pField; + bool bIsSplittedColumn = pSpecs->bIsSplittedValue; + + _out_rWasNull = true; + if ( !pSpec || !pContact) + return false; + + if ( G_PARAM_SPEC_VALUE_TYPE (pSpec) != nType ) + { + SAL_WARN("connectivity.evoab2", "Wrong type (0x" << std::hex << static_cast<int>(G_PARAM_SPEC_VALUE_TYPE(pSpec)) << ") (0x" + << std::hex << static_cast<int>(nType) << ") " << (pSpec->name ? pSpec->name : "<noname>")); + return false; + } + + g_value_init( pStackValue, nType ); + if ( bIsSplittedColumn ) + { + const SplitEvoColumns* evo_addr( get_evo_addr() ); + for (int i=0;i<OTHER_ZIP;i++) + { + if (0 == strcmp (g_param_spec_get_name (pSpec), evo_addr[i].pColumnName)) + { + _out_rWasNull = handleSplitAddress( pContact, pStackValue, evo_addr[i].value ); + return true; + } + } + } + else + { + g_object_get_property( G_OBJECT (pContact), + g_param_spec_get_name (pSpec), + pStackValue ); + if ( G_VALUE_TYPE( pStackValue ) != nType ) + { + SAL_WARN("connectivity.evoab2", "Fetched type mismatch" ); + g_value_unset( pStackValue ); + return false; + } + } + _out_rWasNull = false; + return true; +} + +extern "C" { + +static int CompareContacts( gconstpointer _lhs, gconstpointer _rhs, gpointer _userData ) +{ + EContact* lhs = const_cast< gpointer >( _lhs ); + EContact* rhs = const_cast< gpointer >( _rhs ); + + GValue aLhsValue = { 0, { { 0 } } }; + GValue aRhsValue = { 0, { { 0 } } }; + bool bLhsNull = true; + bool bRhsNull = true; + + OUString sLhs, sRhs; + bool bLhs(false), bRhs(false); + + const ComparisonData& rCompData = *static_cast< const ComparisonData* >( _userData ); + for ( const auto& sortCol : rCompData.rSortOrder ) + { + sal_Int32 nField = sortCol.nField; + GType eFieldType = evoab::getGFieldType( nField ); + + bool success = getValue( lhs, nField, eFieldType, &aLhsValue, bLhsNull ) + && getValue( rhs, nField, eFieldType, &aRhsValue, bRhsNull ); + OSL_ENSURE( success, "CompareContacts: could not retrieve both values!" ); + if ( !success ) + return 0; + + if ( bLhsNull && !bRhsNull ) + return -1; + if ( !bLhsNull && bRhsNull ) + return 1; + if ( bLhsNull && bRhsNull ) + continue; + + if ( eFieldType == G_TYPE_STRING ) + { + sLhs = valueToOUString( aLhsValue ); + sRhs = valueToOUString( aRhsValue ); + sal_Int32 nCompResult = rCompData.aIntlWrapper.getCaseCollator()->compareString( sLhs, sRhs ); + if ( nCompResult != 0 ) + return nCompResult; + continue; + } + + bLhs = valueToBool( aLhsValue ); + bRhs = valueToBool( aRhsValue ); + if ( bLhs && !bRhs ) + return -1; + if ( !bLhs && bRhs ) + return 1; + continue; + } + + return 0; +} + +} + +OString OEvoabVersionHelper::getUserName( EBook *pBook ) +{ + OString aName; + if( isLDAP( pBook ) ) + aName = e_source_get_property( e_book_get_source( pBook ), "binddn" ); + else + aName = e_source_get_property( e_book_get_source( pBook ), "user" ); + return aName; +} + +namespace { + +bool isBookBackend( EBookClient *pBook, const char *backendname) +{ + if (!pBook) + return false; + ESource *pSource = e_client_get_source (reinterpret_cast<EClient *>(pBook)); + return isSourceBackend(pSource, backendname); +} + +class OEvoabVersion36Helper : public OEvoabVersionHelper +{ +private: + GSList *m_pContacts; +public: + OEvoabVersion36Helper() + : m_pContacts(nullptr) + { + } + + virtual ~OEvoabVersion36Helper() override + { + freeContacts(); + } + + virtual EBook* openBook(const char *abname) override + { + //It would be better if here we had id to begin with, see + //NDatabaseMetaData.cxx + const char *id = nullptr; + GList *pSources = e_source_registry_list_sources(get_e_source_registry(), E_SOURCE_EXTENSION_ADDRESS_BOOK); + for (GList* liter = pSources; liter; liter = liter->next) + { + ESource *pSource = E_SOURCE (liter->data); + + if (strcmp(abname, e_source_get_display_name( pSource )) == 0) + { + id = e_source_get_uid( pSource ); + break; + } + } + g_list_foreach (pSources, reinterpret_cast<GFunc>(g_object_unref), nullptr); + g_list_free (pSources); + if (!id) + return nullptr; + + ESource *pSource = e_source_registry_ref_source(get_e_source_registry(), id); + EBookClient *pBook = pSource ? createClient (pSource) : nullptr; + if (pBook && !e_client_open_sync (pBook, true, nullptr, nullptr)) + { + g_object_unref (G_OBJECT (pBook)); + pBook = nullptr; + } + if (pSource) + g_object_unref (pSource); + return pBook; + } + + virtual bool isLDAP( EBook *pBook ) override + { + return isBookBackend(pBook, "ldap"); + } + + virtual bool isLocal( EBook *pBook ) override + { + return isBookBackend(pBook, "local"); + } + + virtual void freeContacts() override final + { + e_client_util_free_object_slist(m_pContacts); + m_pContacts = nullptr; + } + + virtual void executeQuery (EBook* pBook, EBookQuery* pQuery, OString &/*rPassword*/) override + { + freeContacts(); + char *sexp = e_book_query_to_string( pQuery ); + e_book_client_get_contacts_sync( pBook, sexp, &m_pContacts, nullptr, nullptr ); + g_free (sexp); + } + + virtual EContact *getContact(sal_Int32 nIndex) override + { + gpointer pData = g_slist_nth_data (m_pContacts, nIndex); + return pData ? E_CONTACT (pData) : nullptr; + } + + virtual sal_Int32 getNumContacts() override + { + return g_slist_length( m_pContacts ); + } + + virtual bool hasContacts() override + { + return m_pContacts != nullptr; + } + + virtual void sortContacts( const ComparisonData& _rCompData ) override + { + OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" ); + ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" ); + + m_pContacts = g_slist_sort_with_data( m_pContacts, &CompareContacts, + const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) ); + } + +protected: + virtual EBookClient * createClient( ESource *pSource ) + { + return e_book_client_new (pSource, nullptr); + } +}; + +class OEvoabVersion38Helper : public OEvoabVersion36Helper +{ +protected: + virtual EBookClient * createClient( ESource *pSource ) override + { + return e_book_client_connect_direct_sync (get_e_source_registry (), pSource, nullptr, nullptr); + } +}; + +ESource * findSource( const char *id ) +{ + ESourceList *pSourceList = nullptr; + + g_return_val_if_fail (id != nullptr, nullptr); + + if (!e_book_get_addressbooks (&pSourceList, nullptr)) + pSourceList = nullptr; + + for ( GSList *g = e_source_list_peek_groups (pSourceList); g; g = g->next) + { + for (GSList *s = e_source_group_peek_sources (E_SOURCE_GROUP (g->data)); s; s = s->next) + { + ESource *pSource = E_SOURCE (s->data); + if (!strcmp (e_source_peek_name (pSource), id)) + return pSource; + } + } + return nullptr; +} + +bool isAuthRequired( EBook *pBook ) +{ + return e_source_get_property( e_book_get_source( pBook ), + "auth" ) != nullptr; +} + +class OEvoabVersion35Helper : public OEvoabVersionHelper +{ +private: + GList *m_pContacts; + +public: + OEvoabVersion35Helper() + : m_pContacts(nullptr) + { + } + + virtual ~OEvoabVersion35Helper() override + { + freeContacts(); + } + + virtual EBook* openBook(const char *abname) override + { + ESource *pSource = findSource (abname); + EBook *pBook = pSource ? e_book_new (pSource, nullptr) : nullptr; + if (pBook && !e_book_open (pBook, true, nullptr)) + { + g_object_unref (G_OBJECT (pBook)); + pBook = nullptr; + } + return pBook; + } + + virtual bool isLDAP( EBook *pBook ) override + { + return pBook && !strncmp( "ldap://", e_book_get_uri( pBook ), 6 ); + } + + virtual bool isLocal( EBook *pBook ) override + { + return pBook && ( !strncmp( "file://", e_book_get_uri( pBook ), 6 ) || + !strncmp( "local:", e_book_get_uri( pBook ), 6 ) ); + } + + virtual void freeContacts() override final + { + g_list_free(m_pContacts); + m_pContacts = nullptr; + } + + virtual void executeQuery (EBook* pBook, EBookQuery* pQuery, OString &rPassword) override + { + freeContacts(); + + ESource *pSource = e_book_get_source( pBook ); + bool bAuthSuccess = true; + + if( isAuthRequired( pBook ) ) + { + OString aUser( getUserName( pBook ) ); + const char *pAuth = e_source_get_property( pSource, "auth" ); + bAuthSuccess = e_book_authenticate_user( pBook, aUser.getStr(), rPassword.getStr(), pAuth, nullptr ); + } + + if (bAuthSuccess) + e_book_get_contacts( pBook, pQuery, &m_pContacts, nullptr ); + } + + virtual EContact *getContact(sal_Int32 nIndex) override + { + gpointer pData = g_list_nth_data (m_pContacts, nIndex); + return pData ? E_CONTACT (pData) : nullptr; + } + + virtual sal_Int32 getNumContacts() override + { + return g_list_length( m_pContacts ); + } + + virtual bool hasContacts() override + { + return m_pContacts != nullptr; + } + + virtual void sortContacts( const ComparisonData& _rCompData ) override + { + OSL_ENSURE( !_rCompData.rSortOrder.empty(), "sortContacts: no need to call this without any sort order!" ); + ENSURE_OR_THROW( _rCompData.aIntlWrapper.getCaseCollator(), "no collator for comparing strings" ); + + m_pContacts = g_list_sort_with_data( m_pContacts, &CompareContacts, + const_cast< gpointer >( static_cast< gconstpointer >( &_rCompData ) ) ); + } +}; + +} + +OEvoabResultSet::OEvoabResultSet( OCommonStatement* pStmt, OEvoabConnection *pConnection ) + :OResultSet_BASE(m_aMutex) + ,::comphelper::OPropertyContainer( OResultSet_BASE::rBHelper ) + ,m_pStatement(pStmt) + ,m_pConnection(pConnection) + ,m_bWasNull(true) + ,m_nFetchSize(0) + ,m_nResultSetType(ResultSetType::SCROLL_INSENSITIVE) + ,m_nFetchDirection(FetchDirection::FORWARD) + ,m_nResultSetConcurrency(ResultSetConcurrency::READ_ONLY) + ,m_nIndex(-1) + ,m_nLength(0) +{ + if (eds_check_version( 3, 7, 6 ) == nullptr) + m_pVersionHelper = std::make_unique<OEvoabVersion38Helper>(); + else if (eds_check_version( 3, 6, 0 ) == nullptr) + m_pVersionHelper = std::make_unique<OEvoabVersion36Helper>(); + else + m_pVersionHelper = std::make_unique<OEvoabVersion35Helper>(); + + #define REGISTER_PROP( id, member ) \ + registerProperty( \ + OMetaConnection::getPropMap().getNameByIndex( id ), \ + id, \ + PropertyAttribute::READONLY, \ + &member, \ + cppu::UnoType<decltype(member)>::get() \ + ); + + REGISTER_PROP( PROPERTY_ID_FETCHSIZE, m_nFetchSize ); + REGISTER_PROP( PROPERTY_ID_RESULTSETTYPE, m_nResultSetType ); + REGISTER_PROP( PROPERTY_ID_FETCHDIRECTION, m_nFetchDirection ); + REGISTER_PROP( PROPERTY_ID_RESULTSETCONCURRENCY, m_nResultSetConcurrency ); +} + +OEvoabResultSet::~OEvoabResultSet() +{} + +void OEvoabResultSet::construct( const QueryData& _rData ) +{ + ENSURE_OR_THROW( _rData.getQuery(), "internal error: no EBookQuery" ); + + EBook *pBook = m_pVersionHelper->openBook(OUStringToOString(_rData.sTable, RTL_TEXTENCODING_UTF8).getStr()); + if ( !pBook ) + m_pConnection->throwGenericSQLException( STR_CANNOT_OPEN_BOOK, *this ); + + m_pVersionHelper->freeContacts(); + bool bExecuteQuery = true; + switch ( _rData.eFilterType ) + { + case eFilterNone: + if ( !m_pVersionHelper->isLocal( pBook ) ) + { + SQLError aErrorFactory; + SQLException aAsException = aErrorFactory.getSQLException( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED, *this ); + m_aWarnings.appendWarning( SQLWarning( + aAsException.Message, + aAsException.Context, + aAsException.SQLState, + aAsException.ErrorCode, + aAsException.NextException + ) ); + bExecuteQuery = false; + } + break; + case eFilterAlwaysFalse: + bExecuteQuery = false; + break; + case eFilterOther: + bExecuteQuery = true; + break; + } + if ( bExecuteQuery ) + { + OString aPassword = m_pConnection->getPassword(); + m_pVersionHelper->executeQuery(pBook, _rData.getQuery(), aPassword); + m_pConnection->setPassword( aPassword ); + + if ( m_pVersionHelper->hasContacts() && !_rData.aSortOrder.empty() ) + { + ComparisonData aCompData(_rData.aSortOrder); + m_pVersionHelper->sortContacts(aCompData); + } + } + m_nLength = m_pVersionHelper->getNumContacts(); + SAL_INFO("connectivity.evoab2", "Query return " << m_nLength << " records"); + m_nIndex = -1; + + // create our meta data (need the EBookQuery for this) + m_xMetaData = new OEvoabResultSetMetaData( _rData.sTable ); + + m_xMetaData->setEvoabFields( _rData.xSelectColumns ); +} + + +void OEvoabResultSet::disposing() +{ + ::comphelper::OPropertyContainer::disposing(); + + ::osl::MutexGuard aGuard(m_aMutex); + m_pVersionHelper.reset(); + m_pStatement = nullptr; + m_xMetaData.clear(); +} + +Any SAL_CALL OEvoabResultSet::queryInterface( const Type & rType ) +{ + Any aRet = ::comphelper::OPropertyContainer::queryInterface(rType); + if(!aRet.hasValue()) + aRet = OResultSet_BASE::queryInterface(rType); + return aRet; +} + +Sequence< Type > SAL_CALL OEvoabResultSet::getTypes( ) +{ + return ::comphelper::concatSequences( + OResultSet_BASE::getTypes(), + getBaseTypes() + ); +} + + +// XRow Interface + +/** + * getString: + * @nColumnNum: The column index from the table. + * + * If the equivalent NResultSetMetaData.cxx marks the columntype of + * nColumnNum as DataType::VARCHAR this accessor is used. + */ +OUString SAL_CALL OEvoabResultSet::getString( sal_Int32 nColumnNum ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + OUString aResult; + if ( m_xMetaData.is()) + { + sal_Int32 nFieldNumber = m_xMetaData->fieldAtColumn(nColumnNum); + GValue aValue = { 0, { { 0 } } }; + if ( getValue( getCur(), nFieldNumber, G_TYPE_STRING, &aValue, m_bWasNull ) ) + aResult = valueToOUString( aValue ); + } + return aResult; +} + +sal_Bool SAL_CALL OEvoabResultSet::getBoolean( sal_Int32 nColumnNum ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + bool bResult = false; + + if ( m_xMetaData.is()) + { + sal_Int32 nFieldNumber = m_xMetaData->fieldAtColumn(nColumnNum); + GValue aValue = { 0, { { 0 } } }; + if ( getValue( getCur(), nFieldNumber, G_TYPE_BOOLEAN, &aValue, m_bWasNull ) ) + bResult = valueToBool( aValue ); + } + return bResult; +} + +sal_Int64 SAL_CALL OEvoabResultSet::getLong( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getLong", *this ); + return sal_Int64(); +} + +Reference< XArray > SAL_CALL OEvoabResultSet::getArray( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getArray", *this ); + return nullptr; +} + +Reference< XClob > SAL_CALL OEvoabResultSet::getClob( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getClob", *this ); + return nullptr; +} + +Reference< XBlob > SAL_CALL OEvoabResultSet::getBlob( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBlob", *this ); + return nullptr; +} + +Reference< XRef > SAL_CALL OEvoabResultSet::getRef( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getRef", *this ); + return nullptr; +} + +Any SAL_CALL OEvoabResultSet::getObject( sal_Int32 /*nColumnNum*/, const Reference< css::container::XNameAccess >& /*typeMap*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getObject", *this ); + return Any(); +} + +sal_Int16 SAL_CALL OEvoabResultSet::getShort( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getShort", *this ); + return 0; +} + +css::util::Time SAL_CALL OEvoabResultSet::getTime( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getTime", *this ); + return css::util::Time(); +} + +util::DateTime SAL_CALL OEvoabResultSet::getTimestamp( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getTimestamp", *this ); + return css::util::DateTime(); +} + +Reference< XInputStream > SAL_CALL OEvoabResultSet::getBinaryStream( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBinaryStream", *this ); + return nullptr; +} + +Reference< XInputStream > SAL_CALL OEvoabResultSet::getCharacterStream( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getCharacterStream", *this ); + return nullptr; +} + +sal_Int8 SAL_CALL OEvoabResultSet::getByte( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getByte", *this ); + return 0; +} + +Sequence< sal_Int8 > SAL_CALL OEvoabResultSet::getBytes( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBytes", *this ); + return Sequence< sal_Int8 >(); +} + +css::util::Date SAL_CALL OEvoabResultSet::getDate( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getDate", *this ); + return css::util::Date(); +} + +double SAL_CALL OEvoabResultSet::getDouble( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getDouble", *this ); + return 0; +} + +float SAL_CALL OEvoabResultSet::getFloat( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getFloat", *this ); + return 0; +} + +sal_Int32 SAL_CALL OEvoabResultSet::getInt( sal_Int32 /*nColumnNum*/ ) +{ + ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getInt", *this ); + return 0; +} +// XRow Interface Ends + + +// XResultSetMetaDataSupplier Interface +Reference< XResultSetMetaData > SAL_CALL OEvoabResultSet::getMetaData( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + // the meta data should have been created at construction time + ENSURE_OR_THROW( m_xMetaData.is(), "internal error: no meta data" ); + return m_xMetaData.get(); +} +// XResultSetMetaDataSupplier Interface Ends + + +// XResultSet Interface +sal_Bool SAL_CALL OEvoabResultSet::next( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + if (m_nIndex+1 < m_nLength) { + ++m_nIndex ; + return true; + } + else + return false; +} + +sal_Bool SAL_CALL OEvoabResultSet::wasNull( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return m_bWasNull; +} + +sal_Bool SAL_CALL OEvoabResultSet::isBeforeFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return m_nIndex < 0; +} + +sal_Int32 SAL_CALL OEvoabResultSet::getRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return m_nIndex; +} + +sal_Bool SAL_CALL OEvoabResultSet::isAfterLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return m_nIndex >= m_nLength; +} + +sal_Bool SAL_CALL OEvoabResultSet::isFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return m_nIndex == 0; +} + +sal_Bool SAL_CALL OEvoabResultSet::isLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return m_nIndex == m_nLength - 1; +} + +void SAL_CALL OEvoabResultSet::beforeFirst( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + m_nIndex = -1; +} + +void SAL_CALL OEvoabResultSet::afterLast( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + m_nIndex = m_nLength; +} + + +sal_Bool SAL_CALL OEvoabResultSet::first( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + m_nIndex = 0; + return true; +} + + +sal_Bool SAL_CALL OEvoabResultSet::last( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + m_nIndex = m_nLength - 1; + return true; +} + +sal_Bool SAL_CALL OEvoabResultSet::absolute( sal_Int32 row ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + if (row < m_nLength) { + m_nIndex = row; + return true; + } + else + return false; +} + +sal_Bool SAL_CALL OEvoabResultSet::relative( sal_Int32 row ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + if ((m_nIndex+row) < m_nLength) { + m_nIndex += row; + return true; + } + else + return false; +} + +sal_Bool SAL_CALL OEvoabResultSet::previous( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + if(m_nIndex > 0) { + m_nIndex--; + return true; + } + else + return false; +} + +Reference< XInterface > SAL_CALL OEvoabResultSet::getStatement( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + css::uno::WeakReferenceHelper aStatement(static_cast<OWeakObject*>(m_pStatement)); + return aStatement.get(); +} + + +sal_Bool SAL_CALL OEvoabResultSet::rowDeleted( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return false; +} + +sal_Bool SAL_CALL OEvoabResultSet::rowInserted( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return false; +} + +sal_Bool SAL_CALL OEvoabResultSet::rowUpdated( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + return false; +} + +void SAL_CALL OEvoabResultSet::refreshRow( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); +} +//XResult Interface ends + +// XCancellable + +void SAL_CALL OEvoabResultSet::cancel( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); +} + +//XCloseable +void SAL_CALL OEvoabResultSet::close( ) +{ + { + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + } + dispose(); +} + +// XWarningsSupplier + +void SAL_CALL OEvoabResultSet::clearWarnings( ) +{ + m_aWarnings.clearWarnings(); +} + +Any SAL_CALL OEvoabResultSet::getWarnings( ) +{ + return m_aWarnings.getWarnings(); +} + +//XColumnLocate Interface +sal_Int32 SAL_CALL OEvoabResultSet::findColumn( const OUString& columnName ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + checkDisposed(OResultSet_BASE::rBHelper.bDisposed); + + // find the first column with the name columnName + Reference< XResultSetMetaData > xMeta = getMetaData(); + sal_Int32 nLen = xMeta->getColumnCount(); + sal_Int32 i = 1; + for(;i<=nLen;++i) + { + if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) : + columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i))) + return i; + } + + ::dbtools::throwInvalidColumnException( columnName, *this ); + assert(false); + return 0; // Never reached +} + +//XColumnLocate interface ends + + +::cppu::IPropertyArrayHelper* OEvoabResultSet::createArrayHelper( ) const +{ + Sequence< Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); +} + +::cppu::IPropertyArrayHelper & OEvoabResultSet::getInfoHelper() +{ + return *getArrayHelper(); +} + +void SAL_CALL OEvoabResultSet::acquire() throw() +{ + OResultSet_BASE::acquire(); +} + +void SAL_CALL OEvoabResultSet::release() throw() +{ + OResultSet_BASE::release(); +} + +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL +OEvoabResultSet::getPropertySetInfo( ) +{ + return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); +} + + +} // connectivity::evoab + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |