Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/dbaccess/source/core/api/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 104 kB image not shown  

Quelle  RowSet.cxx   Sprache: C

 
/* -*- 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 <sal/config.h>
#include <sal/log.hxx>

#include <map>
#include <utility>

#include "RowSet.hxx"
#include <stringconstants.hxx>
#include <sdbcoretools.hxx>
#include <SingleSelectQueryComposer.hxx>
#include "CRowSetColumn.hxx"
#include "CRowSetDataColumn.hxx"
#include "RowSetCache.hxx"
#include <strings.hrc>
#include <strings.hxx>
#include <core_resource.hxx>
#include <tablecontainer.hxx>

#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdb/DatabaseContext.hpp>
#include <com/sun/star/sdb/ErrorCondition.hpp>
#include <com/sun/star/sdb/RowChangeAction.hpp>
#include <com/sun/star/sdb/RowSetVetoException.hpp>
#include <com/sun/star/sdb/XCompletedConnection.hpp>
#include <com/sun/star/sdb/XParametersSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/sdbc/FetchDirection.hpp>
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/sdbcx/Privilege.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>

#include <comphelper/extract.hxx>
#include <comphelper/seqstream.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/servicehelper.hxx>
#include <comphelper/types.hxx>
#include <comphelper/uno3.hxx>
#include <connectivity/BlobHelper.hxx>
#include <connectivity/dbconversion.hxx>
#include <connectivity/dbexception.hxx>
#include <connectivity/dbtools.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/interfacecontainer.h>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <o3tl/safeint.hxx>
#include <unotools/syslocale.hxx>
#include <comphelper/diagnose_ex.hxx>

using namespace dbaccess;
using namespace connectivity;
using namespace comphelper;
using namespace dbtools;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::util;
using namespace ::cppu;
using namespace ::osl;

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_dba_ORowSet_get_implementation(css::uno::XComponentContext* context,
                                                 css::uno::Sequence<css::uno::Any> const &)
{
    return cppu::acquire(new ORowSet(context));
}

namespace dbaccess
{
ORowSet::ORowSet( const Reference< css::uno::XComponentContext >& _rxContext )
    :ORowSet_BASE1(m_aMutex)
    ,ORowSetBase( _rxContext, ORowSet_BASE1::rBHelper, &m_aMutex )
    ,m_aPrematureParamValues(new ORowSetValueVector)
    ,m_aParameterValueForCache(new ORowSetValueVector)
    ,m_aRowsetListeners(*m_pMutex)
    ,m_aApproveListeners(*m_pMutex)
    ,m_aRowsChangeListener(*m_pMutex)
    ,m_sErrorString(ResourceManager::loadString(RID_STR_COMMAND_LEADING_TO_ERROR))
    ,m_nFetchDirection(FetchDirection::FORWARD)
    ,m_nFetchSize(50)
    ,m_nMaxFieldSize(0)
    ,m_nMaxRows(0)
    ,m_nQueryTimeOut(0)
    ,m_nCommandType(CommandType::COMMAND)
    ,m_nTransactionIsolation(0)
    ,m_nPrivileges(0)
    ,m_nLastKnownRowCount(0)
    ,m_nInAppend(0)
    ,m_bInsertingRow(false)
    ,m_bLastKnownRowCountFinal(false)
    ,m_bUseEscapeProcessing(true)
    ,m_bApplyFilter(false)
    ,m_bCommandFacetsDirty( true )
    ,m_bParametersDirty( true )
    ,m_bModified(false)
    ,m_bRebuildConnOnExecute(false)
    ,m_bIsBookmarkable(true)
    ,m_bNew(false)
    ,m_bCanUpdateInsertedRows(true)
    ,m_bOwnConnection(false)
    ,m_bPropChangeNotifyEnabled(true)
{
    m_nResultSetType = ResultSetType::SCROLL_SENSITIVE;
    m_nResultSetConcurrency = ResultSetConcurrency::UPDATABLE;
    m_pMySelf = this;
    m_aActiveConnection <<= m_xActiveConnection;

    sal_Int32 const nRBT = PropertyAttribute::READONLY   | PropertyAttribute::BOUND      | PropertyAttribute::TRANSIENT;
    sal_Int32 const nRT  = PropertyAttribute::READONLY   | PropertyAttribute::TRANSIENT;
    sal_Int32 const nBT  = PropertyAttribute::BOUND      | PropertyAttribute::TRANSIENT;

    m_aPrematureParamValues->resize( 0 );

    // sdb.RowSet Properties
    registerMayBeVoidProperty(PROPERTY_ACTIVE_CONNECTION,PROPERTY_ID_ACTIVE_CONNECTION, PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT|PropertyAttribute::BOUND, &m_aActiveConnection,   cppu::UnoType<XConnection>::get());
    registerProperty(PROPERTY_DATASOURCENAME,       PROPERTY_ID_DATASOURCENAME,         PropertyAttribute::BOUND,       &m_aDataSourceName,     ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_COMMAND,              PROPERTY_ID_COMMAND,                PropertyAttribute::BOUND,       &m_aCommand,&nbsp;           ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_COMMAND_TYPE,         PROPERTY_ID_COMMAND_TYPE,           PropertyAttribute::BOUND,       &m_nCommandType,        ::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_ACTIVECOMMAND,        PROPERTY_ID_ACTIVECOMMAND,          nRBT,                           &m_aActiveCommand,      ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_IGNORERESULT,         PROPERTY_ID_IGNORERESULT,           PropertyAttribute::BOUND,       &m_bIgnoreResult,       cppu::UnoType<bool>::get());
    registerProperty(PROPERTY_FILTER,               PROPERTY_ID_FILTER,                 PropertyAttribute::BOUND,       &m_aFilter,&nbsp;            ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_HAVING_CLAUSE,        PROPERTY_ID_HAVING_CLAUSE,          PropertyAttribute::BOUND,       &m_aHavingClause,       ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_GROUP_BY,             PROPERTY_ID_GROUP_BY,               PropertyAttribute::BOUND,       &m_aGroupBy,            ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_APPLYFILTER,          PROPERTY_ID_APPLYFILTER,            PropertyAttribute::BOUND,       &m_bApplyFilter,        cppu::UnoType<bool>::get());
    registerProperty(PROPERTY_ORDER,                PROPERTY_ID_ORDER,                  PropertyAttribute::BOUND,       &m_aOrder,              ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_PRIVILEGES,           PROPERTY_ID_PRIVILEGES,             nRT,                            &m_nPrivileges,         ::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_ISMODIFIED,           PROPERTY_ID_ISMODIFIED,             nBT,                            &m_bModified,           cppu::UnoType<bool>::get());
    registerProperty(PROPERTY_ISNEW,                PROPERTY_ID_ISNEW,                  nRBT,                           &m_bNew,                cppu::UnoType<bool>::get());
    registerProperty(PROPERTY_SINGLESELECTQUERYCOMPOSER,PROPERTY_ID_SINGLESELECTQUERYCOMPOSER,  nRT,                    &m_xComposer,   cppu::UnoType<XSingleSelectQueryComposer>::get());

    // sdbcx.ResultSet Properties
    registerProperty(PROPERTY_ISBOOKMARKABLE,       PROPERTY_ID_ISBOOKMARKABLE,         nRT,                            &m_bIsBookmarkable,      cppu::UnoType<bool>::get());
    registerProperty(PROPERTY_CANUPDATEINSERTEDROWS,PROPERTY_ID_CANUPDATEINSERTEDROWS,  nRT,                            &m_bCanUpdateInsertedRows,      cppu::UnoType<bool>::get());
    // sdbc.ResultSet Properties
    registerProperty(PROPERTY_RESULTSETCONCURRENCY, PROPERTY_ID_RESULTSETCONCURRENCY,   PropertyAttribute::TRANSIENT,   &m_nResultSetConcurrency,::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_RESULTSETTYPE,        PROPERTY_ID_RESULTSETTYPE,          PropertyAttribute::TRANSIENT,   &m_nResultSetType,      ::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_FETCHDIRECTION,       PROPERTY_ID_FETCHDIRECTION,         PropertyAttribute::TRANSIENT,   &m_nFetchDirection,     ::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_FETCHSIZE,            PROPERTY_ID_FETCHSIZE,              PropertyAttribute::TRANSIENT,   &m_nFetchSize,          ::cppu::UnoType<sal_Int32>::get());

    // sdbc.RowSet Properties
    registerProperty(PROPERTY_URL,                  PROPERTY_ID_URL,                    0,                              &m_aURL,                ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_TRANSACTIONISOLATION, PROPERTY_ID_TRANSACTIONISOLATION,   PropertyAttribute::TRANSIENT,   &m_nTransactionIsolation,::cppu::UnoType<sal_Int32>::get());
    registerMayBeVoidProperty(PROPERTY_TYPEMAP,     PROPERTY_ID_TYPEMAP,                PropertyAttribute::MAYBEVOID|PropertyAttribute::TRANSIENT,  &m_aTypeMap,            cppu::UnoType<XNameAccess>::get());
    registerProperty(PROPERTY_ESCAPE_PROCESSING,PROPERTY_ID_ESCAPE_PROCESSING,  PropertyAttribute::BOUND,       &m_bUseEscapeProcessing,cppu::UnoType<bool>::get()  );
    registerProperty(PROPERTY_QUERYTIMEOUT,         PROPERTY_ID_QUERYTIMEOUT,           PropertyAttribute::TRANSIENT,   &m_nQueryTimeOut,       ::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_MAXFIELDSIZE,         PROPERTY_ID_MAXFIELDSIZE,           PropertyAttribute::TRANSIENT,   &m_nMaxFieldSize,       ::cppu::UnoType<sal_Int32>::get());
    registerProperty(PROPERTY_MAXROWS,              PROPERTY_ID_MAXROWS,                0,                              &m_nMaxRows,            ::cppu::UnoType<sal_Int32>::get() );
    registerProperty(PROPERTY_USER,                 PROPERTY_ID_USER,                   PropertyAttribute::TRANSIENT,   &m_aUser,&nbsp;              ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_PASSWORD,             PROPERTY_ID_PASSWORD,               PropertyAttribute::TRANSIENT,   &m_aPassword,           ::cppu::UnoType<OUString>::get());

    registerProperty(PROPERTY_UPDATE_CATALOGNAME,   PROPERTY_ID_UPDATE_CATALOGNAME,     PropertyAttribute::BOUND,       &m_aUpdateCatalogName,  ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_UPDATE_SCHEMANAME,    PROPERTY_ID_UPDATE_SCHEMANAME,      PropertyAttribute::BOUND,       &m_aUpdateSchemaName,   ::cppu::UnoType<OUString>::get());
    registerProperty(PROPERTY_UPDATE_TABLENAME,     PROPERTY_ID_UPDATE_TABLENAME,       PropertyAttribute::BOUND,       &m_aUpdateTableName,    ::cppu::UnoType<OUString>::get());

    // ???
    registerProperty(PROPERTY_CHANGE_NOTIFICATION_ENABLED, PROPERTY_ID_PROPCHANGE_NOTIFY, PropertyAttribute::BOUND,     &m_bPropChangeNotifyEnabled, cppu::UnoType<bool>::get());
}

ORowSet::~ORowSet()
{
    if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
    {
        SAL_WARN("dbaccess""Please check who doesn't dispose this component!");
        osl_atomic_increment( &m_refCount );
        dispose();
    }
}

void ORowSet::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const
{
    switch( _nHandle )
    {
        case PROPERTY_ID_COMMAND_TYPE:
            _rDefault <<= CommandType::COMMAND;
            break;
        case PROPERTY_ID_IGNORERESULT:
            _rDefault <<= false;
            break;
        case PROPERTY_ID_APPLYFILTER:
            _rDefault <<= false;
            break;
        case PROPERTY_ID_ISMODIFIED:
            _rDefault <<= false;
            break;
        case PROPERTY_ID_ISBOOKMARKABLE:
            _rDefault <<= true;
            break;
        case PROPERTY_ID_CANUPDATEINSERTEDROWS:
            _rDefault <<= true;
            break;
        case PROPERTY_ID_RESULTSETTYPE:
            _rDefault <<= ResultSetType::SCROLL_INSENSITIVE;
            break;
        case PROPERTY_ID_RESULTSETCONCURRENCY:
            _rDefault <<= ResultSetConcurrency::UPDATABLE;
            break;
        case PROPERTY_ID_FETCHDIRECTION:
            _rDefault <<= FetchDirection::FORWARD;
            break;
        case PROPERTY_ID_FETCHSIZE:
            _rDefault <<= static_cast<sal_Int32>(1);
            break;
        case PROPERTY_ID_ESCAPE_PROCESSING:
            _rDefault <<= true;
            break;
        case PROPERTY_ID_MAXROWS:
            _rDefault <<= sal_Int32( 0 );
            break;
        case PROPERTY_ID_FILTER:
        case PROPERTY_ID_HAVING_CLAUSE:
        case PROPERTY_ID_GROUP_BY:
        case PROPERTY_ID_ORDER:
        case PROPERTY_ID_UPDATE_CATALOGNAME:
        case PROPERTY_ID_UPDATE_SCHEMANAME:
        case PROPERTY_ID_UPDATE_TABLENAME:
            _rDefault <<= OUString();
            break;
    }
}

void SAL_CALL ORowSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any&&nbsp;rValue)
{
    switch(nHandle)
    {
        case PROPERTY_ID_ISMODIFIED:
            m_bModified = cppu::any2bool(rValue);
            break;
        case PROPERTY_ID_FETCHDIRECTION:
            if( m_nResultSetType == ResultSetType::FORWARD_ONLY)
                throw Exception(u"resultsettype is FORWARD_ONLY"_ustr, nullptr);
            [[fallthrough]];
        default:
            OPropertyStateContainer::setFastPropertyValue_NoBroadcast(nHandle,rValue);
    }

    if  (   ( nHandle == PROPERTY_ID_ACTIVE_CONNECTION )
        ||  ( nHandle == PROPERTY_ID_DATASOURCENAME )
        ||  ( nHandle == PROPERTY_ID_COMMAND )
        ||  ( nHandle == PROPERTY_ID_COMMAND_TYPE )
        ||  ( nHandle == PROPERTY_ID_IGNORERESULT )
        ||  ( nHandle == PROPERTY_ID_FILTER )
        ||  ( nHandle == PROPERTY_ID_HAVING_CLAUSE )
        ||  ( nHandle == PROPERTY_ID_GROUP_BY )
        ||  ( nHandle == PROPERTY_ID_APPLYFILTER )
        ||  ( nHandle == PROPERTY_ID_ORDER )
        ||  ( nHandle == PROPERTY_ID_URL )
        ||  ( nHandle == PROPERTY_ID_USER )
        )
    {
        m_bCommandFacetsDirty = true;
    }


    switch(nHandle)
    {
        case PROPERTY_ID_ACTIVE_CONNECTION:
            // the new connection
            {
                assert(m_aActiveConnection == rValue);
                Reference< XConnection > xNewConnection(m_aActiveConnection,UNO_QUERY);
                setActiveConnection(xNewConnection, false);
            }

            m_bOwnConnection        = false;
            m_bRebuildConnOnExecute = false;
            break;

        case PROPERTY_ID_DATASOURCENAME:
            if(!m_xStatement.is())
            {
                Reference< XConnection >  xNewConn;
                Any aNewConn;
                aNewConn <<= xNewConn;
                setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn);
            }
            else
                m_bRebuildConnOnExecute = true;
            break;
        case PROPERTY_ID_FETCHSIZE:
            if(m_pCache)
            {
                m_pCache->setFetchSize(m_nFetchSize);
                fireRowcount();
            }
            break;
        case PROPERTY_ID_URL:
            // is the connection-to-be-built determined by the url (which is the case if m_aDataSourceName is empty) ?
            if (m_aDataSourceName.isEmpty())
            {
                // are we active at the moment ?
                if (m_xStatement.is())
                    // yes -> the next execute needs to rebuild our connection because of this new property
                    m_bRebuildConnOnExecute = true;
                else
                {   // no -> drop our active connection (if we have one) as it doesn't correspond to this new property value anymore
                    Reference< XConnection >  xNewConn;
                    Any aNewConn;
                    aNewConn <<= xNewConn;
                    setFastPropertyValue(PROPERTY_ID_ACTIVE_CONNECTION, aNewConn);
                }
            }
            m_bOwnConnection = true;
            break;
        case PROPERTY_ID_TYPEMAP:
            m_xTypeMap.set(m_aTypeMap, css::uno::UNO_QUERY);
            break;
        case PROPERTY_ID_PROPCHANGE_NOTIFY:
            m_bPropChangeNotifyEnabled = ::cppu::any2bool(rValue);
            break;
        default:
            break;
    }
}

void SAL_CALL ORowSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
{
    if(m_pCache)
    {
        switch(nHandle)
        {
        case PROPERTY_ID_ISMODIFIED:
            rValue <<= m_bModified;
            break;
        case PROPERTY_ID_ISNEW:
            rValue <<= m_bNew;
            break;
        case PROPERTY_ID_PRIVILEGES:
            rValue <<= m_pCache->m_nPrivileges;
            break;
        case PROPERTY_ID_ACTIVE_CONNECTION:
            rValue <<= m_xActiveConnection;
            break;
        case PROPERTY_ID_TYPEMAP:
            rValue <<= m_xTypeMap;
            break;
        default:
            ORowSetBase::getFastPropertyValue(rValue,nHandle);
        }
    }
    else
    {
        switch(nHandle)
        {
            case PROPERTY_ID_ACTIVE_CONNECTION:
                rValue <<= m_xActiveConnection;
                break;
            case PROPERTY_ID_TYPEMAP:
                rValue <<= m_xTypeMap;
                break;
            case PROPERTY_ID_PROPCHANGE_NOTIFY:
                rValue <<= m_bPropChangeNotifyEnabled;
                break;
            default:
                ORowSetBase::getFastPropertyValue(rValue,nHandle);
        }
    }
}

// css::XTypeProvider
Sequence< Type > SAL_CALL ORowSet::getTypes()
{
    OTypeCollection aTypes(cppu::UnoType<XPropertySet>::get(),
                            cppu::UnoType<XFastPropertySet>::get(),
                            cppu::UnoType<XMultiPropertySet>::get(),
                           ::comphelper::concatSequences(ORowSet_BASE1::getTypes(),ORowSetBase::getTypes()));
    return aTypes.getTypes();
}

Sequence< sal_Int8 > SAL_CALL ORowSet::getImplementationId()
{
    return css::uno::Sequence<sal_Int8>();
}

// css::XInterface
Any SAL_CALL ORowSet::queryInterface( const Type & rType )
{
    return ORowSet_BASE1::queryInterface( rType);
}

void SAL_CALL ORowSet::acquire() noexcept
{
    ORowSet_BASE1::acquire();
}

void SAL_CALL ORowSet::release() noexcept
{
    ORowSet_BASE1::release();
}

// css::XAggregation
Any SAL_CALL ORowSet::queryAggregation( const Type& rType )
{
    Any aRet(ORowSetBase::queryInterface(rType));
    if (!aRet.hasValue())
        aRet = ORowSet_BASE1::queryAggregation(rType);
    return aRet;
}

// css::XServiceInfo
OUString SAL_CALL ORowSet::getImplementationName()
{
    return u"com.sun.star.comp.dba.ORowSet"_ustr;
}

sal_Bool SAL_CALL ORowSet::supportsService( const OUString& _rServiceName )
{
    return cppu::supportsService(this, _rServiceName);
}

Sequence< OUString > SAL_CALL ORowSet::getSupportedServiceNames()
{
    return { SERVICE_SDBC_RESULTSET, SERVICE_SDBC_ROWSET, SERVICE_SDBCX_RESULTSET,
             SERVICE_SDB_RESULTSET, SERVICE_SDB_ROWSET };
}

// OComponentHelper
void SAL_CALL ORowSet::disposing()
{
    OPropertyStateContainer::disposing();

    MutexGuard aGuard(m_aMutex);
    EventObject aDisposeEvent;
    aDisposeEvent.Source = static_cast< XComponent* >(this);
    m_aRowsetListeners.disposeAndClear( aDisposeEvent );
    m_aApproveListeners.disposeAndClear( aDisposeEvent );
    m_aRowsChangeListener.disposeAndClear( aDisposeEvent );

    freeResources( true );

    // remove myself as dispose listener
    Reference< XComponent >  xComponent(m_xActiveConnection, UNO_QUERY);
    if (xComponent.is())
        xComponent->removeEventListener(query_aggregation<XEventListener>(this));

    m_aActiveConnection = Any(); // the any contains a reference too
    if(m_bOwnConnection)
        ::comphelper::disposeComponent(m_xActiveConnection);
    m_xActiveConnection = nullptr;


    ORowSetBase::disposing();
}

void ORowSet::freeResources( bool _bComplete )
{
    MutexGuard aGuard(m_aMutex);

    // free all clones
    for (auto const& clone : m_aClones)
    {
        rtl::Reference< ORowSetClone > xComp(clone);
        if (xComp.is())
            xComp->dispose();
    }
    m_aClones.clear();

    doCancelModification();

    m_aBookmark     = Any();
    m_bBeforeFirst  = true;
    m_bAfterLast    = false;
    m_bNew          = false;
    m_bModified     = false;
    m_bIsInsertRow  = false;
    m_bLastKnownRowCountFinal = false;
    m_nLastKnownRowCount      = 0;

    if ( !_bComplete )
        return;

    // the columns must be disposed before the querycomposer is disposed because
    // their owner can be the composer
    TDataColumns().swap(m_aDataColumns);// clear and resize capacity
    std::vector<bool>().swap(m_aReadOnlyDataColumns);

    m_xColumns      = nullptr;
    if ( m_pColumns )
        m_pColumns->disposing();
    // dispose the composer to avoid that everybody knows that the querycomposer is eol
    try { ::comphelper::disposeComponent( m_xComposer ); }
    catch(Exception&)
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
        m_xComposer = nullptr;
    }

    // let our warnings container forget the reference to the (possibly disposed) old result set
    m_aWarnings.setExternalWarnings( nullptr );

    m_pCache.reset();

    impl_resetTables_nothrow();

    m_xStatement    = nullptr;
    m_xTypeMap      = nullptr;

    if ( m_aOldRow.is() )
        m_aOldRow->clearRow();

    impl_disposeParametersContainer_nothrow();

    m_bCommandFacetsDirty = true;
}

void ORowSet::setActiveConnection( Reference< XConnection > const & _rxNewConn, bool _bFireEvent )
{
    if (_rxNewConn.get() == m_xActiveConnection.get())
        // nothing to do
        return;

    // remove the event listener for the old connection
    Reference< XComponent >  xComponent(m_xActiveConnection, UNO_QUERY);
    if (xComponent.is())
        xComponent->removeEventListener(query_aggregation<XEventListener>(this));

    // if we owned the connection, remember it for later disposing
    if(m_bOwnConnection)
        m_xOldConnection = m_xActiveConnection;

    // for firing the PropertyChangeEvent
    sal_Int32 nHandle = PROPERTY_ID_ACTIVE_CONNECTION;
    Any aOldConnection; aOldConnection <<= m_xActiveConnection;
    Any aNewConnection; aNewConnection <<= _rxNewConn;

    // set the new connection
    m_xActiveConnection = _rxNewConn;
    if (m_xActiveConnection.is())
        m_aActiveConnection <<= m_xActiveConnection;
    else
        m_aActiveConnection.clear();

    // fire the event
    if (_bFireEvent)
        fire(&nHandle, &aNewConnection, &aOldConnection, 1, false);

    // register as event listener for the new connection
    xComponent.set(m_xActiveConnection,UNO_QUERY);
    if (xComponent.is())
        xComponent->addEventListener(query_aggregation<XEventListener>(this));
}

// css::XEventListener
void SAL_CALL ORowSet::disposing( const css::lang::EventObject& Source )
{
    // close rowset because the connection is going to be deleted (someone told me :-)
    Reference<XConnection> xCon(Source.Source,UNO_QUERY);
    if(m_xActiveConnection == xCon)
    {
        close();
        {
            MutexGuard aGuard( m_aMutex );
            Reference< XConnection > xXConnection;
            setActiveConnection( xXConnection );
        }
    }
}

// XCloseable
void SAL_CALL ORowSet::close(  )
{
    {
        MutexGuard aGuard( m_aMutex );
        ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    }
    // additional things to set
    freeResources( true );
}

// comphelper::OPropertyArrayUsageHelper
::cppu::IPropertyArrayHelper* ORowSet::createArrayHelper( ) const
{
    Sequence< Property > aProps;
    describeProperties(aProps);
    return new ::cppu::OPropertyArrayHelper(aProps);
}

// cppu::OPropertySetHelper
::cppu::IPropertyArrayHelper& SAL_CALL ORowSet::getInfoHelper()
{
    return *::comphelper::OPropertyArrayUsageHelper<ORowSet>::getArrayHelper();
}

void ORowSet::updateValue(sal_Int32 columnIndex,const ORowSetValue& x)
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::MutexGuard aGuard( *m_pMutex );
    checkUpdateConditions(columnIndex);
    checkUpdateIterator();

    ORowSetValueVector::Vector& rRow = **m_aCurrentRow;
    ORowSetNotifier aNotify(this, std::vector(rRow));
    m_pCache->updateValue(columnIndex,x,rRow,aNotify.getChangedColumns());
    m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
    aNotify.firePropertyChange();
}

// XRowUpdate
void SAL_CALL ORowSet::updateNull( sal_Int32 columnIndex )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::MutexGuard aGuard( *m_pMutex );
    checkUpdateConditions(columnIndex);
    checkUpdateIterator();

    ORowSetValueVector::Vector& rRow = **m_aCurrentRow;
    ORowSetNotifier aNotify(this, std::vector(rRow));
    m_pCache->updateNull(columnIndex,rRow,aNotify.getChangedColumns());
    m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
    aNotify.firePropertyChange();
}

void SAL_CALL ORowSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x )
{
    updateValue(columnIndex, static_cast<bool>(x));
}

void SAL_CALL ORowSet::updateByte( sal_Int32 columnIndex, sal_Int8 x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateShort( sal_Int32 columnIndex, sal_Int16 x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateInt( sal_Int32 columnIndex, sal_Int32 x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateLong( sal_Int32 columnIndex, sal_Int64 x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateFloat( sal_Int32 columnIndex, float x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateDouble( sal_Int32 columnIndex, double x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateString( sal_Int32 columnIndex, const OUString& x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateDate( sal_Int32 columnIndex, const css::util::Date& x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateTime( sal_Int32 columnIndex, const css::util::Time& x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateTimestamp( sal_Int32 columnIndex, const css::util::DateTime& x )
{
    updateValue(columnIndex,x);
}

void SAL_CALL ORowSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    ::osl::MutexGuard aGuard( *m_pMutex );
    checkUpdateConditions(columnIndex);
    checkUpdateIterator();

    {
        Sequence<sal_Int8> aSeq;
        if(x.is())
            x->readBytes(aSeq,length);
        updateValue(columnIndex,aSeq);
    }
}

void SAL_CALL ORowSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    ::osl::MutexGuard aGuard( *m_pMutex );
    checkUpdateConditions(columnIndex);
    checkUpdateIterator();
    ORowSetValueVector::Vector& rRow = **m_aCurrentRow;
    ORowSetNotifier aNotify(this, std::vector(rRow));
    m_pCache->updateCharacterStream(columnIndex,x,length,rRow,aNotify.getChangedColumns());
    m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
    aNotify.firePropertyChange();
}

void SAL_CALL ORowSet::updateObject( sal_Int32 columnIndex, const Any& x )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    ::osl::MutexGuard aGuard( *m_pMutex );
    checkUpdateConditions(columnIndex);
    checkUpdateIterator();

    Any aNewValue = x;

    if ( m_pColumns )
    {
        Reference<XPropertySet> xColumn(m_pColumns->getByIndex(columnIndex-1),UNO_QUERY);
        sal_Int32 nColType = 0;
        xColumn->getPropertyValue(PROPERTY_TYPE) >>= nColType;
        switch( nColType )
        {
            case DataType::DATE:
            case DataType::TIME:
            case DataType::TIMESTAMP:
            {
                double nValue = 0;
                if ( x >>= nValue )
                {
                    if ( DataType::TIMESTAMP == nColType )
                        aNewValue <<= dbtools::DBTypeConversion::toDateTime( nValue );
                    else if ( DataType::DATE == nColType )
                        aNewValue <<= dbtools::DBTypeConversion::toDate( nValue );
                    else
                        aNewValue <<= dbtools::DBTypeConversion::toTime( nValue );
                }
                break;
            }
        }
    }

    if (!::dbtools::implUpdateObject(this, columnIndex, aNewValue))
    {   // there is no other updateXXX call which can handle the value in x
        ORowSetValueVector::Vector& rRow = **m_aCurrentRow;
        ORowSetNotifier aNotify(this, std::vector(rRow));
        m_pCache->updateObject(columnIndex,aNewValue,rRow,aNotify.getChangedColumns());
        m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
        aNotify.firePropertyChange();
    }
}

void SAL_CALL ORowSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    ::osl::MutexGuard aGuard( *m_pMutex );
    checkUpdateConditions(columnIndex);
    checkUpdateIterator();
    ORowSetValueVector::Vector& rRow = **m_aCurrentRow;
    ORowSetNotifier aNotify(this, std::vector(rRow));
    m_pCache->updateNumericObject(columnIndex,x,rRow,aNotify.getChangedColumns());
    m_bModified = m_bModified || !aNotify.getChangedColumns().empty();
    aNotify.firePropertyChange();
}

namespace
{
    class ProtectFlag
    {
        bool& m_rInsertingRow;
    public:
        explicit ProtectFlag(bool& rInsertingRow)
            : m_rInsertingRow(rInsertingRow)
        {
            if (m_rInsertingRow)
            {
                throw std::runtime_error("recursion in insertRow");
            }
            m_rInsertingRow = true;
        }
        ~ProtectFlag()
        {
            m_rInsertingRow = false;
        }
    };
}

// XResultSetUpdate
void SAL_CALL ORowSet::insertRow()
{
    ProtectFlag aFlagControl(m_bInsertingRow);

    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    // insertRow is not allowed when
    // standing not on the insert row nor
    // when the row isn't modified
    // or the concurrency is read only
    ::osl::ResettableMutexGuard aGuard( *m_pMutex );

    if(!m_pCache || !m_bNew || !m_bModified || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY)
        throwFunctionSequenceException(*this);

    // remember old value for fire
    bool bOld = m_bNew;

    ORowSetRow aOldValues;
    if ( !m_aCurrentRow.isNull() )
        aOldValues = new ORowSetValueVector( *(*m_aCurrentRow));
    Sequence<Any> aChangedBookmarks;
    RowsChangeEvent aEvt(*this,RowChangeAction::INSERT,1,aChangedBookmarks);
    notifyAllListenersRowBeforeChange(aGuard,aEvt);

    std::vector< Any > aBookmarks;
    bool bInserted = m_pCache->insertRow(aBookmarks);

    // make sure that our row is set to the new inserted row before clearing the insert flags in the cache
    m_pCache->resetInsertRow(bInserted);

    // notification order
    // - column values
    setCurrentRow( falsetrue, aOldValues, aGuard ); // we don't move here

    // read-only flag restored
    impl_restoreDataColumnsWriteable_throw();

    // - rowChanged
    notifyAllListenersRowChanged(aGuard,aEvt);

    if ( !aBookmarks.empty() )
    {
        RowsChangeEvent aUpEvt(*this,RowChangeAction::UPDATE,aBookmarks.size(),comphelper::containerToSequence(aBookmarks));
        notifyAllListenersRowChanged(aGuard,aUpEvt);
    }

    // - IsModified
    if(!m_bModified)
        fireProperty(PROPERTY_ID_ISMODIFIED,false,true);
    OSL_ENSURE( !m_bModified, "ORowSet::insertRow: just updated, but _still_ modified?" );

    // - IsNew
    if(m_bNew != bOld)
        fireProperty(PROPERTY_ID_ISNEW,m_bNew,bOld);

    // - RowCount/IsRowCountFinal
    fireRowcount();
}

void SAL_CALL ORowSet::updateRow(  )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);
    // not allowed when standing on insert row
    ::osl::ResettableMutexGuard aGuard( *m_pMutex );
    if ( !m_pCache || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY || m_bNew || ((m_pCache->m_nPrivileges & Privilege::UPDATE ) != Privilege::UPDATE) )
        throwFunctionSequenceException(*this);


    if(!m_bModified)
        return;

    ORowSetRow aOldValues;
    if ( !m_aCurrentRow.isNull() )
        aOldValues = new ORowSetValueVector( *(*m_aCurrentRow) );

    Sequence<Any> aChangedBookmarks;
    RowsChangeEvent aEvt(*this,RowChangeAction::UPDATE,1,aChangedBookmarks);
    notifyAllListenersRowBeforeChange(aGuard,aEvt);

    std::vector< Any > aBookmarks;
    m_pCache->updateRow(m_aCurrentRow.operator ->(),aBookmarks);
    if ( !aBookmarks.empty() )
        aEvt.Bookmarks = comphelper::containerToSequence(aBookmarks);
    aEvt.Rows += aBookmarks.size();
    m_aBookmark     = m_pCache->getBookmark();
    m_aCurrentRow   = m_pCache->m_aMatrixIter;
    m_bIsInsertRow  = false;
    if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && (*m_pCache->m_aMatrixIter).is() )
    {
        if ( m_pCache->isResultSetChanged() )
        {
            impl_rebuild_throw(aGuard);
        }
        else
        {
            m_aOldRow->setRow(new ORowSetValueVector(*(*m_aCurrentRow)));

            // notification order
            // - column values
            ORowSetBase::firePropertyChange(aOldValues);
        }
        // - rowChanged
        notifyAllListenersRowChanged(aGuard,aEvt);

        // - IsModified
        if(!m_bModified)
            fireProperty(PROPERTY_ID_ISMODIFIED,false,true);
        OSL_ENSURE( !m_bModified, "ORowSet::updateRow: just updated, but _still_ modified?" );

        // - RowCount/IsRowCountFinal
        fireRowcount();
    }
    else if ( !m_bAfterLast ) // the update went wrong
    {
        ::dbtools::throwSQLException( DBA_RES( RID_STR_UPDATE_FAILED ), StandardSQLState::INVALID_CURSOR_POSITION, *this );
    }
}

void SAL_CALL ORowSet::deleteRow(  )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::ResettableMutexGuard aGuard( *m_pMutex );
    checkCache();

    if ( m_bBeforeFirst || m_bAfterLast )
        ::dbtools::throwSQLException( DBA_RES( RID_STR_NO_DELETE_BEFORE_AFTER ), StandardSQLState::INVALID_CURSOR_POSITION, *this );
    if ( m_bNew )
        ::dbtools::throwSQLException( DBA_RES( RID_STR_NO_DELETE_INSERT_ROW ), StandardSQLState::INVALID_CURSOR_POSITION, *this );
    if  ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
        ::dbtools::throwSQLException( DBA_RES( RID_STR_RESULT_IS_READONLY ), StandardSQLState::FUNCTION_SEQUENCE_ERROR, *this );
    if ( ( m_pCache->m_nPrivileges & Privilege::DELETE ) != Privilege::DELETE )
        ::dbtools::throwSQLException( DBA_RES( RID_STR_NO_DELETE_PRIVILEGE ), StandardSQLState::FUNCTION_SEQUENCE_ERROR, *this );
    if ( rowDeleted() )
        ::dbtools::throwSQLException( DBA_RES( RID_STR_ROW_ALREADY_DELETED ), StandardSQLState::FUNCTION_SEQUENCE_ERROR, *this );

    // this call position the cache indirect
    Any aBookmarkToDelete( m_aBookmark );
    positionCache( CursorMoveDirection::Current );
    sal_Int32 nDeletePosition = m_pCache->getRow();

    notifyRowSetAndClonesRowDelete( aBookmarkToDelete );

    ORowSetRow aOldValues;
    if ( m_pCache->m_aMatrixIter != m_pCache->getEnd() && m_pCache->m_aMatrixIter->is() )
        aOldValues = new ORowSetValueVector( *(*(m_pCache->m_aMatrixIter)) );

    Sequence<Any> aChangedBookmarks;
    RowsChangeEvent aEvt(*this,RowChangeAction::DELETE,1,aChangedBookmarks);
    notifyAllListenersRowBeforeChange(aGuard,aEvt);

    m_pCache->deleteRow();
    notifyRowSetAndClonesRowDeleted( aBookmarkToDelete, nDeletePosition );

    ORowSetNotifier aNotifier( this );
        // this will call cancelRowModification on the cache if necessary

    // notification order
    // - rowChanged
    notifyAllListenersRowChanged(aGuard,aEvt);

    // - IsModified
    // - IsNew
    aNotifier.fire( );

    // - RowCount/IsRowCountFinal
    fireRowcount();
}

void ORowSet::implCancelRowUpdates( bool _bNotifyModified )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::MutexGuard aGuard( *m_pMutex );
    if ( m_bBeforeFirst || m_bAfterLast || rowDeleted() )
        return// nothing to do so return

    checkCache();
    // cancelRowUpdates is not allowed when:
    // - standing on the insert row
    // - the concurrency is read only
    // - the current row is deleted
    if ( m_bNew || m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
        throwFunctionSequenceException(*this);

    positionCache( CursorMoveDirection::Current );

    ORowSetRow aOldValues;
    if ( !m_bModified && _bNotifyModified && !m_aCurrentRow.isNull() )
        aOldValues = new ORowSetValueVector( *(*m_aCurrentRow) );

    m_pCache->cancelRowUpdates();

    m_aBookmark     = m_pCache->getBookmark();
    m_aCurrentRow   = m_pCache->m_aMatrixIter;
    m_bIsInsertRow  = false;

    // notification order
    // IsModified
    if( !m_bModified && _bNotifyModified )
    {
        // - column values
        ORowSetBase::firePropertyChange(aOldValues);
        fireProperty(PROPERTY_ID_ISMODIFIED,false,true);
    }
}

void SAL_CALL ORowSet::cancelRowUpdates(  )
{
    implCancelRowUpdates( true );
}

void SAL_CALL ORowSet::addRowSetListener( const Reference< XRowSetListener >& listener )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::MutexGuard aGuard( m_aColumnsMutex );
    if(listener.is())
        m_aRowsetListeners.addInterface(listener);
}

void SAL_CALL ORowSet::removeRowSetListener( const Reference< XRowSetListener >& listener )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::MutexGuard aGuard( m_aColumnsMutex );
    if(listener.is())
        m_aRowsetListeners.removeInterface(listener);
}

void ORowSet::notifyAllListeners(::osl::ResettableMutexGuard& _rGuard)
{
    EventObject aEvt(*m_pMySelf);
    _rGuard.clear();
    m_aRowsetListeners.notifyEach( &XRowSetListener::rowSetChanged, aEvt );
    _rGuard.reset();
}

void ORowSet::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard)
{
    EventObject aEvt(*m_pMySelf);
    _rGuard.clear();
    m_aRowsetListeners.notifyEach( &XRowSetListener::cursorMoved, aEvt );
    _rGuard.reset();
}

void ORowSet::notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard, const RowsChangeEvent& aEvt)
{
    _rGuard.clear();
    m_aRowsetListeners.notifyEach( &XRowSetListener::rowChanged, static_cast<EventObject>(aEvt) );
    m_aRowsChangeListener.notifyEach( &XRowsChangeListener::rowsChanged, aEvt );
    _rGuard.reset();
}

bool ORowSet::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard)
{
    EventObject aEvt(*m_pMySelf);
    std::vector< Reference< css::sdb::XRowSetApproveListener > > aListenerSeq = m_aApproveListeners.getElements();
    _rGuard.clear();
    bool bCheck = std::all_of(aListenerSeq.rbegin(), aListenerSeq.rend(),
        [&aEvt](Reference<css::sdb::XRowSetApproveListener>& rxItem) {
            try
            {
                return static_cast<bool>(rxItem->approveCursorMove(aEvt));
            }
            catch( RuntimeException& )
            {
                return true;
            }
        });
    _rGuard.reset();
    return bCheck;
}

void ORowSet::notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const RowChangeEvent &aEvt)
{
    std::vector< Reference< css::sdb::XRowSetApproveListener > > aListenerSeq = m_aApproveListeners.getElements();
    _rGuard.clear();
    bool bCheck = std::all_of(aListenerSeq.rbegin(), aListenerSeq.rend(),
        [&aEvt](Reference<css::sdb::XRowSetApproveListener>& rxItem) {
            try
            {
                return static_cast<bool>(rxItem->approveRowChange(aEvt));
            }
            catch( RuntimeException& )
            {
                return true;
            }
        });
    _rGuard.reset();

    if ( !bCheck )
        m_aErrors.raiseTypedException( sdb::ErrorCondition::ROW_SET_OPERATION_VETOED, *this, ::cppu::UnoType< RowSetVetoException >::get() );
}

void ORowSet::fireRowcount()
{
    sal_Int32 nCurrentRowCount( impl_getRowCount() );
    bool bCurrentRowCountFinal( m_pCache->m_bRowCountFinal );

    if ( m_nLastKnownRowCount != nCurrentRowCount )
    {
        sal_Int32 nHandle = PROPERTY_ID_ROWCOUNT;
        Any aNew,aOld;
        aNew <<= nCurrentRowCount; aOld <<= m_nLastKnownRowCount;
        fire(&nHandle,&aNew,&aOld,1,false);
        m_nLastKnownRowCount = nCurrentRowCount;
    }
    if ( !m_bLastKnownRowCountFinal && ( m_bLastKnownRowCountFinal != bCurrentRowCountFinal ) )
    {
        sal_Int32 nHandle = PROPERTY_ID_ISROWCOUNTFINAL;
        Any aNew,aOld;
        aNew <<= bCurrentRowCountFinal;
        aOld <<= m_bLastKnownRowCountFinal;
        fire(&nHandle,&aNew,&aOld,1,false);
        m_bLastKnownRowCountFinal = bCurrentRowCountFinal;
    }
}

void SAL_CALL ORowSet::moveToInsertRow(  )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::ResettableMutexGuard aGuard( *m_pMutex );
    checkPositioningAllowed();
    if ( ( m_pCache->m_nPrivileges & Privilege::INSERT ) != Privilege::INSERT )
        ::dbtools::throwSQLException( DBA_RES( RID_STR_NO_INSERT_PRIVILEGE ), StandardSQLState::GENERAL_ERROR, *this );

    if ( !notifyAllListenersCursorBeforeMove( aGuard ) )
        return;

    // remember old value for fire
    ORowSetRow aOldValues;
    if ( rowDeleted() )
    {
        positionCache( CursorMoveDirection::Forward );
        m_pCache->next();
        setCurrentRow( truefalse, aOldValues, aGuard);
    }
    else
        positionCache( CursorMoveDirection::Current );

    // check before because the resultset could be empty
    if  (   !m_bBeforeFirst
        &&  !m_bAfterLast
        &&  m_pCache->m_aMatrixIter != m_pCache->getEnd()
        &&  m_pCache->m_aMatrixIter->is()
        )
        aOldValues = new ORowSetValueVector( *(*(m_pCache->m_aMatrixIter)) );

    const bool bNewState = m_bNew;
    const bool bModState = m_bModified;

    m_pCache->moveToInsertRow();
    m_aCurrentRow = m_pCache->m_aInsertRow;
    m_bIsInsertRow  = true;

    // set read-only flag to false
    impl_setDataColumnsWriteable_throw();

    // notification order
    // - column values
    ORowSetBase::firePropertyChange(aOldValues);

    // - cursorMoved
    notifyAllListenersCursorMoved(aGuard);

    // - IsModified
    if ( bModState != m_bModified )
        fireProperty( PROPERTY_ID_ISMODIFIED, m_bModified, bModState );

    // - IsNew
    if ( bNewState != m_bNew )
        fireProperty( PROPERTY_ID_ISNEW, m_bNew, bNewState );

    // - RowCount/IsRowCountFinal
    fireRowcount();
}

void ORowSet::impl_setDataColumnsWriteable_throw()
{
    impl_restoreDataColumnsWriteable_throw();
    m_aReadOnlyDataColumns.resize(m_aDataColumns.size(),false);
    std::vector<bool, std::allocator<bool> >::iterator aReadIter = m_aReadOnlyDataColumns.begin();
    for (auto const& dataColumn : m_aDataColumns)
    {
        bool bReadOnly = false;
        dataColumn->getPropertyValue(PROPERTY_ISREADONLY) >>= bReadOnly;
        *aReadIter = bReadOnly;

        dataColumn->setPropertyValue(PROPERTY_ISREADONLY,Any(false));
        ++aReadIter;
    }
}

void ORowSet::impl_restoreDataColumnsWriteable_throw()
{
    assert(m_aDataColumns.size() == m_aReadOnlyDataColumns.size() || m_aReadOnlyDataColumns.empty());
    TDataColumns::const_iterator aIter = m_aDataColumns.begin();
    for (bool readOnlyDataColumn : m_aReadOnlyDataColumns)
    {
        (*aIter)->setPropertyValue(PROPERTY_ISREADONLY, Any(readOnlyDataColumn) );
        ++aIter;
    }
    m_aReadOnlyDataColumns.clear();
}

void SAL_CALL ORowSet::moveToCurrentRow(  )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    ::osl::ResettableMutexGuard aGuard( *m_pMutex );
    checkPositioningAllowed();

    if ( !m_pCache->m_bNew && !m_bModified )
        // nothing to do if we're not on the insertion row, and not modified otherwise
        return;

    if ( rowDeleted() )
        // this would perhaps even justify a RuntimeException...
        // if the current row is deleted, then no write access to this row should be possible. So,
        // m_bModified should be true. Also, as soon as somebody calls moveToInsertRow,
        // our current row should not be deleted anymore. So, we should not have survived the above
        // check "if ( !m_pCache->m_bNew && !m_bModified )"
        ::dbtools::throwSQLException( DBA_RES( RID_STR_ROW_ALREADY_DELETED ), StandardSQLState::FUNCTION_SEQUENCE_ERROR, *this );

    if ( !notifyAllListenersCursorBeforeMove( aGuard ) )
        return;

    positionCache( CursorMoveDirection::CurrentRefresh );

    ORowSetNotifier aNotifier( this );

    // notification order
    // - cursorMoved
    notifyAllListenersCursorMoved(aGuard);

    // - IsModified
    // - IsNew
    aNotifier.fire();
}

// XRow
sal_Bool SAL_CALL ORowSet::wasNull(  )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    checkCache();

    return ( m_pCache && isInsertRow() ) ? (**m_pCache->m_aInsertRow)[m_nLastColumnIndex].isNull() : ORowSetBase::wasNull();
}

const ORowSetValue& ORowSet::getInsertValue(sal_Int32 columnIndex)
{
    checkCache();

    if ( m_pCache && isInsertRow() )
    {
        m_nLastColumnIndex = columnIndex;
        return  (**m_pCache->m_aInsertRow)[m_nLastColumnIndex];
    }
    return getValue(columnIndex);
}

OUString SAL_CALL ORowSet::getString( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getString();
}

sal_Bool SAL_CALL ORowSet::getBoolean( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getBool();
}

sal_Int8 SAL_CALL ORowSet::getByte( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getInt8();
}

sal_Int16 SAL_CALL ORowSet::getShort( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getInt16();
}

sal_Int32 SAL_CALL ORowSet::getInt( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getInt32();
}

sal_Int64 SAL_CALL ORowSet::getLong( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getLong();
}

float SAL_CALL ORowSet::getFloat( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getFloat();
}

double SAL_CALL ORowSet::getDouble( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getDouble();
}

Sequence< sal_Int8 > SAL_CALL ORowSet::getBytes( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getSequence();
}

css::util::Date SAL_CALL ORowSet::getDate( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getDate();
}

css::util::Time SAL_CALL ORowSet::getTime( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getTime();
}

css::util::DateTime SAL_CALL ORowSet::getTimestamp( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).getDateTime();
}

Reference< css::io::XInputStream > SAL_CALL ORowSet::getBinaryStream( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    if ( m_pCache && isInsertRow() )
    {
        checkCache();
        m_nLastColumnIndex = columnIndex;
        return new ::comphelper::SequenceInputStream((**m_pCache->m_aInsertRow)[m_nLastColumnIndex].getSequence());
    }

    return ORowSetBase::getBinaryStream(columnIndex);
}

Reference< css::io::XInputStream > SAL_CALL ORowSet::getCharacterStream( sal_Int32 columnIndex )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    if(m_pCache && isInsertRow() )
    {
        checkCache();
        m_nLastColumnIndex = columnIndex;
        return new ::comphelper::SequenceInputStream((**m_pCache->m_aInsertRow)[m_nLastColumnIndex].getSequence());
    }

    return ORowSetBase::getCharacterStream(columnIndex);
}

Any SAL_CALL ORowSet::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& ;/*typeMap*/ )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    return getInsertValue(columnIndex).makeAny();
}

Reference< XRef > SAL_CALL ORowSet::getRef( sal_Int32 /*columnIndex*/ )
{
    return Reference< XRef >();
}

Reference< XBlob > SAL_CALL ORowSet::getBlob( sal_Int32 columnIndex )
{
    if ( m_pCache && isInsertRow() )
    {
        checkCache();
        m_nLastColumnIndex = columnIndex;
        return new ::connectivity::BlobHelper((**m_pCache->m_aInsertRow)[m_nLastColumnIndex].getSequence());
    }
    return ORowSetBase::getBlob(columnIndex);
}

Reference< XClob > SAL_CALL ORowSet::getClob( sal_Int32 columnIndex )
{
    return Reference< XClob >(getInsertValue(columnIndex).makeAny(),UNO_QUERY);
}

Reference< XArray > SAL_CALL ORowSet::getArray( sal_Int32 /*columnIndex*/ )
{
    return Reference< XArray >();
}

void SAL_CALL ORowSet::executeWithCompletion( const Reference< XInteractionHandler >& ;_rxHandler )
{
    if (!_rxHandler.is())
        execute();

    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    // tell everybody that we will change the result set
    approveExecution();

    ResettableMutexGuard aGuard( m_aMutex );

    try
    {
        freeResources( m_bCommandFacetsDirty );

        // calc the connection to be used
        if (m_xActiveConnection.is() && m_bRebuildConnOnExecute)
        {
            // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too
            Reference< XConnection > xXConnection;
            setActiveConnection( xXConnection );
        }
        calcConnection( _rxHandler );
        m_bRebuildConnOnExecute = false;

        Reference< XSingleSelectQueryComposer > xComposer = getCurrentSettingsComposer( this, m_aContext, nullptr );
        Reference<XParametersSupplier>  xParameters(xComposer, UNO_QUERY);

        Reference<XIndexAccess>  xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>();
        const sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0;
        if ( m_aParametersSet.size() < o3tl::make_unsigned(nParamCount) )
            m_aParametersSet.resize( nParamCount ,false);

        ::dbtools::askForParameters( xComposer, this, m_xActiveConnection, _rxHandler,m_aParametersSet );
    }
    // ensure that only the allowed exceptions leave this block
    catch(SQLException&)
    {
        throw;
    }
    catch(RuntimeException&)
    {
        throw;
    }
    catch(Exception const &)
    {
        TOOLS_WARN_EXCEPTION("dbaccess""ORowSet::executeWithCompletion: caught an unexpected exception type while filling in the parameters");
    }

    // we're done with the parameters, now for the real execution

    //  do the real execute
    execute_NoApprove_NoNewConn(aGuard);
}

Reference< XIndexAccess > SAL_CALL ORowSet::getParameters(  )
{
    ::osl::MutexGuard aGuard( *m_pMutex );
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    if ( m_bCommandFacetsDirty )
        // need to rebuild the parameters, since some property which contributes to the
        // complete command, and thus the parameters, changed
        impl_disposeParametersContainer_nothrow();

    if ( !m_pParameters && !m_aCommand.isEmpty() )
    {
        try
        {
            OUString sNotInterestedIn;
            impl_initComposer_throw( sNotInterestedIn );
        }
        catchconst Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("dbaccess");
        }
    }

    // our caller could change our parameters at any time
    m_bParametersDirty = true;

    return m_pParameters;
}

void ORowSet::approveExecution()
{
    ::osl::MutexGuard aGuard( m_aColumnsMutex );
    EventObject aEvt(*this);

    OInterfaceIteratorHelper3 aApproveIter( m_aApproveListeners );
    while ( aApproveIter.hasMoreElements() )
    {
        Reference< XRowSetApproveListener > xListener( aApproveIter.next() );
        try
        {
            if ( !xListener->approveRowSetChange( aEvt ) )
                throw RowSetVetoException();
        }
        catch ( const DisposedException& e )
        {
            if ( e.Context == xListener )
                aApproveIter.remove();
        }
        catch ( const RuntimeException& ) { throw; }
        catch ( const RowSetVetoException& ) { throw; }
        catch ( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION("dbaccess");
        }
    }
}

// XRowSet
void SAL_CALL ORowSet::execute(  )
{
    ::connectivity::checkDisposed(ORowSet_BASE1::rBHelper.bDisposed);

    // tell everybody that we will change the result set
    approveExecution();

    ResettableMutexGuard aGuard( m_aMutex );
    freeResources( m_bCommandFacetsDirty );

    // calc the connection to be used
    if (m_xActiveConnection.is() && m_bRebuildConnOnExecute) {
        // there was a setProperty(ActiveConnection), but a setProperty(DataSource) _after_ that, too
        Reference< XConnection> xXConnection;
        setActiveConnection( xXConnection );
    }

    calcConnection(nullptr);
    m_bRebuildConnOnExecute = false;

    // do the real execute
    execute_NoApprove_NoNewConn(aGuard);
}

void ORowSet::setStatementResultSetType( const Reference< XPropertySet >& _rxStatement, sal_Int32 _nDesiredResultSetType, sal_Int32 _nDesiredResultSetConcurrency )
{
    OSL_ENSURE( _rxStatement.is(), "ORowSet::setStatementResultSetType: invalid statement - this will crash!" );

    sal_Int32 nResultSetType( _nDesiredResultSetType );
    sal_Int32 nResultSetConcurrency( _nDesiredResultSetConcurrency );

    // there *might* be a data source setting which tells use to be more defensive with those settings
    // #i15113#
    bool bRespectDriverRST = false;
    Any aSetting;
    if (getDataSourceSetting(::dbaccess::getDataSource(m_xActiveConnection), u"RespectDriverResultSetType"_ustr, aSetting))
    {
        OSL_VERIFY( aSetting >>= bRespectDriverRST );
    }

    if ( bRespectDriverRST )
    {
        // try type/concurrency settings with decreasing usefulness, and rely on what the connection claims
        // to support
        Reference< XDatabaseMetaData > xMeta( m_xActiveConnection->getMetaData() );

        sal_Int32 nCharacteristics[5][2] =
        {   { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::UPDATABLE },
            { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::UPDATABLE },
            { ResultSetType::SCROLL_SENSITIVE, ResultSetConcurrency::READ_ONLY },
            { ResultSetType::SCROLL_INSENSITIVE, ResultSetConcurrency::READ_ONLY },
            { ResultSetType::FORWARD_ONLY, ResultSetConcurrency::READ_ONLY }
        };
        sal_Int32 i=0;
        if ( m_xActiveConnection->getMetaData()->isReadOnly() )
            i = 2; // if the database is read-only we only should use read-only concurrency

        for ( ; i<5; ++i )
        {
            nResultSetType = nCharacteristics[i][0];
            nResultSetConcurrency = nCharacteristics[i][1];

            // don't try type/concurrency pairs which are more featured than what our caller requested
            if ( nResultSetType > _nDesiredResultSetType )
                continue;
            if ( nResultSetConcurrency > _nDesiredResultSetConcurrency )
                continue;

            if ( xMeta.is() && xMeta->supportsResultSetConcurrency( nResultSetType, nResultSetConcurrency ) )
                break;
        }
    }

    _rxStatement->setPropertyValue( PROPERTY_RESULTSETTYPE, Any( nResultSetType ) );
    _rxStatement->setPropertyValue( PROPERTY_RESULTSETCONCURRENCY, Any( nResultSetConcurrency ) );
}

void ORowSet::impl_ensureStatement_throw()
{
    OUString sCommandToExecute;
    if(m_bCommandFacetsDirty)
    {
        impl_initComposer_throw( sCommandToExecute );
    }
    else
    {
        sCommandToExecute = m_bUseEscapeProcessing ? m_xComposer->getQueryWithSubstitution() : m_aActiveCommand;
    }

    try
    {
        m_xStatement = m_xActiveConnection->prepareStatement( sCommandToExecute );
        if ( !m_xStatement.is() )
        {
            ::dbtools::throwSQLException( DBA_RES( RID_STR_INTERNAL_ERROR ), StandardSQLState::GENERAL_ERROR, *this );
        }

        Reference< XPropertySet > xStatementProps( m_xStatement, UNO_QUERY_THROW );
        // set the result set type and concurrency
        try
        {
            xStatementProps->setPropertyValue( PROPERTY_USEBOOKMARKS, Any( true ) );
            xStatementProps->setPropertyValue( PROPERTY_MAXROWS, Any( m_nMaxRows ) );

            setStatementResultSetType( xStatementProps, m_nResultSetType, m_nResultSetConcurrency );
        }
        catch ( const Exception& )
        {
            // this exception doesn't matter here because when we catch an exception
            // then the driver doesn't support this feature
        }
    }
    catch (SQLException& rException)
    {
        css::sdbc::SQLException* pLastExceptionInChain = SQLExceptionInfo::getLastException(&rException);
        assert(pLastExceptionInChain && "will at least be &rException");

        // append information about what we were actually going to execute
        OUString sInfo(m_sErrorString.replaceFirst("$command$", sCommandToExecute));
        pLastExceptionInChain->NextException = SQLExceptionInfo::createException(SQLExceptionInfo::TYPE::SQLContext, sInfo, OUString(), 0);

        // propagate
        throw;
    }
}

Reference< XResultSet > ORowSet::impl_prepareAndExecute_throw()
{
    impl_ensureStatement_throw();

    m_aParameterValueForCache->resize(1);
    Reference< XParameters > xParam( m_xStatement, UNO_QUERY_THROW );
    size_t nParamCount( m_pParameters.is() ? m_pParameters->size() : m_aPrematureParamValues->size() );
    for ( size_t i=1; i<=nParamCount; ++i )
    {
        ORowSetValue& rParamValue( getParameterStorage( static_cast<sal_Int32>(i) ) );
        ::dbtools::setObjectWithInfo( xParam, i, rParamValue.makeAny(), rParamValue.getTypeKind() );
        m_aParameterValueForCache->push_back(rParamValue);
    }
    m_bParametersDirty = false;

    Reference< XResultSet > xResultSet(m_xStatement->executeQuery());

    OUString aComposedUpdateTableName;
    if ( !m_aUpdateTableName.isEmpty() )
        aComposedUpdateTableName = composeTableName( m_xActiveConnection->getMetaData(), m_aUpdateCatalogName, m_aUpdateSchemaName, m_aUpdateTableName, false, ::dbtools::EComposeRule::InDataManipulation );

    SAL_INFO("dbaccess""ORowSet::impl_prepareAndExecute_throw: creating cache" );
    m_pCache =
        std::make_shared<ORowSetCache>(xResultSet, m_xComposer.get(), m_aContext, aComposedUpdateTableName,
               m_bModified, m_bNew, *m_aParameterValueForCache, m_aFilter, m_nMaxRows);
    if ( m_nResultSetConcurrency == ResultSetConcurrency::READ_ONLY )
    {
        m_nPrivileges = Privilege::SELECT;
        m_pCache->m_nPrivileges = Privilege::SELECT;
    }
    m_pCache->setFetchSize(m_nFetchSize);
    m_aCurrentRow   = m_pCache->createIterator(this);
    m_bIsInsertRow  = false;
    m_aOldRow       = m_pCache->registerOldRow();

    return xResultSet;
}

void ORowSet::impl_initializeColumnSettings_nothrow( const Reference< XPropertySet >&&nbsp;_rxTemplateColumn, const Reference< XPropertySet >& _rxRowSetColumn )
{
    OSL_ENSURE( _rxTemplateColumn.is() && _rxRowSetColumn.is(),
        "ORowSet::impl_initializeColumnSettings_nothrow: this will crash!" );

    bool bHaveAnyColumnSetting = false;
    try
    {
        Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_SET_THROW );

        // a number of properties is plain copied
        const OUString aPropertyNames[] = {
            PROPERTY_ALIGN, PROPERTY_RELATIVEPOSITION, PROPERTY_WIDTH, PROPERTY_HIDDEN, PROPERTY_CONTROLMODEL,
            PROPERTY_HELPTEXT, PROPERTY_CONTROLDEFAULT
        };
        for (const auto & aPropertyName : aPropertyNames)
        {
            if ( xInfo->hasPropertyByName( aPropertyName ) )
            {
                _rxRowSetColumn->setPropertyValue( aPropertyName, _rxTemplateColumn->getPropertyValue( aPropertyName ) );
                bHaveAnyColumnSetting = true;
            }
        }

        // the format key is slightly more complex
        sal_Int32 nFormatKey = 0;
        if( xInfo->hasPropertyByName( PROPERTY_NUMBERFORMAT ) )
        {
            _rxTemplateColumn->getPropertyValue( PROPERTY_NUMBERFORMAT ) >>= nFormatKey;
            bHaveAnyColumnSetting = true;
        }
        if ( !nFormatKey && m_xNumberFormatTypes.is() )
            nFormatKey = ::dbtools::getDefaultNumberFormat( _rxTemplateColumn, m_xNumberFormatTypes, SvtSysLocale().GetLanguageTag().getLocale() );
        _rxRowSetColumn->setPropertyValue( PROPERTY_NUMBERFORMAT, Any( nFormatKey ) );
    }
    catch(Exception&)
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
        return;
    }

    if ( bHaveAnyColumnSetting )
        return;

    // the template column could not provide *any* setting. Okay, probably it's a parser column, which
    // does not offer those. However, perhaps the template column refers to a table column, which we
    // can use as new template column
    try
    {
        Reference< XPropertySetInfo > xInfo( _rxTemplateColumn->getPropertySetInfo(), UNO_SET_THROW );
        if ( !xInfo->hasPropertyByName( PROPERTY_TABLENAME ) )
            // no chance
            return;

        OUString sTableName;
        OSL_VERIFY( _rxTemplateColumn->getPropertyValue( PROPERTY_TABLENAME ) >>= sTableName );

        Reference< XNameAccess > xTables( impl_getTables_throw(), UNO_SET_THROW );
        if ( !xTables->hasByName( sTableName ) )
            // no chance
            return;

        Reference< XColumnsSupplier > xTableColSup( xTables->getByName( sTableName ), UNO_QUERY_THROW );
        Reference< XNameAccess > xTableCols( xTableColSup->getColumns(), UNO_SET_THROW );

        OUString sTableColumnName;

        // get the "Name" or (preferred) "RealName" property of the column
        OUString sNamePropertyName( PROPERTY_NAME );
        if ( xInfo->hasPropertyByName( PROPERTY_REALNAME ) )
            sNamePropertyName = PROPERTY_REALNAME;
        OSL_VERIFY( _rxTemplateColumn->getPropertyValue( sNamePropertyName ) >>= sTableColumnName );

        if ( !xTableCols->hasByName( sTableColumnName ) )
            return;

        Reference< XPropertySet > xTableColumn( xTableCols->getByName( sTableColumnName ), UNO_QUERY_THROW );
        impl_initializeColumnSettings_nothrow( xTableColumn, _rxRowSetColumn );
    }
    catchconst Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("dbaccess");
    }
}

