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 OUString
g_sPropertyNameForFetchSize(u
"FetchSize"_ustr
);
412 constexpr OUString
g_sPropertyNameForFetchDirection(u
"FetchDirection"_ustr
);
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
: *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
: *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 u
"com.sun.star.comp.ucb.CachedContentResultSet"_ustr
;
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 { u
"com.sun.star.ucb.CachedContentResultSet"_ustr
};
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
)
1226 Reference
<XContentIdentifier
> CachedContentResultSet
1227 ::queryContentIdentifierImpl(std::unique_lock
<std::mutex
>& rGuard
)
1229 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1233 Reference
<XContent
> CachedContentResultSet
1234 ::queryContentImpl(std::unique_lock
<std::mutex
>& rGuard
)
1236 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1239 // XResultSet methods. ( inherited )
1243 sal_Bool SAL_CALL CachedContentResultSet
1246 std::unique_lock
aGuard(m_aMutex
);
1247 impl_EnsureNotDisposed(aGuard
);
1258 m_bAfterLast
= true;
1262 //known valid position
1263 if( impl_isKnownValidPosition( aGuard
, m_nRow
+ 1 ) )
1270 sal_Int32 nRow
= m_nRow
;
1272 bool bValid
= applyPositionToOrigin( aGuard
, nRow
+ 1 );
1275 m_bAfterLast
= !bValid
;
1280 sal_Bool SAL_CALL CachedContentResultSet
1283 std::unique_lock
aGuard(m_aMutex
);
1284 impl_EnsureNotDisposed(aGuard
);
1286 if( impl_isForwardOnly(aGuard
) )
1287 throw SQLException();
1290 if( !m_bAfterLast
&& !m_nRow
)
1293 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1296 m_bAfterLast
= false;
1299 //known valid position ?:
1300 if( impl_isKnownValidPosition( aGuard
, m_nRow
- 1 ) )
1303 m_bAfterLast
= false;
1307 sal_Int32 nRow
= m_nRow
;
1309 bool bValid
= applyPositionToOrigin( aGuard
, nRow
- 1 );
1312 m_bAfterLast
= false;
1317 sal_Bool SAL_CALL CachedContentResultSet
1318 ::absolute( sal_Int32 row
)
1320 std::unique_lock
aGuard(m_aMutex
);
1321 impl_EnsureNotDisposed(aGuard
);
1324 throw SQLException();
1326 if( impl_isForwardOnly(aGuard
) )
1327 throw SQLException();
1329 if( !m_xResultSetOrigin
.is() )
1331 OSL_FAIL( "broadcaster was disposed already" );
1338 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1346 m_bAfterLast
= false;
1349 //unknown final count:
1352 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1357 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1360 m_nLastAppliedPos
= nNewRow
;
1362 m_bAfterLastApplied
= m_bAfterLast
= false;
1367 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1370 m_nLastAppliedPos
= nCurRow
;
1372 m_bAfterLast
= false;
1373 return nCurRow
!= 0;
1378 if( row
> m_nKnownCount
)
1380 m_nRow
= m_nKnownCount
+ 1;
1381 m_bAfterLast
= true;
1385 m_bAfterLast
= false;
1388 //unknown new position:
1391 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1396 sal_Int32 nNewRow
= row
;
1397 if( nNewRow
> m_nKnownCount
)
1399 nNewRow
= m_nKnownCount
+ 1;
1400 m_bAfterLastApplied
= m_bAfterLast
= true;
1403 m_bAfterLastApplied
= m_bAfterLast
= false;
1405 m_nLastAppliedPos
= nNewRow
;
1411 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1412 bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1415 m_nLastAppliedPos
= nCurRow
;
1417 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1418 return nCurRow
&& !bIsAfterLast
;
1422 sal_Bool SAL_CALL CachedContentResultSet
1423 ::relative( sal_Int32 rows
)
1425 std::unique_lock
aGuard(m_aMutex
);
1426 impl_EnsureNotDisposed(aGuard
);
1428 if( impl_isForwardOnly(aGuard
) )
1429 throw SQLException();
1431 if( m_bAfterLast
|| impl_isKnownInvalidPosition( aGuard
, m_nRow
) )
1432 throw SQLException();
1437 sal_Int32 nNewRow
= m_nRow
+ rows
;
1441 if( impl_isKnownValidPosition( aGuard
, nNewRow
) )
1444 m_bAfterLast
= false;
1449 //known invalid new position:
1452 m_bAfterLast
= false;
1456 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1458 m_bAfterLast
= true;
1459 m_nRow
= m_nKnownCount
+ 1;
1462 //unknown new position:
1463 bool bValid
= applyPositionToOrigin( aGuard
, nNewRow
);
1465 m_bAfterLast
= !bValid
; // only nNewRow > 0 possible here
1472 sal_Bool SAL_CALL CachedContentResultSet
1475 std::unique_lock
aGuard(m_aMutex
);
1476 impl_EnsureNotDisposed(aGuard
);
1478 if( impl_isForwardOnly(aGuard
) )
1479 throw SQLException();
1481 if( impl_isKnownValidPosition( aGuard
, 1 ) )
1484 m_bAfterLast
= false;
1487 if( impl_isKnownInvalidPosition( aGuard
, 1 ) )
1490 m_bAfterLast
= false;
1494 bool bValid
= applyPositionToOrigin( aGuard
, 1 );
1496 m_bAfterLast
= false;
1501 sal_Bool SAL_CALL CachedContentResultSet
1504 std::unique_lock
aGuard(m_aMutex
);
1505 impl_EnsureNotDisposed(aGuard
);
1507 if( impl_isForwardOnly(aGuard
) )
1508 throw SQLException();
1512 m_nRow
= m_nKnownCount
;
1513 m_bAfterLast
= false;
1514 return m_nKnownCount
!= 0;
1517 if( !m_xResultSetOrigin
.is() )
1519 OSL_FAIL( "broadcaster was disposed already" );
1524 bool bValid
= m_xResultSetOrigin
->last();
1527 m_bAfterLastApplied
= m_bAfterLast
= false;
1530 m_nLastAppliedPos
= m_nKnownCount
;
1531 m_nRow
= m_nKnownCount
;
1536 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1539 m_nLastAppliedPos
= nCurRow
;
1541 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1542 m_nKnownCount
= nCurRow
;
1543 m_bFinalCount
= true;
1544 return nCurRow
!= 0;
1548 void SAL_CALL CachedContentResultSet
1551 std::unique_lock
aGuard(m_aMutex
);
1552 impl_EnsureNotDisposed(aGuard
);
1554 if( impl_isForwardOnly(aGuard
) )
1555 throw SQLException();
1558 m_bAfterLast
= false;
1562 void SAL_CALL CachedContentResultSet
1565 std::unique_lock
aGuard(m_aMutex
);
1566 impl_EnsureNotDisposed(aGuard
);
1568 if( impl_isForwardOnly(aGuard
) )
1569 throw SQLException();
1572 m_bAfterLast
= true;
1576 sal_Bool SAL_CALL CachedContentResultSet
1579 std::unique_lock
aGuard(m_aMutex
);
1580 impl_EnsureNotDisposed(aGuard
);
1585 return m_bAfterLast
;
1589 if( !m_xResultSetOrigin
.is() )
1591 OSL_FAIL( "broadcaster was disposed already" );
1596 //find out whether the original resultset contains rows or not
1597 m_xResultSetOrigin
->afterLast();
1600 m_bAfterLastApplied
= true;
1603 return m_xResultSetOrigin
->isAfterLast();
1607 sal_Bool SAL_CALL CachedContentResultSet
1610 std::unique_lock
aGuard(m_aMutex
);
1611 impl_EnsureNotDisposed(aGuard
);
1622 if( !m_xResultSetOrigin
.is() )
1624 OSL_FAIL( "broadcaster was disposed already" );
1629 //find out whether the original resultset contains rows or not
1630 m_xResultSetOrigin
->beforeFirst();
1633 m_bAfterLastApplied
= false;
1634 m_nLastAppliedPos
= 0;
1637 return m_xResultSetOrigin
->isBeforeFirst();
1641 sal_Bool SAL_CALL CachedContentResultSet
1644 std::unique_lock
aGuard(m_aMutex
);
1645 impl_EnsureNotDisposed(aGuard
);
1648 Reference
< XResultSet
> xResultSetOrigin
;
1660 xResultSetOrigin
= m_xResultSetOrigin
;
1662 //need to ask origin
1663 if( !applyPositionToOrigin( aGuard
, nRow
) )
1666 return xResultSetOrigin
->isFirst();
1670 sal_Bool SAL_CALL CachedContentResultSet
1673 std::unique_lock
aGuard(m_aMutex
);
1674 impl_EnsureNotDisposed(aGuard
);
1677 Reference
< XResultSet
> xResultSetOrigin
;
1680 if( m_nRow
< m_nKnownCount
)
1683 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1686 xResultSetOrigin
= m_xResultSetOrigin
;
1688 //need to ask origin
1689 if( !applyPositionToOrigin( aGuard
, nRow
) )
1692 return xResultSetOrigin
->isLast();
1697 sal_Int32 SAL_CALL CachedContentResultSet
1700 std::unique_lock
aGuard(m_aMutex
);
1701 impl_EnsureNotDisposed(aGuard
);
1709 void SAL_CALL CachedContentResultSet
1712 std::unique_lock
aGuard(m_aMutex
);
1713 impl_EnsureNotDisposed(aGuard
);
1715 //the ContentResultSet is static and will not change
1716 //therefore we don't need to reload anything
1720 sal_Bool SAL_CALL CachedContentResultSet
1723 std::unique_lock
aGuard(m_aMutex
);
1724 impl_EnsureNotDisposed(aGuard
);
1726 //the ContentResultSet is static and will not change
1730 sal_Bool SAL_CALL CachedContentResultSet
1733 std::unique_lock
aGuard(m_aMutex
);
1734 impl_EnsureNotDisposed(aGuard
);
1736 //the ContentResultSet is static and will not change
1741 sal_Bool SAL_CALL CachedContentResultSet
1744 std::unique_lock
aGuard(m_aMutex
);
1745 impl_EnsureNotDisposed(aGuard
);
1747 //the ContentResultSet is static and will not change
1752 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1755 std::unique_lock
aGuard(m_aMutex
);
1756 impl_EnsureNotDisposed(aGuard
);
1757 //@todo ?return anything
1758 return Reference
< XInterface
>();
1762 // XRow methods. ( inherited )
1766 sal_Bool SAL_CALL CachedContentResultSet
1769 std::unique_lock
aGuard(m_aMutex
);
1770 impl_EnsureNotDisposed(aGuard
);
1771 impl_init_xRowOrigin(aGuard
);
1772 if( m_bLastReadWasFromCache
)
1773 return m_bLastCachedReadWasNull
;
1774 if( !m_xRowOrigin
.is() )
1776 OSL_FAIL( "broadcaster was disposed already" );
1780 return m_xRowOrigin
->wasNull();
1784 OUString SAL_CALL CachedContentResultSet
1785 ::getString( sal_Int32 columnIndex
)
1787 return rowOriginGet
<OUString
>(&css::sdbc::XRow::getString
, columnIndex
);
1791 sal_Bool SAL_CALL CachedContentResultSet
1792 ::getBoolean( sal_Int32 columnIndex
)
1794 return rowOriginGet
<sal_Bool
>(&css::sdbc::XRow::getBoolean
, columnIndex
);
1798 sal_Int8 SAL_CALL CachedContentResultSet
1799 ::getByte( sal_Int32 columnIndex
)
1801 return rowOriginGet
<sal_Int8
>(&css::sdbc::XRow::getByte
, columnIndex
);
1805 sal_Int16 SAL_CALL CachedContentResultSet
1806 ::getShort( sal_Int32 columnIndex
)
1808 return rowOriginGet
<sal_Int16
>(&css::sdbc::XRow::getShort
, columnIndex
);
1812 sal_Int32 SAL_CALL CachedContentResultSet
1813 ::getInt( sal_Int32 columnIndex
)
1815 return rowOriginGet
<sal_Int32
>(&css::sdbc::XRow::getInt
, columnIndex
);
1819 sal_Int64 SAL_CALL CachedContentResultSet
1820 ::getLong( sal_Int32 columnIndex
)
1822 return rowOriginGet
<sal_Int64
>(&css::sdbc::XRow::getLong
, columnIndex
);
1826 float SAL_CALL CachedContentResultSet
1827 ::getFloat( sal_Int32 columnIndex
)
1829 return rowOriginGet
<float>(&css::sdbc::XRow::getFloat
, columnIndex
);
1833 double SAL_CALL CachedContentResultSet
1834 ::getDouble( sal_Int32 columnIndex
)
1836 return rowOriginGet
<double>(&css::sdbc::XRow::getDouble
, columnIndex
);
1840 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
1841 ::getBytes( sal_Int32 columnIndex
)
1843 return rowOriginGet
< css::uno::Sequence
<sal_Int8
> >(
1844 &css::sdbc::XRow::getBytes
, columnIndex
);
1848 Date SAL_CALL CachedContentResultSet
1849 ::getDate( sal_Int32 columnIndex
)
1851 return rowOriginGet
<css::util::Date
>(
1852 &css::sdbc::XRow::getDate
, columnIndex
);
1856 Time SAL_CALL CachedContentResultSet
1857 ::getTime( sal_Int32 columnIndex
)
1859 return rowOriginGet
<css::util::Time
>(
1860 &css::sdbc::XRow::getTime
, columnIndex
);
1864 DateTime SAL_CALL CachedContentResultSet
1865 ::getTimestamp( sal_Int32 columnIndex
)
1867 return rowOriginGet
<css::util::DateTime
>(
1868 &css::sdbc::XRow::getTimestamp
, columnIndex
);
1872 Reference
< css::io::XInputStream
>
1873 SAL_CALL CachedContentResultSet
1874 ::getBinaryStream( sal_Int32 columnIndex
)
1876 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1877 &css::sdbc::XRow::getBinaryStream
, columnIndex
);
1881 Reference
< css::io::XInputStream
>
1882 SAL_CALL CachedContentResultSet
1883 ::getCharacterStream( sal_Int32 columnIndex
)
1885 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1886 &css::sdbc::XRow::getCharacterStream
, columnIndex
);
1890 Any SAL_CALL CachedContentResultSet
1891 ::getObject( sal_Int32 columnIndex
,
1893 css::container::XNameAccess
>& typeMap
)
1895 //if you change this function please pay attention to
1896 //function template rowOriginGet, where this is similar implemented
1898 std::unique_lock
aGuard(m_aMutex
);
1899 sal_Int32 nRow
= m_nRow
;
1900 sal_Int32 nFetchSize
= m_nFetchSize
;
1901 sal_Int32 nFetchDirection
= m_nFetchDirection
;
1902 if( !m_aCache
.hasRow( nRow
) )
1904 if( !m_aCache
.hasCausedException( nRow
) )
1906 if( !m_xFetchProvider
.is() )
1908 OSL_FAIL( "broadcaster was disposed already" );
1911 impl_fetchData( aGuard
, nRow
, nFetchSize
, nFetchDirection
);
1913 if( !m_aCache
.hasRow( nRow
) )
1915 m_bLastReadWasFromCache
= false;
1916 applyPositionToOrigin( aGuard
, nRow
);
1917 impl_init_xRowOrigin(aGuard
);
1919 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
1922 //@todo: pay attention to typeMap
1923 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
1924 m_bLastReadWasFromCache
= true;
1925 m_bLastCachedReadWasNull
= !rValue
.hasValue();
1930 Reference
< XRef
> SAL_CALL CachedContentResultSet
1931 ::getRef( sal_Int32 columnIndex
)
1933 return rowOriginGet
< css::uno::Reference
<css::sdbc::XRef
> >(
1934 &css::sdbc::XRow::getRef
, columnIndex
);
1938 Reference
< XBlob
> SAL_CALL CachedContentResultSet
1939 ::getBlob( sal_Int32 columnIndex
)
1941 return rowOriginGet
< css::uno::Reference
<css::sdbc::XBlob
> >(
1942 &css::sdbc::XRow::getBlob
, columnIndex
);
1946 Reference
< XClob
> SAL_CALL CachedContentResultSet
1947 ::getClob( sal_Int32 columnIndex
)
1949 return rowOriginGet
< css::uno::Reference
<css::sdbc::XClob
> >(
1950 &css::sdbc::XRow::getClob
, columnIndex
);
1954 Reference
< XArray
> SAL_CALL CachedContentResultSet
1955 ::getArray( sal_Int32 columnIndex
)
1957 return rowOriginGet
< css::uno::Reference
<css::sdbc::XArray
> >(
1958 &css::sdbc::XRow::getArray
, columnIndex
);
1962 // Type Converter Support
1965 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter(std::unique_lock
<std::mutex
>& )
1967 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
1969 m_bTriedToGetTypeConverter
= true;
1970 m_xTypeConverter
.set( Converter::create(m_xContext
) );
1972 OSL_ENSURE( m_xTypeConverter
.is(),
1973 "PropertyValueSet::getTypeConverter() - "
1974 "Service 'com.sun.star.script.Converter' n/a!" );
1976 return m_xTypeConverter
;
1982 CachedContentResultSetFactory::CachedContentResultSetFactory(
1983 const Reference
< XComponentContext
> & rxContext
)
1985 m_xContext
= rxContext
;
1988 CachedContentResultSetFactory::~CachedContentResultSetFactory()
1992 // CachedContentResultSetFactory XServiceInfo methods.
1994 OUString SAL_CALL
CachedContentResultSetFactory::getImplementationName()
1996 return u
"com.sun.star.comp.ucb.CachedContentResultSetFactory"_ustr
;
1998 sal_Bool SAL_CALL
CachedContentResultSetFactory::supportsService( const OUString
& ServiceName
)
2000 return cppu::supportsService( this, ServiceName
);
2002 css::uno::Sequence
< OUString
> SAL_CALL
CachedContentResultSetFactory::getSupportedServiceNames()
2004 return { u
"com.sun.star.ucb.CachedContentResultSetFactory"_ustr
};
2007 // Service factory implementation.
2011 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
2012 ucb_CachedContentResultSetFactory_get_implementation(
2013 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
2015 return cppu::acquire(new CachedContentResultSetFactory(context
));
2019 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2023 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2024 ::createCachedContentResultSet(
2025 const Reference
< XResultSet
> & xSource
,
2026 const Reference
< XContentIdentifierMapping
> & xMapping
)
2028 Reference
< XResultSet
> xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2032 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */