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

Quelle  cachedcontentresultsetstub.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 "cachedcontentresultsetstub.hxx"
#include <com/sun/star/sdbc/FetchDirection.hpp>
#include <com/sun/star/sdbc/SQLException.hpp>
#include <com/sun/star/ucb/FetchError.hpp>
#include <osl/diagnose.h>
#include <cppuhelper/queryinterface.hxx>
#include <ucbhelper/macros.hxx>

using namespace com::sun::star::beans;
using namespace com::sun::star::lang;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;
using namespace cppu;


CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > const &&nbsp;xOrigin )
                : ContentResultSetWrapper( xOrigin )
                , m_nColumnCount( 0 )
                , m_bColumnCountCached( false )
                , m_bNeedToPropagateFetchSize( true )
                , m_bFirstFetchSizePropagationDone( false )
                , m_nLastFetchSize( 1 )//this value is not important at all
                , m_bLastFetchDirection( true )//this value is not important at all
                , m_aPropertyNameForFetchSize( u"FetchSize"_ustr )
                , m_aPropertyNameForFetchDirection( u"FetchDirection"_ustr )
{
    impl_init();
}

CachedContentResultSetStub::~CachedContentResultSetStub()
{
    impl_deinit();
}


// XInterface methods.
void SAL_CALL CachedContentResultSetStub::acquire()
    noexcept
{
    OWeakObject::acquire();
}

void SAL_CALL CachedContentResultSetStub::release()
    noexcept
{
    OWeakObject::release();
}

Any SAL_CALL CachedContentResultSetStub
    ::queryInterface( const Type&  rType )
{
    //list all interfaces inclusive baseclasses of interfaces

    Any aRet = ContentResultSetWrapper::queryInterface( rType );
    if( aRet.hasValue() )
        return aRet;

    aRet = cppu::queryInterface( rType
                , static_cast< XTypeProvider* >( this )
                , static_cast< XServiceInfo* >( this )
                , static_cast< XFetchProvider* >( this )
                , static_cast< XFetchProviderForContentAccess* >( this )
                );

    return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}


// own methods.  ( inherited )


//virtual, only called from ContentResultSetWrapperListener
void CachedContentResultSetStub
    ::impl_propertyChange( const PropertyChangeEvent& rEvt )
{
    std::unique_lock aGuard(m_aMutex);
    impl_EnsureNotDisposed(aGuard);

    //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
    //because it will ignore them anyway and we can save this remote calls
    if(    rEvt.PropertyName == m_aPropertyNameForFetchSize
        || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
        return;

    PropertyChangeEvent aEvt( rEvt );
    aEvt.Source = static_cast< XPropertySet * >( this );
    aEvt.Further = false;

    impl_notifyPropertyChangeListeners( aGuard, aEvt );
}


//virtual, only called from ContentResultSetWrapperListener
void CachedContentResultSetStub
    ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
{
    std::unique_lock aGuard(m_aMutex);
    impl_EnsureNotDisposed(aGuard);

    //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
    //because it will ignore them anyway and we can save this remote calls
    if(    rEvt.PropertyName == m_aPropertyNameForFetchSize
        || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
        return;

    PropertyChangeEvent aEvt( rEvt );
    aEvt.Source = static_cast< XPropertySet * >( this );
    aEvt.Further = false;

    impl_notifyVetoableChangeListeners( aGuard, aEvt );
}


// XTypeProvider methods.


XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
//list all interfaces exclusive baseclasses
Sequence< Type > SAL_CALL CachedContentResultSetStub
    ::getTypes()
{
    static Sequence<Type> ourTypes(
                {   CPPU_TYPE_REF( XTypeProvider ),
                    CPPU_TYPE_REF( XServiceInfo ),
                    CPPU_TYPE_REF( XComponent ),
                    CPPU_TYPE_REF( XCloseable ),
                    CPPU_TYPE_REF( XResultSetMetaDataSupplier ),
                    CPPU_TYPE_REF( XPropertySet ),
                    CPPU_TYPE_REF( XPropertyChangeListener ),
                    CPPU_TYPE_REF( XVetoableChangeListener ),
                    CPPU_TYPE_REF( XResultSet ),
                    CPPU_TYPE_REF( XContentAccess ),
                    CPPU_TYPE_REF( XRow ),
                    CPPU_TYPE_REF( XFetchProvider ),
                    CPPU_TYPE_REF( XFetchProviderForContentAccess ) } );

    return ourTypes;
}


// XServiceInfo methods.

OUString SAL_CALL CachedContentResultSetStub::getImplementationName()
{
    return u"com.sun.star.comp.ucb.CachedContentResultSetStub"_ustr;
}

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

css::uno::Sequence< OUString > SAL_CALL CachedContentResultSetStub::getSupportedServiceNames()
{
    return { u"com.sun.star.ucb.CachedContentResultSetStub"_ustr };
}



// XFetchProvider methods.


FetchResult CachedContentResultSetStub::impl_fetchHelper(
        std::unique_lock<std::mutex>& rGuard,
        sal_Int32 nRowStartPosition, sal_Int32 nRowCount, bool bDirection,
        std::function<void( std::unique_lock<std::mutex>&, css::uno::Any& rRowContent)> impl_loadRow)
{
    impl_EnsureNotDisposed(rGuard);
    if( !m_xResultSetOrigin.is() )
    {
        OSL_FAIL( "broadcaster was disposed already" );
        throw RuntimeException();
    }
    impl_propagateFetchSizeAndDirection( rGuard, nRowCount, bDirection );
    FetchResult aRet;
    aRet.StartIndex = nRowStartPosition;
    aRet.Orientation = bDirection;
    aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/
    sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow();
    if( impl_isForwardOnly(rGuard) )
    {
        if( nOldOriginal_Pos != nRowStartPosition )
        {
            /*@todo*/
            aRet.FetchError = FetchError::EXCEPTION;
            return aRet;
        }
        if( nRowCount != 1 )
            aRet.FetchError = FetchError::EXCEPTION;

        aRet.Rows.realloc( 1 );

        try
        {
            impl_loadRow( rGuard, aRet.Rows.getArray()[0] );
        }
        catch( SQLException& )
        {
            aRet.Rows.realloc( 0 );
            aRet.FetchError = FetchError::EXCEPTION;
            return aRet;
        }
        return aRet;
    }
    aRet.Rows.realloc( nRowCount );
    auto pRows = aRet.Rows.getArray();
    bool bOldOriginal_AfterLast = false;
    if( !nOldOriginal_Pos )
        bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast();
    sal_Int32 nN = 1;
    try
    {
        bool bValidNewPos = false;
        try
        {
            /*if( nOldOriginal_Pos != nRowStartPosition )*/
            bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition );
        }
        catch( SQLException& )
        {
            aRet.Rows.realloc( 0 );
            aRet.FetchError = FetchError::EXCEPTION;
            return aRet;
        }
        if( !bValidNewPos )
        {
            aRet.Rows.realloc( 0 );
            aRet.FetchError = FetchError::EXCEPTION;

            /*restore old position*/
            if( nOldOriginal_Pos )
                m_xResultSetOrigin->absolute( nOldOriginal_Pos );
            else if( bOldOriginal_AfterLast )
                m_xResultSetOrigin->afterLast();
            else
                m_xResultSetOrigin->beforeFirst();

            return aRet;
        }
        for( ; nN <= nRowCount; )
        {
            impl_loadRow( rGuard, pRows[nN-1] );
            nN++;
            if( nN <= nRowCount )
            {
                if( bDirection )
                {
                    if( !m_xResultSetOrigin->next() )
                    {
                        aRet.Rows.realloc( nN-1 );
                        aRet.FetchError = FetchError::ENDOFDATA;
                        break;
                    }
                }
                else
                {
                    if( !m_xResultSetOrigin->previous() )
                    {
                        aRet.Rows.realloc( nN-1 );
                        aRet.FetchError = FetchError::ENDOFDATA;
                        break;
                    }
                }
            }
        }
    }
    catch( SQLException& )
    {
        aRet.Rows.realloc( nN-1 );
        aRet.FetchError = FetchError::EXCEPTION;
    }
    /*restore old position*/
    if( nOldOriginal_Pos )
        m_xResultSetOrigin->absolute( nOldOriginal_Pos );
    else if( bOldOriginal_AfterLast )
        m_xResultSetOrigin->afterLast();
    else
        m_xResultSetOrigin->beforeFirst();
    return aRet;
}

FetchResult SAL_CALL CachedContentResultSetStub
    ::fetch( sal_Int32 nRowStartPosition
    , sal_Int32 nRowCount, sal_Bool bDirection )
{
    std::unique_lock aGuard(m_aMutex);
    impl_init_xRowOrigin(aGuard);
    return impl_fetchHelper( aGuard, nRowStartPosition, nRowCount, bDirection,
        [&](std::unique_lock<std::mutex>& rGuard, css::uno::Any& rRowContent)
        { return impl_getCurrentRowContent(rGuard, rRowContent, m_xRowOrigin); });
}

sal_Int32 CachedContentResultSetStub
    ::impl_getColumnCount(std::unique_lock<std::mutex>& /*rGuard*/)
{
    sal_Int32 nCount;
    bool bCached;
    nCount = m_nColumnCount;
    bCached = m_bColumnCountCached;
    if( !bCached )
    {
        try
        {
            Reference< XResultSetMetaData > xMetaData = getMetaData();
            if( xMetaData.is() )
                nCount = xMetaData->getColumnCount();
        }
        catch( SQLException& )
        {
            OSL_FAIL( "couldn't determine the column count" );
            nCount = 0;
        }
    }
    m_nColumnCount = nCount;
    m_bColumnCountCached = true;
    return m_nColumnCount;
}

void CachedContentResultSetStub
    ::impl_getCurrentRowContent( std::unique_lock<std::mutex>& rGuard, Any& rRowContent
        , const Reference< XRow >& xRow )
{
    sal_Int32 nCount = impl_getColumnCount(rGuard);

    Sequence< Any > aContent( nCount );
    auto aContentRange = asNonConstRange(aContent);
    for( sal_Int32 nN = 1; nN <= nCount; nN++ )
    {
        aContentRange[nN-1] = xRow->getObject( nN, nullptr );
    }

    rRowContent <<= aContent;
}

void CachedContentResultSetStub
    ::impl_propagateFetchSizeAndDirection( std::unique_lock<std::mutex>& rGuard, sal_Int32 nFetchSize, bool bFetchDirection )
{
    //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResultSets

    //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls

    //if the underlying ResultSet has a property FetchSize and FetchDirection,
    //we will set these properties, if the new given parameters are different from the last ones

    if( !m_bNeedToPropagateFetchSize )
        return;

    sal_Int32 nLastSize;
    bool bLastDirection;
    bool bFirstPropagationDone;
    nLastSize               = m_nLastFetchSize;
    bLastDirection          = m_bLastFetchDirection;
    bFirstPropagationDone   = m_bFirstFetchSizePropagationDone;

    if( nLastSize == nFetchSize
        && bLastDirection == bFetchDirection
        && bFirstPropagationDone )
        return;

    if(!bFirstPropagationDone)
    {
        //check whether the properties 'FetchSize' and 'FetchDirection' do exist

        Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfoImpl(rGuard);
        bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
        bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );

        if(!bHasSize || !bHasDirection)
        {
            m_bNeedToPropagateFetchSize = false;
            return;
        }
    }

    bool bSetSize       = ( nLastSize       !=nFetchSize        ) || !bFirstPropagationDone;
    bool bSetDirection  = ( bLastDirection  !=bFetchDirection   ) || !bFirstPropagationDone;

    m_bFirstFetchSizePropagationDone = true;
    m_nLastFetchSize        = nFetchSize;
    m_bLastFetchDirection   = bFetchDirection;

    if( bSetSize )
    {
        Any aValue;
        aValue <<= nFetchSize;
        try
        {
            setPropertyValueImpl( rGuard, m_aPropertyNameForFetchSize, aValue );
        }
        catch( css::uno::Exception& ) {}
    }
    if( !bSetDirection )
        return;

    sal_Int32 nFetchDirection = FetchDirection::FORWARD;
    if( !bFetchDirection )
        nFetchDirection = FetchDirection::REVERSE;
    Any aValue;
    aValue <<= nFetchDirection;
    try
    {
        setPropertyValueImpl( rGuard, m_aPropertyNameForFetchDirection, aValue );
    }
    catch( css::uno::Exception& ) {}
}


// XFetchProviderForContentAccess methods.


void CachedContentResultSetStub
    ::impl_getCurrentContentIdentifierString( std::unique_lock<std::mutex>& /*rGuard*/, Any& rAny
        , const Reference< XContentAccess >& xContentAccess )
{
     rAny <<= xContentAccess->queryContentIdentifierString();
}

void CachedContentResultSetStub
    ::impl_getCurrentContentIdentifier( std::unique_lock<std::mutex>& /*rGuard*/, Any&&nbsp;rAny
        , const Reference< XContentAccess >& xContentAccess )
{
     rAny <<= xContentAccess->queryContentIdentifier();
}

void CachedContentResultSetStub
    ::impl_getCurrentContent( std::unique_lock<std::mutex>& /*rGuard*/, Any& rAny
        , const Reference< XContentAccess >& xContentAccess )
{
     rAny <<= xContentAccess->queryContent();
}

//virtual
FetchResult SAL_CALL CachedContentResultSetStub
    ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
        , sal_Int32 nRowCount, sal_Bool bDirection )
{
    std::unique_lock aGuard( m_aMutex );
    impl_init_xContentAccessOrigin(aGuard);
    return impl_fetchHelper( aGuard, nRowStartPosition, nRowCount, bDirection,
        [&](std::unique_lock<std::mutex>& rGuard, css::uno::Any& rRowContent)
        { return impl_getCurrentContentIdentifierString(rGuard, rRowContent, m_xContentAccessOrigin); });
}

//virtual
FetchResult SAL_CALL CachedContentResultSetStub
    ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
        , sal_Int32 nRowCount, sal_Bool bDirection )
{
    std::unique_lock aGuard( m_aMutex );
    impl_init_xContentAccessOrigin(aGuard);
    return impl_fetchHelper( aGuard, nRowStartPosition, nRowCount, bDirection,
        [&](std::unique_lock<std::mutex>& rGuard, css::uno::Any& rRowContent)
        { return impl_getCurrentContentIdentifier(rGuard, rRowContent, m_xContentAccessOrigin); });
}

//virtual
FetchResult SAL_CALL CachedContentResultSetStub
    ::fetchContents( sal_Int32 nRowStartPosition
        , sal_Int32 nRowCount, sal_Bool bDirection )
{
    std::unique_lock aGuard( m_aMutex );
    impl_init_xContentAccessOrigin(aGuard);
    return impl_fetchHelper( aGuard, nRowStartPosition, nRowCount, bDirection,
        [&](std::unique_lock<std::mutex>& rGuard, css::uno::Any& rRowContent)
        { return impl_getCurrentContent(rGuard, rRowContent, m_xContentAccessOrigin); });
}




CachedContentResultSetStubFactory::CachedContentResultSetStubFactory()
{
}

CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
{
}


// CachedContentResultSetStubFactory XServiceInfo methods.

OUString SAL_CALL CachedContentResultSetStubFactory::getImplementationName()
{
    return u"com.sun.star.comp.ucb.CachedContentResultSetStubFactory"_ustr;
}
sal_Bool SAL_CALL CachedContentResultSetStubFactory::supportsService( const OUString&&nbsp;ServiceName )
{
    return cppu::supportsService( this, ServiceName );
}
css::uno::Sequence< OUString > SAL_CALL CachedContentResultSetStubFactory::getSupportedServiceNames()
{
    return { u"com.sun.star.ucb.CachedContentResultSetStubFactory"_ustr };
}

// Service factory implementation.


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




// CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.


    //virtual
Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
    ::createCachedContentResultSetStub(
            const Reference< XResultSet > & xSource )
{
    if( xSource.is() )
    {
        Reference< XResultSet > xRet = new CachedContentResultSetStub( xSource );
        return xRet;
    }
    return nullptr;
}


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.6 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.