void ORowSet::execute_NoApprove_NoNewConn(ResettableMutexGuard& _rClearForNotification)
{
    // now we can dispose our old connection
    ::comphelper::disposeComponent(m_xOldConnection);
    m_xOldConnection = nullptr;

    // do we need a new statement
    if ( m_bCommandFacetsDirty )
    {
        m_xStatement    = nullptr;
        m_xComposer     = nullptr;

        Reference< XResultSet > xResultSet( impl_prepareAndExecute_throw() );

        // let our warnings container forget the reference to the (possibly disposed) old result set
        m_aWarnings.setExternalWarnings( nullptr );
        // clear all current warnings
        m_aWarnings.clearWarnings();
        // let the warnings container know about the new "external warnings"
        m_aWarnings.setExternalWarnings( Reference< XWarningsSupplier >( xResultSet, UNO_QUERY ) );

        // get the locale
        Locale aLocale = SvtSysLocale().GetLanguageTag().getLocale();

        // get the numberformatTypes
        OSL_ENSURE(m_xActiveConnection.is(),"No ActiveConnection");
        Reference< XNumberFormatsSupplier> xNumberFormat = ::dbtools::getNumberFormats(m_xActiveConnection);
        if ( xNumberFormat.is() )
            m_xNumberFormatTypes.set(xNumberFormat->getNumberFormats(),UNO_QUERY);

--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.20 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.