1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "cachedcontentresultset.hxx"
22 #include <com/sun/star/sdbc/FetchDirection.hpp>
23 #include <com/sun/star/sdbc/SQLException.hpp>
24 #include <com/sun/star/ucb/FetchError.hpp>
25 #include <com/sun/star/beans/PropertyAttribute.hpp>
26 #include <com/sun/star/script/CannotConvertException.hpp>
27 #include <com/sun/star/script/Converter.hpp>
28 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
29 #include <rtl/ustring.hxx>
30 #include <o3tl/any.hxx>
31 #include <osl/diagnose.h>
32 #include <cppuhelper/exc_hlp.hxx>
33 #include <cppuhelper/queryinterface.hxx>
34 #include <ucbhelper/macros.hxx>
36 #include <string_view>
38 using namespace com::sun::star::beans
;
39 using namespace com::sun::star::lang
;
40 using namespace com::sun::star::script
;
41 using namespace com::sun::star::sdbc
;
42 using namespace com::sun::star::ucb
;
43 using namespace com::sun::star::uno
;
44 using namespace com::sun::star::util
;
48 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
49 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
51 //if you change this function template please pay attention to
52 //function getObject, where this is similar implemented
54 template<typename T
> T
CachedContentResultSet::rowOriginGet(
55 T (SAL_CALL
css::sdbc::XRow::* f
)(sal_Int32
), sal_Int32 columnIndex
)
57 std::unique_lock
aGuard(m_aMutex
);
58 impl_EnsureNotDisposed(aGuard
);
59 sal_Int32 nRow
= m_nRow
;
60 sal_Int32 nFetchSize
= m_nFetchSize
;
61 sal_Int32 nFetchDirection
= m_nFetchDirection
;
62 if( !m_aCache
.hasRow( nRow
) )
64 if( !m_aCache
.hasCausedException( nRow
) )
66 if( !m_xFetchProvider
.is() )
68 OSL_FAIL( "broadcaster was disposed already" );
71 if( impl_isForwardOnly(aGuard
) )
72 applyPositionToOrigin( aGuard
, nRow
);
74 impl_fetchData( aGuard
, nRow
, nFetchSize
, nFetchDirection
);
76 if( !m_aCache
.hasRow( nRow
) )
78 m_bLastReadWasFromCache
= false;
79 applyPositionToOrigin( aGuard
, nRow
);
80 impl_init_xRowOrigin(aGuard
);
82 return (m_xRowOrigin
.get()->*f
)( columnIndex
);
85 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
87 m_bLastReadWasFromCache
= true;
88 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
89 /* Last chance. Try type converter service... */
90 if ( m_bLastCachedReadWasNull
&& rValue
.hasValue() )
92 Reference
< XTypeConverter
> xConverter
= getTypeConverter(aGuard
);
93 if ( xConverter
.is() )
97 Any aConvAny
= xConverter
->convertTo(
99 cppu::UnoType
<T
>::get() );
100 m_bLastCachedReadWasNull
= !( aConvAny
>>= aRet
);
102 catch (const IllegalArgumentException
&)
105 catch (const CannotConvertException
&)
114 // CCRS_Cache methods
117 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
118 const Reference
< XContentIdentifierMapping
> & xMapping
)
119 : m_xContentIdentifierMapping( xMapping
)
123 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
127 void CachedContentResultSet::CCRS_Cache
131 m_pMappedReminder
.reset();
134 void CachedContentResultSet::CCRS_Cache
135 ::loadData( const FetchResult
& rResult
)
141 bool CachedContentResultSet::CCRS_Cache
142 ::hasRow( sal_Int32 row
) const
146 sal_Int32 nStart
= m_pResult
->StartIndex
;
147 sal_Int32 nEnd
= nStart
;
148 if( m_pResult
->Orientation
)
149 nEnd
+= m_pResult
->Rows
.getLength() - 1;
151 nStart
-= m_pResult
->Rows
.getLength() + 1;
153 return nStart
<= row
&& row
<= nEnd
;
156 sal_Int32
CachedContentResultSet::CCRS_Cache
161 sal_Int32 nEnd
= m_pResult
->StartIndex
;
162 if( m_pResult
->Orientation
)
163 return nEnd
+ m_pResult
->Rows
.getLength() - 1;
168 bool CachedContentResultSet::CCRS_Cache
169 ::hasKnownLast() const
174 return ( m_pResult
->FetchError
& FetchError::ENDOFDATA
)
175 && m_pResult
->Orientation
176 && m_pResult
->Rows
.hasElements();
179 bool CachedContentResultSet::CCRS_Cache
180 ::hasCausedException( sal_Int32 nRow
) const
184 if( !( m_pResult
->FetchError
& FetchError::EXCEPTION
) )
187 sal_Int32 nEnd
= m_pResult
->StartIndex
;
188 if( m_pResult
->Orientation
)
189 nEnd
+= m_pResult
->Rows
.getLength();
191 return nRow
== nEnd
+1;
194 Any
& CachedContentResultSet::CCRS_Cache
195 ::getRowAny( sal_Int32 nRow
)
198 throw SQLException();
200 throw SQLException();
201 if( !hasRow( nRow
) )
202 throw SQLException();
204 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
208 return m_pResult
->Rows
.getArray()[nDiff
];
211 void CachedContentResultSet::CCRS_Cache
212 ::remindMapped( sal_Int32 nRow
)
214 //remind that this row was mapped
217 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
220 Sequence
< sal_Bool
>& rMappedReminder
= getMappedReminder();
221 if( nDiff
< rMappedReminder
.getLength() )
223 sal_Bool
* pMappedReminder
= rMappedReminder
.getArray();
224 pMappedReminder
[nDiff
] = true;
228 bool CachedContentResultSet::CCRS_Cache
229 ::isRowMapped( sal_Int32 nRow
)
231 if( !m_pMappedReminder
|| !m_pResult
)
233 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
236 if( nDiff
< m_pMappedReminder
->getLength() )
237 return (*m_pMappedReminder
)[nDiff
];
241 Sequence
< sal_Bool
>& CachedContentResultSet::CCRS_Cache
242 ::getMappedReminder()
244 if( !m_pMappedReminder
)
246 sal_Int32 nCount
= m_pResult
->Rows
.getLength();
247 m_pMappedReminder
.emplace( nCount
);
248 std::fill_n(m_pMappedReminder
->getArray(), m_pMappedReminder
->getLength(), false);
250 return *m_pMappedReminder
;
253 const Any
& CachedContentResultSet::CCRS_Cache
254 ::getAny( sal_Int32 nRow
, sal_Int32 nColumnIndex
)
257 throw SQLException();
258 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
260 Any
& rRow
= getRowAny( nRow
);
261 Sequence
< Any
> aValue
;
263 if( m_xContentIdentifierMapping
->mapRow( aValue
) )
266 remindMapped( nRow
);
269 m_xContentIdentifierMapping
.clear();
271 auto & rowAny
= getRowAny(nRow
);
272 auto rRow
= o3tl::doAccess
<Sequence
<Any
>>(rowAny
);
274 if( nColumnIndex
> rRow
->getLength() )
275 throw SQLException();
276 return (*rRow
)[nColumnIndex
-1];
279 OUString
const & CachedContentResultSet::CCRS_Cache
280 ::getContentIdentifierString( sal_Int32 nRow
)
284 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
286 Any
& rRow
= getRowAny( nRow
);
289 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifierString( aValue
);
290 remindMapped( nRow
);
292 return *o3tl::doAccess
<OUString
>(getRowAny(nRow
));
294 catch(const SQLException
& ex
)
296 css::uno::Any anyEx
= cppu::getCaughtException();
297 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
298 css::uno::Reference
< css::uno::XInterface
>(),
303 Reference
< XContentIdentifier
> CachedContentResultSet::CCRS_Cache
304 ::getContentIdentifier( sal_Int32 nRow
)
308 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
310 Any
& rRow
= getRowAny( nRow
);
311 Reference
< XContentIdentifier
> aValue
;
313 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifier( aValue
);
314 remindMapped( nRow
);
316 return *o3tl::doAccess
<Reference
<XContentIdentifier
>>(getRowAny(nRow
));
318 catch(const SQLException
& ex
)
320 css::uno::Any anyEx
= cppu::getCaughtException();
321 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
322 css::uno::Reference
< css::uno::XInterface
>(),
327 Reference
< XContent
> CachedContentResultSet::CCRS_Cache
328 ::getContent( sal_Int32 nRow
)
332 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
334 Any
& rRow
= getRowAny( nRow
);
335 Reference
< XContent
> aValue
;
337 rRow
<<= m_xContentIdentifierMapping
->mapContent( aValue
);
338 remindMapped( nRow
);
340 return *o3tl::doAccess
<Reference
<XContent
>>(getRowAny(nRow
));
342 catch (const SQLException
& ex
)
344 css::uno::Any anyEx
= cppu::getCaughtException();
345 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
346 css::uno::Reference
< css::uno::XInterface
>(),
354 class CCRS_PropertySetInfo
:
355 public cppu::OWeakObject
,
356 public css::lang::XTypeProvider
,
357 public css::beans::XPropertySetInfo
359 friend class CachedContentResultSet
;
362 std::optional
<Sequence
< css::beans::Property
>>
365 sal_Int32 m_nFetchSizePropertyHandle
;
366 sal_Int32 m_nFetchDirectionPropertyHandle
;
370 impl_getRemainedHandle() const;
374 std::u16string_view rName
375 , css::beans::Property
& rProp
) const;
377 impl_getPos( std::u16string_view rName
) const;
380 impl_isMyPropertyName( std::u16string_view rName
);
383 explicit CCRS_PropertySetInfo( Reference
<
384 XPropertySetInfo
> const & xPropertySetInfoOrigin
);
387 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
) override
;
388 virtual void SAL_CALL
acquire()
390 virtual void SAL_CALL
release()
394 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
395 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes() override
;
398 virtual Sequence
< css::beans::Property
> SAL_CALL
399 getProperties() override
;
401 virtual css::beans::Property SAL_CALL
402 getPropertyByName( const OUString
& aName
) override
;
404 virtual sal_Bool SAL_CALL
405 hasPropertyByName( const OUString
& Name
) override
;
408 //some helping variables ( names for my special properties )
409 const char16_t g_sPropertyNameForCount
[] = u
"RowCount";
410 const char16_t g_sPropertyNameForFinalCount
[] = u
"IsRowCountFinal";
411 constexpr OUStringLiteral
g_sPropertyNameForFetchSize(u
"FetchSize");
412 constexpr OUStringLiteral
g_sPropertyNameForFetchDirection(u
"FetchDirection");
414 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
415 Reference
< XPropertySetInfo
> const & xInfo
)
416 : m_nFetchSizePropertyHandle( -1 )
417 , m_nFetchDirectionPropertyHandle( -1 )
419 //initialize list of properties:
421 // it is required, that the received xInfo contains the two
422 // properties with names 'g_sPropertyNameForCount' and
423 // 'g_sPropertyNameForFinalCount'
427 m_xProperties
= xInfo
->getProperties();
431 OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
432 m_xProperties
.emplace();
435 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
436 sal_Int32 nFetchSize
= impl_getPos( g_sPropertyNameForFetchSize
);
437 sal_Int32 nFetchDirection
= impl_getPos( g_sPropertyNameForFetchDirection
);
438 sal_Int32 nDeleted
= 0;
439 if( nFetchSize
!= -1 )
441 if( nFetchDirection
!= -1 )
444 Sequence
< Property
> aOrigProps( *m_xProperties
);
445 sal_Int32 nOrigProps
= aOrigProps
.getLength();
447 m_xProperties
->realloc( nOrigProps
+ 2 - nDeleted
);//note that nDeleted is <= 2
448 auto pProperties
= m_xProperties
->getArray();
449 for( sal_Int32 n
= 0, m
= 0; n
< nOrigProps
; n
++, m
++ )
451 if( n
== nFetchSize
|| n
== nFetchDirection
)
454 pProperties
[ m
] = aOrigProps
[ n
];
457 Property
& rMyProp
= pProperties
[ nOrigProps
- nDeleted
];
458 rMyProp
.Name
= g_sPropertyNameForFetchSize
;
459 rMyProp
.Type
= cppu::UnoType
<sal_Int32
>::get();
460 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
462 if( nFetchSize
!= -1 )
463 m_nFetchSizePropertyHandle
= aOrigProps
[nFetchSize
].Handle
;
465 m_nFetchSizePropertyHandle
= impl_getRemainedHandle();
467 rMyProp
.Handle
= m_nFetchSizePropertyHandle
;
471 Property
& rMyProp
= pProperties
[ nOrigProps
- nDeleted
+ 1 ];
472 rMyProp
.Name
= g_sPropertyNameForFetchDirection
;
473 rMyProp
.Type
= cppu::UnoType
<sal_Bool
>::get();
474 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
476 m_nFetchDirectionPropertyHandle
= rMyProp
.Handle
;
480 // XInterface methods.
482 void SAL_CALL
CCRS_PropertySetInfo::acquire()
485 OWeakObject::acquire();
488 void SAL_CALL
CCRS_PropertySetInfo::release()
491 OWeakObject::release();
494 css::uno::Any SAL_CALL
CCRS_PropertySetInfo::queryInterface( const css::uno::Type
& rType
)
496 css::uno::Any aRet
= cppu::queryInterface( rType
,
497 static_cast< XTypeProvider
* >(this),
498 static_cast< XPropertySetInfo
* >(this)
500 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
503 // XTypeProvider methods.
505 //list all interfaces exclusive baseclasses
506 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
511 // XPropertySetInfo methods.
514 Sequence
< Property
> SAL_CALL CCRS_PropertySetInfo
517 return *m_xProperties
;
521 Property SAL_CALL CCRS_PropertySetInfo
522 ::getPropertyByName( const OUString
& aName
)
525 if ( impl_queryProperty( aName
, aProp
) )
528 throw UnknownPropertyException(aName
);
532 sal_Bool SAL_CALL CCRS_PropertySetInfo
533 ::hasPropertyByName( const OUString
& Name
)
535 return ( impl_getPos( Name
) != -1 );
542 sal_Int32 CCRS_PropertySetInfo
543 ::impl_getPos( std::u16string_view rName
) const
545 for( sal_Int32 nN
= m_xProperties
->getLength(); nN
--; )
547 const Property
& rMyProp
= (*m_xProperties
)[nN
];
548 if( rMyProp
.Name
== rName
)
554 bool CCRS_PropertySetInfo
555 ::impl_queryProperty( std::u16string_view rName
, Property
& rProp
) const
557 for( const Property
& rMyProp
: std::as_const(*m_xProperties
) )
559 if( rMyProp
.Name
== rName
)
561 rProp
.Name
= rMyProp
.Name
;
562 rProp
.Handle
= rMyProp
.Handle
;
563 rProp
.Type
= rMyProp
.Type
;
564 rProp
.Attributes
= rMyProp
.Attributes
;
573 bool CCRS_PropertySetInfo
574 ::impl_isMyPropertyName( std::u16string_view rPropertyName
)
576 return ( rPropertyName
== g_sPropertyNameForCount
577 || rPropertyName
== g_sPropertyNameForFinalCount
578 || rPropertyName
== g_sPropertyNameForFetchSize
579 || rPropertyName
== g_sPropertyNameForFetchDirection
);
582 sal_Int32 CCRS_PropertySetInfo
583 ::impl_getRemainedHandle( ) const
585 sal_Int32 nHandle
= 1;
589 OSL_FAIL( "Properties not initialized yet" );
596 for( const auto & rProp
: std::as_const(*m_xProperties
) )
598 if( nHandle
== rProp
.Handle
)
612 CachedContentResultSet::CachedContentResultSet(
613 const Reference
< XComponentContext
> & rxContext
614 , const Reference
< XResultSet
> & xOrigin
615 , const Reference
< XContentIdentifierMapping
> &
616 xContentIdentifierMapping
)
617 : ContentResultSetWrapper( xOrigin
)
619 , m_xContext( rxContext
)
621 , m_xContentIdentifierMapping( xContentIdentifierMapping
)
622 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
623 , m_bAfterLast( false )
624 , m_nLastAppliedPos( 0 )
625 , m_bAfterLastApplied( false )
627 , m_bFinalCount( false )
629 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
)
631 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
)
633 , m_bLastReadWasFromCache( false )
634 , m_bLastCachedReadWasNull( true )
635 , m_aCache( m_xContentIdentifierMapping
)
636 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping
)
637 , m_aCacheContentIdentifier( m_xContentIdentifierMapping
)
638 , m_aCacheContent( m_xContentIdentifierMapping
)
639 , m_bTriedToGetTypeConverter( false )
641 m_xFetchProvider
.set( m_xResultSetOrigin
, UNO_QUERY
);
642 OSL_ENSURE( m_xFetchProvider
.is(), "interface XFetchProvider is required" );
644 m_xFetchProviderForContentAccess
.set( m_xResultSetOrigin
, UNO_QUERY
);
645 OSL_ENSURE( m_xFetchProviderForContentAccess
.is(), "interface XFetchProviderForContentAccess is required" );
650 CachedContentResultSet::~CachedContentResultSet()
653 //do not delete m_pMyPropSetInfo, cause it is hold via reference
660 bool CachedContentResultSet
661 ::applyPositionToOrigin( std::unique_lock
<std::mutex
>& rGuard
, sal_Int32 nRow
)
663 impl_EnsureNotDisposed(rGuard
);
667 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
671 OSL_ENSURE( nRow
>= 0, "only positive values supported" );
672 if( !m_xResultSetOrigin
.is() )
674 OSL_FAIL( "broadcaster was disposed already" );
677 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
679 sal_Int32 nLastAppliedPos
= m_nLastAppliedPos
;
680 bool bAfterLastApplied
= m_bAfterLastApplied
;
681 bool bAfterLast
= m_bAfterLast
;
682 sal_Int32 nForwardOnly
= m_nForwardOnly
;
686 if( bAfterLastApplied
|| nLastAppliedPos
!= nRow
)
688 if( nForwardOnly
== 1 )
690 if( bAfterLastApplied
|| bAfterLast
|| !nRow
|| nRow
< nLastAppliedPos
)
691 throw SQLException();
693 sal_Int32 nN
= nRow
- nLastAppliedPos
;
695 for( nM
= 0; nN
--; nM
++ )
697 if( !m_xResultSetOrigin
->next() )
702 m_nLastAppliedPos
+= nM
;
703 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
704 return nRow
== m_nLastAppliedPos
;
707 if( !nRow
) //absolute( 0 ) will throw exception
709 m_xResultSetOrigin
->beforeFirst();
712 m_nLastAppliedPos
= 0;
713 m_bAfterLastApplied
= false;
718 //move absolute, if !nLastAppliedPos
719 //because move relative would throw exception
720 if( !nLastAppliedPos
|| bAfterLast
|| bAfterLastApplied
)
722 bool bValid
= m_xResultSetOrigin
->absolute( nRow
);
725 m_nLastAppliedPos
= nRow
;
726 m_bAfterLastApplied
= !bValid
;
731 bool bValid
= m_xResultSetOrigin
->relative( nRow
- nLastAppliedPos
);
734 m_nLastAppliedPos
+= ( nRow
- nLastAppliedPos
);
735 m_bAfterLastApplied
= !bValid
;
739 catch (const SQLException
&)
742 if( !bAfterLastApplied
&& !bAfterLast
&& nRow
> nLastAppliedPos
&& impl_isForwardOnly(rGuard
) )
744 sal_Int32 nN
= nRow
- nLastAppliedPos
;
746 for( nM
= 0; nN
--; nM
++ )
748 if( !m_xResultSetOrigin
->next() )
752 m_nLastAppliedPos
+= nM
;
753 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
759 return nRow
== m_nLastAppliedPos
;
765 //define for fetching data
768 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
769 bool bDirection = !!( \
770 nFetchDirection != FetchDirection::REVERSE ); \
771 FetchResult aResult = \
772 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
773 aCache.loadData( aResult ); \
774 sal_Int32 nMax = aCache.getMaxRow(); \
775 sal_Int32 nCurCount = m_nKnownCount; \
776 bool bIsFinalCount = aCache.hasKnownLast(); \
777 bool bCurIsFinalCount = m_bFinalCount; \
778 if( nMax > nCurCount ) \
779 impl_changeRowCount( rGuard, nCurCount, nMax ); \
780 if( bIsFinalCount && !bCurIsFinalCount ) \
781 impl_changeIsRowCountFinal( rGuard, bCurIsFinalCount, bIsFinalCount );
783 void CachedContentResultSet
784 ::impl_fetchData( std::unique_lock
<std::mutex
>& rGuard
, sal_Int32 nRow
785 , sal_Int32 nFetchSize
, sal_Int32 nFetchDirection
)
787 FETCH_XXX( m_aCache
, m_xFetchProvider
, fetch
);
790 void CachedContentResultSet
791 ::impl_changeRowCount( std::unique_lock
<std::mutex
>& rGuard
, sal_Int32 nOld
, sal_Int32 nNew
)
793 OSL_ENSURE( nNew
> nOld
, "RowCount only can grow" );
797 //create PropertyChangeEvent and set value
798 PropertyChangeEvent aEvt
;
799 aEvt
.Source
= static_cast< XPropertySet
* >( this );
800 aEvt
.Further
= false;
801 aEvt
.OldValue
<<= nOld
;
802 aEvt
.NewValue
<<= nNew
;
804 m_nKnownCount
= nNew
;
806 //send PropertyChangeEvent to listeners
807 impl_notifyPropertyChangeListeners( rGuard
, aEvt
);
810 void CachedContentResultSet
811 ::impl_changeIsRowCountFinal( std::unique_lock
<std::mutex
>& rGuard
, bool bOld
, bool bNew
)
813 OSL_ENSURE( !bOld
&& bNew
, "This change is not allowed for IsRowCountFinal" );
817 //create PropertyChangeEvent and set value
818 PropertyChangeEvent aEvt
;
819 aEvt
.Source
= static_cast< XPropertySet
* >( this );
820 aEvt
.Further
= false;
821 aEvt
.OldValue
<<= bOld
;
822 aEvt
.NewValue
<<= bNew
;
824 m_bFinalCount
= bNew
;
826 //send PropertyChangeEvent to listeners
827 impl_notifyPropertyChangeListeners( rGuard
, aEvt
);
830 bool CachedContentResultSet
831 ::impl_isKnownValidPosition( std::unique_lock
<std::mutex
>& /*rGuard*/, sal_Int32 nRow
) const
833 return m_nKnownCount
&& nRow
834 && nRow
<= m_nKnownCount
;
837 bool CachedContentResultSet
838 ::impl_isKnownInvalidPosition( std::unique_lock
<std::mutex
>& /*rGuard*/, sal_Int32 nRow
) const
844 return nRow
> m_nKnownCount
;
849 void CachedContentResultSet
850 ::impl_initPropertySetInfo(std::unique_lock
<std::mutex
>& rGuard
)
852 ContentResultSetWrapper::impl_initPropertySetInfo(rGuard
);
854 if( m_xMyPropertySetInfo
.is() )
856 m_xMyPropertySetInfo
= new CCRS_PropertySetInfo( m_xPropertySetInfo
);
857 m_xPropertySetInfo
= m_xMyPropertySetInfo
.get();
861 // XInterface methods.
862 void SAL_CALL
CachedContentResultSet::acquire()
865 OWeakObject::acquire();
868 void SAL_CALL
CachedContentResultSet::release()
871 OWeakObject::release();
874 Any SAL_CALL CachedContentResultSet
875 ::queryInterface( const Type
& rType
)
877 //list all interfaces inclusive baseclasses of interfaces
879 Any aRet
= ContentResultSetWrapper::queryInterface( rType
);
880 if( aRet
.hasValue() )
883 aRet
= cppu::queryInterface( rType
,
884 static_cast< XTypeProvider
* >( this ),
885 static_cast< XServiceInfo
* >( this ) );
887 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
891 // XTypeProvider methods.
893 //list all interfaces exclusive baseclasses
894 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
899 , XResultSetMetaDataSupplier
902 , XPropertyChangeListener
903 , XVetoableChangeListener
911 // XServiceInfo methods.
913 OUString SAL_CALL
CachedContentResultSet::getImplementationName()
915 return "com.sun.star.comp.ucb.CachedContentResultSet";
918 sal_Bool SAL_CALL
CachedContentResultSet::supportsService( const OUString
& ServiceName
)
920 return cppu::supportsService( this, ServiceName
);
923 css::uno::Sequence
< OUString
> SAL_CALL
CachedContentResultSet::getSupportedServiceNames()
925 return { "com.sun.star.ucb.CachedContentResultSet" };
930 // XPropertySet methods. ( inherited )
934 void CachedContentResultSet
935 ::setPropertyValueImpl( std::unique_lock
<std::mutex
>& rGuard
, const OUString
& aPropertyName
, const Any
& aValue
)
937 impl_EnsureNotDisposed(rGuard
);
939 if( !getPropertySetInfoImpl(rGuard
).is() )
941 OSL_FAIL( "broadcaster was disposed already" );
942 throw UnknownPropertyException();
945 Property aProp
= m_xMyPropertySetInfo
->getPropertyByName( aPropertyName
);
946 //throws UnknownPropertyException, if so
948 if( aProp
.Attributes
& PropertyAttribute::READONLY
)
950 //It is assumed, that the properties
951 //'RowCount' and 'IsRowCountFinal' are readonly!
952 throw IllegalArgumentException();
954 if( aProp
.Name
== g_sPropertyNameForFetchDirection
)
958 if( !( aValue
>>= nNew
) )
960 throw IllegalArgumentException();
963 if( nNew
== FetchDirection::UNKNOWN
)
965 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
;
967 else if( nNew
!= FetchDirection::FORWARD
&& nNew
!= FetchDirection::REVERSE
)
969 throw IllegalArgumentException();
972 //create PropertyChangeEvent and set value
973 PropertyChangeEvent aEvt
;
974 aEvt
.Source
= static_cast< XPropertySet
* >( this );
975 aEvt
.PropertyName
= aPropertyName
;
976 aEvt
.Further
= false;
977 aEvt
.PropertyHandle
= m_xMyPropertySetInfo
->
978 m_nFetchDirectionPropertyHandle
;
979 aEvt
.OldValue
<<= m_nFetchDirection
;
980 aEvt
.NewValue
<<= nNew
;
982 m_nFetchDirection
= nNew
;
984 //send PropertyChangeEvent to listeners
985 impl_notifyPropertyChangeListeners( rGuard
, aEvt
);
987 else if( aProp
.Name
== g_sPropertyNameForFetchSize
)
991 if( !( aValue
>>= nNew
) )
993 throw IllegalArgumentException();
998 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
;
1001 //create PropertyChangeEvent and set value
1002 PropertyChangeEvent aEvt
;
1003 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1004 aEvt
.PropertyName
= aPropertyName
;
1005 aEvt
.Further
= false;
1006 aEvt
.PropertyHandle
= m_xMyPropertySetInfo
->
1007 m_nFetchSizePropertyHandle
;
1008 aEvt
.OldValue
<<= m_nFetchSize
;
1009 aEvt
.NewValue
<<= nNew
;
1011 m_nFetchSize
= nNew
;
1013 //send PropertyChangeEvent to listeners
1014 impl_notifyPropertyChangeListeners( rGuard
, aEvt
);
1018 impl_init_xPropertySetOrigin(rGuard
);
1019 if( !m_xPropertySetOrigin
.is() )
1021 OSL_FAIL( "broadcaster was disposed already" );
1024 m_xPropertySetOrigin
->setPropertyValue( aPropertyName
, aValue
);
1030 Any SAL_CALL CachedContentResultSet
1031 ::getPropertyValue( const OUString
& rPropertyName
)
1033 std::unique_lock
aGuard(m_aMutex
);
1034 impl_EnsureNotDisposed(aGuard
);
1036 if( !getPropertySetInfoImpl(aGuard
).is() )
1038 OSL_FAIL( "broadcaster was disposed already" );
1039 throw UnknownPropertyException();
1042 m_xMyPropertySetInfo
->getPropertyByName( rPropertyName
);
1043 //throws UnknownPropertyException, if so
1046 if( rPropertyName
== g_sPropertyNameForCount
)
1048 aValue
<<= m_nKnownCount
;
1050 else if( rPropertyName
== g_sPropertyNameForFinalCount
)
1052 aValue
<<= m_bFinalCount
;
1054 else if( rPropertyName
== g_sPropertyNameForFetchSize
)
1056 aValue
<<= m_nFetchSize
;
1058 else if( rPropertyName
== g_sPropertyNameForFetchDirection
)
1060 aValue
<<= m_nFetchDirection
;
1064 impl_init_xPropertySetOrigin(aGuard
);
1065 if( !m_xPropertySetOrigin
.is() )
1067 OSL_FAIL( "broadcaster was disposed already" );
1068 throw UnknownPropertyException();
1071 aValue
= m_xPropertySetOrigin
->getPropertyValue( rPropertyName
);
1077 // own methods. ( inherited )
1080 //virtual, only called from ContentResultSetWrapperListener
1081 void CachedContentResultSet
1082 ::impl_disposing( const EventObject
& rEventObject
)
1085 std::unique_lock
aGuard(m_aMutex
);
1086 impl_EnsureNotDisposed(aGuard
);
1087 //release all references to the broadcaster:
1088 m_xFetchProvider
.clear();
1089 m_xFetchProviderForContentAccess
.clear();
1091 ContentResultSetWrapper::impl_disposing( rEventObject
);
1094 //virtual, only called from ContentResultSetWrapperListener
1095 void CachedContentResultSet
1096 ::impl_propertyChange( const PropertyChangeEvent
& rEvt
)
1098 std::unique_lock
aGuard(m_aMutex
);
1099 impl_EnsureNotDisposed(aGuard
);
1101 PropertyChangeEvent
aEvt( rEvt
);
1102 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1103 aEvt
.Further
= false;
1106 if( CCRS_PropertySetInfo
1107 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1109 //don't notify foreign events on fetchsize and fetchdirection
1110 if( aEvt
.PropertyName
== g_sPropertyNameForFetchSize
1111 || aEvt
.PropertyName
== g_sPropertyNameForFetchDirection
)
1114 //adjust my props 'RowCount' and 'IsRowCountFinal'
1115 if( aEvt
.PropertyName
== g_sPropertyNameForCount
)
1120 if( !( aEvt
.NewValue
>>= nNew
) )
1122 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1126 impl_changeRowCount( aGuard
, m_nKnownCount
, nNew
);
1128 else if( aEvt
.PropertyName
== g_sPropertyNameForFinalCount
)
1129 {//IsRowCountFinal changed
1133 if( !( aEvt
.NewValue
>>= bNew
) )
1135 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1138 impl_changeIsRowCountFinal( aGuard
, m_bFinalCount
, bNew
);
1144 impl_notifyPropertyChangeListeners( aGuard
, aEvt
);
1148 //virtual, only called from ContentResultSetWrapperListener
1149 void CachedContentResultSet
1150 ::impl_vetoableChange( const PropertyChangeEvent
& rEvt
)
1152 std::unique_lock
aGuard(m_aMutex
);
1153 impl_EnsureNotDisposed(aGuard
);
1155 //don't notify events on my properties, cause they are not vetoable
1156 if( CCRS_PropertySetInfo
1157 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1163 PropertyChangeEvent
aEvt( rEvt
);
1164 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1165 aEvt
.Further
= false;
1167 impl_notifyVetoableChangeListeners( aGuard
, aEvt
);
1171 // XContentAccess methods. ( inherited ) ( -- position dependent )
1174 #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1175 impl_EnsureNotDisposed(rGuard); \
1176 sal_Int32 nRow = m_nRow; \
1177 sal_Int32 nFetchSize = m_nFetchSize; \
1178 sal_Int32 nFetchDirection = m_nFetchDirection; \
1179 if( !m_aCache##XXX.hasRow( nRow ) ) \
1183 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1185 if( !m_xFetchProviderForContentAccess.is() ) \
1187 OSL_FAIL( "broadcaster was disposed already" ); \
1188 throw RuntimeException(); \
1190 if( impl_isForwardOnly(rGuard) ) \
1191 applyPositionToOrigin( rGuard, nRow ); \
1193 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1195 if( !m_aCache##XXX.hasRow( nRow ) ) \
1197 applyPositionToOrigin( rGuard, nRow ); \
1198 TYPE aRet = ContentResultSetWrapper::query##XXX();\
1199 if( m_xContentIdentifierMapping.is() ) \
1200 return m_xContentIdentifierMapping->map##XXX( aRet );\
1204 catch (const RuntimeException&) \
1208 catch (const Exception& e) \
1210 Any a(cppu::getCaughtException()); \
1211 throw WrappedTargetRuntimeException( \
1212 "wrapped Exception " + e.Message, \
1213 Reference<XInterface>(), a); \
1216 return m_aCache##XXX.get##XXX( nRow );
1219 OUString CachedContentResultSet
1220 ::queryContentIdentifierStringImpl(std::unique_lock
<std::mutex
>& rGuard
)
1222 XCONTENTACCESS_queryXXX( queryContentIdentifierString
, ContentIdentifierString
, OUString
)
1227 Reference
< XContentIdentifier
> SAL_CALL CachedContentResultSet
1228 ::queryContentIdentifier()
1230 std::unique_lock
rGuard(m_aMutex
);
1231 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1236 Reference
< XContent
> SAL_CALL CachedContentResultSet
1239 std::unique_lock
rGuard(m_aMutex
);
1240 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1244 // XResultSet methods. ( inherited )
1248 sal_Bool SAL_CALL CachedContentResultSet
1251 std::unique_lock
aGuard(m_aMutex
);
1252 impl_EnsureNotDisposed(aGuard
);
1263 m_bAfterLast
= true;
1267 //known valid position
1268 if( impl_isKnownValidPosition( aGuard
, m_nRow
+ 1 ) )
1275 sal_Int32 nRow
= m_nRow
;
1277 bool bValid
= applyPositionToOrigin( aGuard
, nRow
+ 1 );
1280 m_bAfterLast
= !bValid
;
1285 sal_Bool SAL_CALL CachedContentResultSet
1288 std::unique_lock
aGuard(m_aMutex
);
1289 impl_EnsureNotDisposed(aGuard
);
1291 if( impl_isForwardOnly(aGuard
) )
1292 throw SQLException();
1295 if( !m_bAfterLast
&& !m_nRow
)
1298 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1301 m_bAfterLast
= false;
1304 //known valid position ?:
1305 if( impl_isKnownValidPosition( aGuard
, m_nRow
- 1 ) )
1308 m_bAfterLast
= false;
1312 sal_Int32 nRow
= m_nRow
;
1314 bool bValid
= applyPositionToOrigin( aGuard
, nRow
- 1 );
1317 m_bAfterLast
= false;
1322 sal_Bool SAL_CALL CachedContentResultSet
1323 ::absolute( sal_Int32 row
)
1325 std::unique_lock
aGuard(m_aMutex
);
1326 impl_EnsureNotDisposed(aGuard
);
1329 throw SQLException();
1331 if( impl_isForwardOnly(aGuard
) )
1332 throw SQLException();
1334 if( !m_xResultSetOrigin
.is() )
1336 OSL_FAIL( "broadcaster was disposed already" );
1343 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1351 m_bAfterLast
= false;
1354 //unknown final count:
1357 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1362 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1365 m_nLastAppliedPos
= nNewRow
;
1367 m_bAfterLastApplied
= m_bAfterLast
= false;
1372 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1375 m_nLastAppliedPos
= nCurRow
;
1377 m_bAfterLast
= false;
1378 return nCurRow
!= 0;
1383 if( row
> m_nKnownCount
)
1385 m_nRow
= m_nKnownCount
+ 1;
1386 m_bAfterLast
= true;
1390 m_bAfterLast
= false;
1393 //unknown new position:
1396 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1401 sal_Int32 nNewRow
= row
;
1402 if( nNewRow
> m_nKnownCount
)
1404 nNewRow
= m_nKnownCount
+ 1;
1405 m_bAfterLastApplied
= m_bAfterLast
= true;
1408 m_bAfterLastApplied
= m_bAfterLast
= false;
1410 m_nLastAppliedPos
= nNewRow
;
1416 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1417 bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1420 m_nLastAppliedPos
= nCurRow
;
1422 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1423 return nCurRow
&& !bIsAfterLast
;
1427 sal_Bool SAL_CALL CachedContentResultSet
1428 ::relative( sal_Int32 rows
)
1430 std::unique_lock
aGuard(m_aMutex
);
1431 impl_EnsureNotDisposed(aGuard
);
1433 if( impl_isForwardOnly(aGuard
) )
1434 throw SQLException();
1436 if( m_bAfterLast
|| impl_isKnownInvalidPosition( aGuard
, m_nRow
) )
1437 throw SQLException();
1442 sal_Int32 nNewRow
= m_nRow
+ rows
;
1446 if( impl_isKnownValidPosition( aGuard
, nNewRow
) )
1449 m_bAfterLast
= false;
1454 //known invalid new position:
1457 m_bAfterLast
= false;
1461 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1463 m_bAfterLast
= true;
1464 m_nRow
= m_nKnownCount
+ 1;
1467 //unknown new position:
1468 bool bValid
= applyPositionToOrigin( aGuard
, nNewRow
);
1470 m_bAfterLast
= !bValid
; // only nNewRow > 0 possible here
1477 sal_Bool SAL_CALL CachedContentResultSet
1480 std::unique_lock
aGuard(m_aMutex
);
1481 impl_EnsureNotDisposed(aGuard
);
1483 if( impl_isForwardOnly(aGuard
) )
1484 throw SQLException();
1486 if( impl_isKnownValidPosition( aGuard
, 1 ) )
1489 m_bAfterLast
= false;
1492 if( impl_isKnownInvalidPosition( aGuard
, 1 ) )
1495 m_bAfterLast
= false;
1499 bool bValid
= applyPositionToOrigin( aGuard
, 1 );
1501 m_bAfterLast
= false;
1506 sal_Bool SAL_CALL CachedContentResultSet
1509 std::unique_lock
aGuard(m_aMutex
);
1510 impl_EnsureNotDisposed(aGuard
);
1512 if( impl_isForwardOnly(aGuard
) )
1513 throw SQLException();
1517 m_nRow
= m_nKnownCount
;
1518 m_bAfterLast
= false;
1519 return m_nKnownCount
!= 0;
1522 if( !m_xResultSetOrigin
.is() )
1524 OSL_FAIL( "broadcaster was disposed already" );
1529 bool bValid
= m_xResultSetOrigin
->last();
1532 m_bAfterLastApplied
= m_bAfterLast
= false;
1535 m_nLastAppliedPos
= m_nKnownCount
;
1536 m_nRow
= m_nKnownCount
;
1541 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1544 m_nLastAppliedPos
= nCurRow
;
1546 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1547 m_nKnownCount
= nCurRow
;
1548 m_bFinalCount
= true;
1549 return nCurRow
!= 0;
1553 void SAL_CALL CachedContentResultSet
1556 std::unique_lock
aGuard(m_aMutex
);
1557 impl_EnsureNotDisposed(aGuard
);
1559 if( impl_isForwardOnly(aGuard
) )
1560 throw SQLException();
1563 m_bAfterLast
= false;
1567 void SAL_CALL CachedContentResultSet
1570 std::unique_lock
aGuard(m_aMutex
);
1571 impl_EnsureNotDisposed(aGuard
);
1573 if( impl_isForwardOnly(aGuard
) )
1574 throw SQLException();
1577 m_bAfterLast
= true;
1581 sal_Bool SAL_CALL CachedContentResultSet
1584 std::unique_lock
aGuard(m_aMutex
);
1585 impl_EnsureNotDisposed(aGuard
);
1590 return m_bAfterLast
;
1594 if( !m_xResultSetOrigin
.is() )
1596 OSL_FAIL( "broadcaster was disposed already" );
1601 //find out whether the original resultset contains rows or not
1602 m_xResultSetOrigin
->afterLast();
1605 m_bAfterLastApplied
= true;
1608 return m_xResultSetOrigin
->isAfterLast();
1612 sal_Bool SAL_CALL CachedContentResultSet
1615 std::unique_lock
aGuard(m_aMutex
);
1616 impl_EnsureNotDisposed(aGuard
);
1627 if( !m_xResultSetOrigin
.is() )
1629 OSL_FAIL( "broadcaster was disposed already" );
1634 //find out whether the original resultset contains rows or not
1635 m_xResultSetOrigin
->beforeFirst();
1638 m_bAfterLastApplied
= false;
1639 m_nLastAppliedPos
= 0;
1642 return m_xResultSetOrigin
->isBeforeFirst();
1646 sal_Bool SAL_CALL CachedContentResultSet
1649 std::unique_lock
aGuard(m_aMutex
);
1650 impl_EnsureNotDisposed(aGuard
);
1653 Reference
< XResultSet
> xResultSetOrigin
;
1665 xResultSetOrigin
= m_xResultSetOrigin
;
1667 //need to ask origin
1668 if( !applyPositionToOrigin( aGuard
, nRow
) )
1671 return xResultSetOrigin
->isFirst();
1675 sal_Bool SAL_CALL CachedContentResultSet
1678 std::unique_lock
aGuard(m_aMutex
);
1679 impl_EnsureNotDisposed(aGuard
);
1682 Reference
< XResultSet
> xResultSetOrigin
;
1685 if( m_nRow
< m_nKnownCount
)
1688 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1691 xResultSetOrigin
= m_xResultSetOrigin
;
1693 //need to ask origin
1694 if( !applyPositionToOrigin( aGuard
, nRow
) )
1697 return xResultSetOrigin
->isLast();
1702 sal_Int32 SAL_CALL CachedContentResultSet
1705 std::unique_lock
aGuard(m_aMutex
);
1706 impl_EnsureNotDisposed(aGuard
);
1714 void SAL_CALL CachedContentResultSet
1717 std::unique_lock
aGuard(m_aMutex
);
1718 impl_EnsureNotDisposed(aGuard
);
1720 //the ContentResultSet is static and will not change
1721 //therefore we don't need to reload anything
1725 sal_Bool SAL_CALL CachedContentResultSet
1728 std::unique_lock
aGuard(m_aMutex
);
1729 impl_EnsureNotDisposed(aGuard
);
1731 //the ContentResultSet is static and will not change
1735 sal_Bool SAL_CALL CachedContentResultSet
1738 std::unique_lock
aGuard(m_aMutex
);
1739 impl_EnsureNotDisposed(aGuard
);
1741 //the ContentResultSet is static and will not change
1746 sal_Bool SAL_CALL CachedContentResultSet
1749 std::unique_lock
aGuard(m_aMutex
);
1750 impl_EnsureNotDisposed(aGuard
);
1752 //the ContentResultSet is static and will not change
1757 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1760 std::unique_lock
aGuard(m_aMutex
);
1761 impl_EnsureNotDisposed(aGuard
);
1762 //@todo ?return anything
1763 return Reference
< XInterface
>();
1767 // XRow methods. ( inherited )
1771 sal_Bool SAL_CALL CachedContentResultSet
1774 std::unique_lock
aGuard(m_aMutex
);
1775 impl_EnsureNotDisposed(aGuard
);
1776 impl_init_xRowOrigin(aGuard
);
1777 if( m_bLastReadWasFromCache
)
1778 return m_bLastCachedReadWasNull
;
1779 if( !m_xRowOrigin
.is() )
1781 OSL_FAIL( "broadcaster was disposed already" );
1785 return m_xRowOrigin
->wasNull();
1789 OUString SAL_CALL CachedContentResultSet
1790 ::getString( sal_Int32 columnIndex
)
1792 return rowOriginGet
<OUString
>(&css::sdbc::XRow::getString
, columnIndex
);
1796 sal_Bool SAL_CALL CachedContentResultSet
1797 ::getBoolean( sal_Int32 columnIndex
)
1799 return rowOriginGet
<sal_Bool
>(&css::sdbc::XRow::getBoolean
, columnIndex
);
1803 sal_Int8 SAL_CALL CachedContentResultSet
1804 ::getByte( sal_Int32 columnIndex
)
1806 return rowOriginGet
<sal_Int8
>(&css::sdbc::XRow::getByte
, columnIndex
);
1810 sal_Int16 SAL_CALL CachedContentResultSet
1811 ::getShort( sal_Int32 columnIndex
)
1813 return rowOriginGet
<sal_Int16
>(&css::sdbc::XRow::getShort
, columnIndex
);
1817 sal_Int32 SAL_CALL CachedContentResultSet
1818 ::getInt( sal_Int32 columnIndex
)
1820 return rowOriginGet
<sal_Int32
>(&css::sdbc::XRow::getInt
, columnIndex
);
1824 sal_Int64 SAL_CALL CachedContentResultSet
1825 ::getLong( sal_Int32 columnIndex
)
1827 return rowOriginGet
<sal_Int64
>(&css::sdbc::XRow::getLong
, columnIndex
);
1831 float SAL_CALL CachedContentResultSet
1832 ::getFloat( sal_Int32 columnIndex
)
1834 return rowOriginGet
<float>(&css::sdbc::XRow::getFloat
, columnIndex
);
1838 double SAL_CALL CachedContentResultSet
1839 ::getDouble( sal_Int32 columnIndex
)
1841 return rowOriginGet
<double>(&css::sdbc::XRow::getDouble
, columnIndex
);
1845 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
1846 ::getBytes( sal_Int32 columnIndex
)
1848 return rowOriginGet
< css::uno::Sequence
<sal_Int8
> >(
1849 &css::sdbc::XRow::getBytes
, columnIndex
);
1853 Date SAL_CALL CachedContentResultSet
1854 ::getDate( sal_Int32 columnIndex
)
1856 return rowOriginGet
<css::util::Date
>(
1857 &css::sdbc::XRow::getDate
, columnIndex
);
1861 Time SAL_CALL CachedContentResultSet
1862 ::getTime( sal_Int32 columnIndex
)
1864 return rowOriginGet
<css::util::Time
>(
1865 &css::sdbc::XRow::getTime
, columnIndex
);
1869 DateTime SAL_CALL CachedContentResultSet
1870 ::getTimestamp( sal_Int32 columnIndex
)
1872 return rowOriginGet
<css::util::DateTime
>(
1873 &css::sdbc::XRow::getTimestamp
, columnIndex
);
1877 Reference
< css::io::XInputStream
>
1878 SAL_CALL CachedContentResultSet
1879 ::getBinaryStream( sal_Int32 columnIndex
)
1881 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1882 &css::sdbc::XRow::getBinaryStream
, columnIndex
);
1886 Reference
< css::io::XInputStream
>
1887 SAL_CALL CachedContentResultSet
1888 ::getCharacterStream( sal_Int32 columnIndex
)
1890 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1891 &css::sdbc::XRow::getCharacterStream
, columnIndex
);
1895 Any SAL_CALL CachedContentResultSet
1896 ::getObject( sal_Int32 columnIndex
,
1898 css::container::XNameAccess
>& typeMap
)
1900 //if you change this function please pay attention to
1901 //function template rowOriginGet, where this is similar implemented
1903 std::unique_lock
aGuard(m_aMutex
);
1904 sal_Int32 nRow
= m_nRow
;
1905 sal_Int32 nFetchSize
= m_nFetchSize
;
1906 sal_Int32 nFetchDirection
= m_nFetchDirection
;
1907 if( !m_aCache
.hasRow( nRow
) )
1909 if( !m_aCache
.hasCausedException( nRow
) )
1911 if( !m_xFetchProvider
.is() )
1913 OSL_FAIL( "broadcaster was disposed already" );
1916 impl_fetchData( aGuard
, nRow
, nFetchSize
, nFetchDirection
);
1918 if( !m_aCache
.hasRow( nRow
) )
1920 m_bLastReadWasFromCache
= false;
1921 applyPositionToOrigin( aGuard
, nRow
);
1922 impl_init_xRowOrigin(aGuard
);
1924 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
1927 //@todo: pay attention to typeMap
1928 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
1929 m_bLastReadWasFromCache
= true;
1930 m_bLastCachedReadWasNull
= !rValue
.hasValue();
1935 Reference
< XRef
> SAL_CALL CachedContentResultSet
1936 ::getRef( sal_Int32 columnIndex
)
1938 return rowOriginGet
< css::uno::Reference
<css::sdbc::XRef
> >(
1939 &css::sdbc::XRow::getRef
, columnIndex
);
1943 Reference
< XBlob
> SAL_CALL CachedContentResultSet
1944 ::getBlob( sal_Int32 columnIndex
)
1946 return rowOriginGet
< css::uno::Reference
<css::sdbc::XBlob
> >(
1947 &css::sdbc::XRow::getBlob
, columnIndex
);
1951 Reference
< XClob
> SAL_CALL CachedContentResultSet
1952 ::getClob( sal_Int32 columnIndex
)
1954 return rowOriginGet
< css::uno::Reference
<css::sdbc::XClob
> >(
1955 &css::sdbc::XRow::getClob
, columnIndex
);
1959 Reference
< XArray
> SAL_CALL CachedContentResultSet
1960 ::getArray( sal_Int32 columnIndex
)
1962 return rowOriginGet
< css::uno::Reference
<css::sdbc::XArray
> >(
1963 &css::sdbc::XRow::getArray
, columnIndex
);
1967 // Type Converter Support
1970 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter(std::unique_lock
<std::mutex
>& )
1972 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
1974 m_bTriedToGetTypeConverter
= true;
1975 m_xTypeConverter
.set( Converter::create(m_xContext
) );
1977 OSL_ENSURE( m_xTypeConverter
.is(),
1978 "PropertyValueSet::getTypeConverter() - "
1979 "Service 'com.sun.star.script.Converter' n/a!" );
1981 return m_xTypeConverter
;
1987 CachedContentResultSetFactory::CachedContentResultSetFactory(
1988 const Reference
< XComponentContext
> & rxContext
)
1990 m_xContext
= rxContext
;
1993 CachedContentResultSetFactory::~CachedContentResultSetFactory()
1997 // CachedContentResultSetFactory XServiceInfo methods.
1999 OUString SAL_CALL
CachedContentResultSetFactory::getImplementationName()
2001 return "com.sun.star.comp.ucb.CachedContentResultSetFactory";
2003 sal_Bool SAL_CALL
CachedContentResultSetFactory::supportsService( const OUString
& ServiceName
)
2005 return cppu::supportsService( this, ServiceName
);
2007 css::uno::Sequence
< OUString
> SAL_CALL
CachedContentResultSetFactory::getSupportedServiceNames()
2009 return { "com.sun.star.ucb.CachedContentResultSetFactory" };
2012 // Service factory implementation.
2016 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
2017 ucb_CachedContentResultSetFactory_get_implementation(
2018 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
2020 return cppu::acquire(new CachedContentResultSetFactory(context
));
2024 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2028 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2029 ::createCachedContentResultSet(
2030 const Reference
< XResultSet
> & xSource
,
2031 const Reference
< XContentIdentifierMapping
> & xMapping
)
2033 Reference
< XResultSet
> xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2037 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */