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>
37 using namespace com::sun::star::beans
;
38 using namespace com::sun::star::lang
;
39 using namespace com::sun::star::script
;
40 using namespace com::sun::star::sdbc
;
41 using namespace com::sun::star::ucb
;
42 using namespace com::sun::star::uno
;
43 using namespace com::sun::star::util
;
47 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
48 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
50 //if you change this function template please pay attention to
51 //function getObject, where this is similar implemented
53 template<typename T
> T
CachedContentResultSet::rowOriginGet(
54 T (SAL_CALL
css::sdbc::XRow::* f
)(sal_Int32
), sal_Int32 columnIndex
)
56 impl_EnsureNotDisposed();
57 osl::ResettableMutexGuard
aGuard(m_aMutex
);
58 sal_Int32 nRow
= m_nRow
;
59 sal_Int32 nFetchSize
= m_nFetchSize
;
60 sal_Int32 nFetchDirection
= m_nFetchDirection
;
61 if( !m_aCache
.hasRow( nRow
) )
63 bool isCleared
= false;
64 if( !m_aCache
.hasCausedException( nRow
) )
66 if( !m_xFetchProvider
.is() )
68 OSL_FAIL( "broadcaster was disposed already" );
73 if( impl_isForwardOnly() )
74 applyPositionToOrigin( nRow
);
76 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
82 if( !m_aCache
.hasRow( nRow
) )
84 m_bLastReadWasFromCache
= false;
86 applyPositionToOrigin( nRow
);
87 impl_init_xRowOrigin();
88 return (m_xRowOrigin
.get()->*f
)( columnIndex
);
91 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
93 m_bLastReadWasFromCache
= true;
94 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
95 /* Last chance. Try type converter service... */
96 if ( m_bLastCachedReadWasNull
&& rValue
.hasValue() )
98 Reference
< XTypeConverter
> xConverter
= getTypeConverter();
99 if ( xConverter
.is() )
103 Any aConvAny
= xConverter
->convertTo(
105 cppu::UnoType
<T
>::get() );
106 m_bLastCachedReadWasNull
= !( aConvAny
>>= aRet
);
108 catch (const IllegalArgumentException
&)
111 catch (const CannotConvertException
&)
120 // CCRS_Cache methods
123 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
124 const Reference
< XContentIdentifierMapping
> & xMapping
)
125 : m_xContentIdentifierMapping( xMapping
)
129 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
133 void CachedContentResultSet::CCRS_Cache
137 m_pMappedReminder
.reset();
140 void CachedContentResultSet::CCRS_Cache
141 ::loadData( const FetchResult
& rResult
)
144 m_pResult
.reset( new FetchResult( rResult
) );
147 bool CachedContentResultSet::CCRS_Cache
148 ::hasRow( sal_Int32 row
)
152 sal_Int32 nStart
= m_pResult
->StartIndex
;
153 sal_Int32 nEnd
= nStart
;
154 if( m_pResult
->Orientation
)
155 nEnd
+= m_pResult
->Rows
.getLength() - 1;
157 nStart
-= m_pResult
->Rows
.getLength() + 1;
159 return nStart
<= row
&& row
<= nEnd
;
162 sal_Int32
CachedContentResultSet::CCRS_Cache
167 sal_Int32 nEnd
= m_pResult
->StartIndex
;
168 if( m_pResult
->Orientation
)
169 return nEnd
+ m_pResult
->Rows
.getLength() - 1;
174 bool CachedContentResultSet::CCRS_Cache
175 ::hasKnownLast() const
180 return ( m_pResult
->FetchError
& FetchError::ENDOFDATA
)
181 && m_pResult
->Orientation
182 && m_pResult
->Rows
.hasElements();
185 bool CachedContentResultSet::CCRS_Cache
186 ::hasCausedException( sal_Int32 nRow
)
190 if( !( m_pResult
->FetchError
& FetchError::EXCEPTION
) )
193 sal_Int32 nEnd
= m_pResult
->StartIndex
;
194 if( m_pResult
->Orientation
)
195 nEnd
+= m_pResult
->Rows
.getLength();
197 return nRow
== nEnd
+1;
200 Any
& CachedContentResultSet::CCRS_Cache
201 ::getRowAny( sal_Int32 nRow
)
204 throw SQLException();
206 throw SQLException();
207 if( !hasRow( nRow
) )
208 throw SQLException();
210 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
214 return (m_pResult
->Rows
)[nDiff
];
217 void CachedContentResultSet::CCRS_Cache
218 ::remindMapped( sal_Int32 nRow
)
220 //remind that this row was mapped
223 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
226 Sequence
< sal_Bool
>* pMappedReminder
= getMappedReminder();
227 if( nDiff
< pMappedReminder
->getLength() )
228 (*pMappedReminder
)[nDiff
] = true;
231 bool CachedContentResultSet::CCRS_Cache
232 ::isRowMapped( sal_Int32 nRow
)
234 if( !m_pMappedReminder
|| !m_pResult
)
236 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
239 if( nDiff
< m_pMappedReminder
->getLength() )
240 return (*m_pMappedReminder
)[nDiff
];
244 Sequence
< sal_Bool
>* CachedContentResultSet::CCRS_Cache
245 ::getMappedReminder()
247 if( !m_pMappedReminder
)
249 sal_Int32 nCount
= m_pResult
->Rows
.getLength();
250 m_pMappedReminder
.reset(new Sequence
< sal_Bool
>( nCount
));
251 std::fill(m_pMappedReminder
->begin(), m_pMappedReminder
->end(), false);
253 return m_pMappedReminder
.get();
256 const Any
& CachedContentResultSet::CCRS_Cache
257 ::getAny( sal_Int32 nRow
, sal_Int32 nColumnIndex
)
260 throw SQLException();
261 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
263 Any
& rRow
= getRowAny( nRow
);
264 Sequence
< Any
> aValue
;
266 if( m_xContentIdentifierMapping
->mapRow( aValue
) )
269 remindMapped( nRow
);
272 m_xContentIdentifierMapping
.clear();
274 auto & rowAny
= getRowAny(nRow
);
275 auto rRow
= o3tl::doAccess
<Sequence
<Any
>>(rowAny
);
277 if( nColumnIndex
> rRow
->getLength() )
278 throw SQLException();
279 return (*rRow
)[nColumnIndex
-1];
282 OUString
const & CachedContentResultSet::CCRS_Cache
283 ::getContentIdentifierString( sal_Int32 nRow
)
287 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
289 Any
& rRow
= getRowAny( nRow
);
292 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifierString( aValue
);
293 remindMapped( nRow
);
295 return *o3tl::doAccess
<OUString
>(getRowAny(nRow
));
297 catch(const SQLException
& ex
)
299 css::uno::Any anyEx
= cppu::getCaughtException();
300 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
301 css::uno::Reference
< css::uno::XInterface
>(),
306 Reference
< XContentIdentifier
> CachedContentResultSet::CCRS_Cache
307 ::getContentIdentifier( sal_Int32 nRow
)
311 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
313 Any
& rRow
= getRowAny( nRow
);
314 Reference
< XContentIdentifier
> aValue
;
316 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifier( aValue
);
317 remindMapped( nRow
);
319 return *o3tl::doAccess
<Reference
<XContentIdentifier
>>(getRowAny(nRow
));
321 catch(const SQLException
& ex
)
323 css::uno::Any anyEx
= cppu::getCaughtException();
324 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
325 css::uno::Reference
< css::uno::XInterface
>(),
330 Reference
< XContent
> CachedContentResultSet::CCRS_Cache
331 ::getContent( sal_Int32 nRow
)
335 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
337 Any
& rRow
= getRowAny( nRow
);
338 Reference
< XContent
> aValue
;
340 rRow
<<= m_xContentIdentifierMapping
->mapContent( aValue
);
341 remindMapped( nRow
);
343 return *o3tl::doAccess
<Reference
<XContent
>>(getRowAny(nRow
));
345 catch (const SQLException
& ex
)
347 css::uno::Any anyEx
= cppu::getCaughtException();
348 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
349 css::uno::Reference
< css::uno::XInterface
>(),
357 class CCRS_PropertySetInfo
:
358 public cppu::OWeakObject
,
359 public css::lang::XTypeProvider
,
360 public css::beans::XPropertySetInfo
362 friend class CachedContentResultSet
;
365 std::unique_ptr
<Sequence
< css::beans::Property
>>
368 sal_Int32 m_nFetchSizePropertyHandle
;
369 sal_Int32 m_nFetchDirectionPropertyHandle
;
373 impl_getRemainedHandle() const;
377 const OUString
& rName
378 , css::beans::Property
& rProp
) const;
380 impl_getPos( const OUString
& rName
) const;
383 impl_isMyPropertyName( const OUString
& rName
);
386 explicit CCRS_PropertySetInfo( Reference
<
387 XPropertySetInfo
> const & xPropertySetInfoOrigin
);
390 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
) override
;
391 virtual void SAL_CALL
acquire()
393 virtual void SAL_CALL
release()
397 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
398 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes() override
;
401 virtual Sequence
< css::beans::Property
> SAL_CALL
402 getProperties() override
;
404 virtual css::beans::Property SAL_CALL
405 getPropertyByName( const OUString
& aName
) override
;
407 virtual sal_Bool SAL_CALL
408 hasPropertyByName( const OUString
& Name
) override
;
411 //some helping variables ( names for my special properties )
412 const char g_sPropertyNameForCount
[] = "RowCount";
413 const char g_sPropertyNameForFinalCount
[] = "IsRowCountFinal";
414 const char g_sPropertyNameForFetchSize
[] = "FetchSize";
415 const char g_sPropertyNameForFetchDirection
[] = "FetchDirection";
417 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
418 Reference
< XPropertySetInfo
> const & xInfo
)
419 : m_nFetchSizePropertyHandle( -1 )
420 , m_nFetchDirectionPropertyHandle( -1 )
422 //initialize list of properties:
424 // it is required, that the received xInfo contains the two
425 // properties with names 'g_sPropertyNameForCount' and
426 // 'g_sPropertyNameForFinalCount'
430 Sequence
<Property
> aProps
= xInfo
->getProperties();
431 m_pProperties
.reset( new Sequence
<Property
> ( aProps
) );
435 OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
436 m_pProperties
.reset( new Sequence
<Property
> );
439 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
440 sal_Int32 nFetchSize
= impl_getPos( g_sPropertyNameForFetchSize
);
441 sal_Int32 nFetchDirection
= impl_getPos( g_sPropertyNameForFetchDirection
);
442 sal_Int32 nDeleted
= 0;
443 if( nFetchSize
!= -1 )
445 if( nFetchDirection
!= -1 )
448 std::unique_ptr
<Sequence
< Property
> > pOrigProps(new Sequence
<Property
> ( *m_pProperties
));
449 sal_Int32 nOrigProps
= pOrigProps
->getLength();
451 m_pProperties
->realloc( nOrigProps
+ 2 - nDeleted
);//note that nDeleted is <= 2
452 for( sal_Int32 n
= 0, m
= 0; n
< nOrigProps
; n
++, m
++ )
454 if( n
== nFetchSize
|| n
== nFetchDirection
)
457 (*m_pProperties
)[ m
] = (*pOrigProps
)[ n
];
460 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
];
461 rMyProp
.Name
= g_sPropertyNameForFetchSize
;
462 rMyProp
.Type
= cppu::UnoType
<sal_Int32
>::get();
463 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
465 if( nFetchSize
!= -1 )
466 m_nFetchSizePropertyHandle
= (*pOrigProps
)[nFetchSize
].Handle
;
468 m_nFetchSizePropertyHandle
= impl_getRemainedHandle();
470 rMyProp
.Handle
= m_nFetchSizePropertyHandle
;
474 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
+ 1 ];
475 rMyProp
.Name
= g_sPropertyNameForFetchDirection
;
476 rMyProp
.Type
= cppu::UnoType
<sal_Bool
>::get();
477 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
479 m_nFetchDirectionPropertyHandle
= rMyProp
.Handle
;
483 // XInterface methods.
485 void SAL_CALL
CCRS_PropertySetInfo::acquire()
488 OWeakObject::acquire();
491 void SAL_CALL
CCRS_PropertySetInfo::release()
494 OWeakObject::release();
497 css::uno::Any SAL_CALL
CCRS_PropertySetInfo::queryInterface( const css::uno::Type
& rType
)
499 css::uno::Any aRet
= cppu::queryInterface( rType
,
500 static_cast< XTypeProvider
* >(this),
501 static_cast< XPropertySetInfo
* >(this)
503 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
506 // XTypeProvider methods.
508 //list all interfaces exclusive baseclasses
509 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
514 // XPropertySetInfo methods.
517 Sequence
< Property
> SAL_CALL CCRS_PropertySetInfo
520 return *m_pProperties
;
524 Property SAL_CALL CCRS_PropertySetInfo
525 ::getPropertyByName( const OUString
& aName
)
528 if ( impl_queryProperty( aName
, aProp
) )
531 throw UnknownPropertyException(aName
);
535 sal_Bool SAL_CALL CCRS_PropertySetInfo
536 ::hasPropertyByName( const OUString
& Name
)
538 return ( impl_getPos( Name
) != -1 );
545 sal_Int32 CCRS_PropertySetInfo
546 ::impl_getPos( const OUString
& rName
) const
548 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
550 const Property
& rMyProp
= (*m_pProperties
)[nN
];
551 if( rMyProp
.Name
== rName
)
557 bool CCRS_PropertySetInfo
558 ::impl_queryProperty( const OUString
& rName
, Property
& rProp
) const
560 for( const Property
& rMyProp
: std::as_const(*m_pProperties
) )
562 if( rMyProp
.Name
== rName
)
564 rProp
.Name
= rMyProp
.Name
;
565 rProp
.Handle
= rMyProp
.Handle
;
566 rProp
.Type
= rMyProp
.Type
;
567 rProp
.Attributes
= rMyProp
.Attributes
;
576 bool CCRS_PropertySetInfo
577 ::impl_isMyPropertyName( const OUString
& rPropertyName
)
579 return ( rPropertyName
== g_sPropertyNameForCount
580 || rPropertyName
== g_sPropertyNameForFinalCount
581 || rPropertyName
== g_sPropertyNameForFetchSize
582 || rPropertyName
== g_sPropertyNameForFetchDirection
);
585 sal_Int32 CCRS_PropertySetInfo
586 ::impl_getRemainedHandle( ) const
588 sal_Int32 nHandle
= 1;
592 OSL_FAIL( "Properties not initialized yet" );
599 for( const auto & rProp
: std::as_const(*m_pProperties
) )
601 if( nHandle
== rProp
.Handle
)
615 CachedContentResultSet::CachedContentResultSet(
616 const Reference
< XComponentContext
> & rxContext
617 , const Reference
< XResultSet
> & xOrigin
618 , const Reference
< XContentIdentifierMapping
> &
619 xContentIdentifierMapping
)
620 : ContentResultSetWrapper( xOrigin
)
622 , m_xContext( rxContext
)
624 , m_xContentIdentifierMapping( xContentIdentifierMapping
)
625 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
626 , m_bAfterLast( false )
627 , m_nLastAppliedPos( 0 )
628 , m_bAfterLastApplied( false )
630 , m_bFinalCount( false )
632 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
)
634 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
)
636 , m_bLastReadWasFromCache( false )
637 , m_bLastCachedReadWasNull( true )
638 , m_aCache( m_xContentIdentifierMapping
)
639 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping
)
640 , m_aCacheContentIdentifier( m_xContentIdentifierMapping
)
641 , m_aCacheContent( m_xContentIdentifierMapping
)
642 , m_bTriedToGetTypeConverter( false )
644 m_xFetchProvider
.set( m_xResultSetOrigin
, UNO_QUERY
);
645 OSL_ENSURE( m_xFetchProvider
.is(), "interface XFetchProvider is required" );
647 m_xFetchProviderForContentAccess
.set( m_xResultSetOrigin
, UNO_QUERY
);
648 OSL_ENSURE( m_xFetchProviderForContentAccess
.is(), "interface XFetchProviderForContentAccess is required" );
653 CachedContentResultSet::~CachedContentResultSet()
656 //do not delete m_pMyPropSetInfo, cause it is hold via reference
663 bool CachedContentResultSet
664 ::applyPositionToOrigin( sal_Int32 nRow
)
666 impl_EnsureNotDisposed();
670 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
674 osl::ResettableMutexGuard
aGuard(m_aMutex
);
675 OSL_ENSURE( nRow
>= 0, "only positive values supported" );
676 if( !m_xResultSetOrigin
.is() )
678 OSL_FAIL( "broadcaster was disposed already" );
681 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
683 sal_Int32 nLastAppliedPos
= m_nLastAppliedPos
;
684 bool bAfterLastApplied
= m_bAfterLastApplied
;
685 bool bAfterLast
= m_bAfterLast
;
686 sal_Int32 nForwardOnly
= m_nForwardOnly
;
690 if( bAfterLastApplied
|| nLastAppliedPos
!= nRow
)
692 if( nForwardOnly
== 1 )
694 if( bAfterLastApplied
|| bAfterLast
|| !nRow
|| nRow
< nLastAppliedPos
)
695 throw SQLException();
697 sal_Int32 nN
= nRow
- nLastAppliedPos
;
699 for( nM
= 0; nN
--; nM
++ )
701 if( !m_xResultSetOrigin
->next() )
706 m_nLastAppliedPos
+= nM
;
707 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
708 return nRow
== m_nLastAppliedPos
;
711 if( !nRow
) //absolute( 0 ) will throw exception
713 m_xResultSetOrigin
->beforeFirst();
716 m_nLastAppliedPos
= 0;
717 m_bAfterLastApplied
= false;
722 //move absolute, if !nLastAppliedPos
723 //because move relative would throw exception
724 if( !nLastAppliedPos
|| bAfterLast
|| bAfterLastApplied
)
726 bool bValid
= m_xResultSetOrigin
->absolute( nRow
);
729 m_nLastAppliedPos
= nRow
;
730 m_bAfterLastApplied
= !bValid
;
735 bool bValid
= m_xResultSetOrigin
->relative( nRow
- nLastAppliedPos
);
738 m_nLastAppliedPos
+= ( nRow
- nLastAppliedPos
);
739 m_bAfterLastApplied
= !bValid
;
743 catch (const SQLException
&)
745 if( !bAfterLastApplied
&& !bAfterLast
&& nRow
> nLastAppliedPos
&& impl_isForwardOnly() )
747 sal_Int32 nN
= nRow
- nLastAppliedPos
;
749 for( nM
= 0; nN
--; nM
++ )
751 if( !m_xResultSetOrigin
->next() )
756 m_nLastAppliedPos
+= nM
;
757 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
763 return nRow
== m_nLastAppliedPos
;
769 //define for fetching data
772 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
773 bool bDirection = !!( \
774 nFetchDirection != FetchDirection::REVERSE ); \
775 FetchResult aResult = \
776 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
777 osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
778 aCache.loadData( aResult ); \
779 sal_Int32 nMax = aCache.getMaxRow(); \
780 sal_Int32 nCurCount = m_nKnownCount; \
781 bool bIsFinalCount = aCache.hasKnownLast(); \
782 bool bCurIsFinalCount = m_bFinalCount; \
784 if( nMax > nCurCount ) \
785 impl_changeRowCount( nCurCount, nMax ); \
786 if( bIsFinalCount && !bCurIsFinalCount ) \
787 impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
789 void CachedContentResultSet
790 ::impl_fetchData( sal_Int32 nRow
791 , sal_Int32 nFetchSize
, sal_Int32 nFetchDirection
)
793 FETCH_XXX( m_aCache
, m_xFetchProvider
, fetch
);
796 void CachedContentResultSet
797 ::impl_changeRowCount( sal_Int32 nOld
, sal_Int32 nNew
)
799 OSL_ENSURE( nNew
> nOld
, "RowCount only can grow" );
803 //create PropertyChangeEvent and set value
804 PropertyChangeEvent aEvt
;
806 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
807 aEvt
.Source
= static_cast< XPropertySet
* >( this );
808 aEvt
.Further
= false;
809 aEvt
.OldValue
<<= nOld
;
810 aEvt
.NewValue
<<= nNew
;
812 m_nKnownCount
= nNew
;
815 //send PropertyChangeEvent to listeners
816 impl_notifyPropertyChangeListeners( aEvt
);
819 void CachedContentResultSet
820 ::impl_changeIsRowCountFinal( bool bOld
, bool bNew
)
822 OSL_ENSURE( !bOld
&& bNew
, "This change is not allowed for IsRowCountFinal" );
826 //create PropertyChangeEvent and set value
827 PropertyChangeEvent aEvt
;
829 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
830 aEvt
.Source
= static_cast< XPropertySet
* >( this );
831 aEvt
.Further
= false;
832 aEvt
.OldValue
<<= bOld
;
833 aEvt
.NewValue
<<= bNew
;
835 m_bFinalCount
= bNew
;
838 //send PropertyChangeEvent to listeners
839 impl_notifyPropertyChangeListeners( aEvt
);
842 bool CachedContentResultSet
843 ::impl_isKnownValidPosition( sal_Int32 nRow
)
845 return m_nKnownCount
&& nRow
846 && nRow
<= m_nKnownCount
;
849 bool CachedContentResultSet
850 ::impl_isKnownInvalidPosition( sal_Int32 nRow
)
856 return nRow
> m_nKnownCount
;
861 void CachedContentResultSet
862 ::impl_initPropertySetInfo()
864 ContentResultSetWrapper::impl_initPropertySetInfo();
866 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
867 if( m_xMyPropertySetInfo
.is() )
869 m_xMyPropertySetInfo
= new CCRS_PropertySetInfo( m_xPropertySetInfo
);
870 m_xPropertySetInfo
= m_xMyPropertySetInfo
.get();
874 // XInterface methods.
875 void SAL_CALL
CachedContentResultSet::acquire()
878 OWeakObject::acquire();
881 void SAL_CALL
CachedContentResultSet::release()
884 OWeakObject::release();
887 Any SAL_CALL CachedContentResultSet
888 ::queryInterface( const Type
& rType
)
890 //list all interfaces inclusive baseclasses of interfaces
892 Any aRet
= ContentResultSetWrapper::queryInterface( rType
);
893 if( aRet
.hasValue() )
896 aRet
= cppu::queryInterface( rType
,
897 static_cast< XTypeProvider
* >( this ),
898 static_cast< XServiceInfo
* >( this ) );
900 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
904 // XTypeProvider methods.
906 //list all interfaces exclusive baseclasses
907 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
912 , XResultSetMetaDataSupplier
915 , XPropertyChangeListener
916 , XVetoableChangeListener
924 // XServiceInfo methods.
926 OUString SAL_CALL
CachedContentResultSet::getImplementationName()
928 return "com.sun.star.comp.ucb.CachedContentResultSet";
931 sal_Bool SAL_CALL
CachedContentResultSet::supportsService( const OUString
& ServiceName
)
933 return cppu::supportsService( this, ServiceName
);
936 css::uno::Sequence
< OUString
> SAL_CALL
CachedContentResultSet::getSupportedServiceNames()
938 return { "com.sun.star.ucb.CachedContentResultSet" };
943 // XPropertySet methods. ( inherited )
947 void SAL_CALL CachedContentResultSet
948 ::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
950 impl_EnsureNotDisposed();
952 if( !getPropertySetInfo().is() )
954 OSL_FAIL( "broadcaster was disposed already" );
955 throw UnknownPropertyException();
958 Property aProp
= m_xMyPropertySetInfo
->getPropertyByName( aPropertyName
);
959 //throws UnknownPropertyException, if so
961 if( aProp
.Attributes
& PropertyAttribute::READONLY
)
963 //It is assumed, that the properties
964 //'RowCount' and 'IsRowCountFinal' are readonly!
965 throw IllegalArgumentException();
967 if( aProp
.Name
== g_sPropertyNameForFetchDirection
)
971 if( !( aValue
>>= nNew
) )
973 throw IllegalArgumentException();
976 if( nNew
== FetchDirection::UNKNOWN
)
978 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
;
980 else if( nNew
!= FetchDirection::FORWARD
&& nNew
!= FetchDirection::REVERSE
)
982 throw IllegalArgumentException();
985 //create PropertyChangeEvent and set value
986 PropertyChangeEvent aEvt
;
988 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
989 aEvt
.Source
= static_cast< XPropertySet
* >( this );
990 aEvt
.PropertyName
= aPropertyName
;
991 aEvt
.Further
= false;
992 aEvt
.PropertyHandle
= m_xMyPropertySetInfo
->
993 m_nFetchDirectionPropertyHandle
;
994 aEvt
.OldValue
<<= m_nFetchDirection
;
995 aEvt
.NewValue
<<= nNew
;
997 m_nFetchDirection
= nNew
;
1000 //send PropertyChangeEvent to listeners
1001 impl_notifyPropertyChangeListeners( aEvt
);
1003 else if( aProp
.Name
== g_sPropertyNameForFetchSize
)
1007 if( !( aValue
>>= nNew
) )
1009 throw IllegalArgumentException();
1014 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
;
1017 //create PropertyChangeEvent and set value
1018 PropertyChangeEvent aEvt
;
1020 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1021 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1022 aEvt
.PropertyName
= aPropertyName
;
1023 aEvt
.Further
= false;
1024 aEvt
.PropertyHandle
= m_xMyPropertySetInfo
->
1025 m_nFetchSizePropertyHandle
;
1026 aEvt
.OldValue
<<= m_nFetchSize
;
1027 aEvt
.NewValue
<<= nNew
;
1029 m_nFetchSize
= nNew
;
1032 //send PropertyChangeEvent to listeners
1033 impl_notifyPropertyChangeListeners( aEvt
);
1037 impl_init_xPropertySetOrigin();
1039 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1040 if( !m_xPropertySetOrigin
.is() )
1042 OSL_FAIL( "broadcaster was disposed already" );
1046 m_xPropertySetOrigin
->setPropertyValue( aPropertyName
, aValue
);
1052 Any SAL_CALL CachedContentResultSet
1053 ::getPropertyValue( const OUString
& rPropertyName
)
1055 impl_EnsureNotDisposed();
1057 if( !getPropertySetInfo().is() )
1059 OSL_FAIL( "broadcaster was disposed already" );
1060 throw UnknownPropertyException();
1063 m_xMyPropertySetInfo
->getPropertyByName( rPropertyName
);
1064 //throws UnknownPropertyException, if so
1067 if( rPropertyName
== g_sPropertyNameForCount
)
1069 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1070 aValue
<<= m_nKnownCount
;
1072 else if( rPropertyName
== g_sPropertyNameForFinalCount
)
1074 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1075 aValue
<<= m_bFinalCount
;
1077 else if( rPropertyName
== g_sPropertyNameForFetchSize
)
1079 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1080 aValue
<<= m_nFetchSize
;
1082 else if( rPropertyName
== g_sPropertyNameForFetchDirection
)
1084 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1085 aValue
<<= m_nFetchDirection
;
1089 impl_init_xPropertySetOrigin();
1091 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1092 if( !m_xPropertySetOrigin
.is() )
1094 OSL_FAIL( "broadcaster was disposed already" );
1095 throw UnknownPropertyException();
1098 aValue
= m_xPropertySetOrigin
->getPropertyValue( rPropertyName
);
1104 // own methods. ( inherited )
1108 void CachedContentResultSet
1109 ::impl_disposing( const EventObject
& rEventObject
)
1112 impl_EnsureNotDisposed();
1113 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1114 //release all references to the broadcaster:
1115 m_xFetchProvider
.clear();
1116 m_xFetchProviderForContentAccess
.clear();
1118 ContentResultSetWrapper::impl_disposing( rEventObject
);
1122 void CachedContentResultSet
1123 ::impl_propertyChange( const PropertyChangeEvent
& rEvt
)
1125 impl_EnsureNotDisposed();
1127 PropertyChangeEvent
aEvt( rEvt
);
1128 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1129 aEvt
.Further
= false;
1132 if( CCRS_PropertySetInfo
1133 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1135 //don't notify foreign events on fetchsize and fetchdirection
1136 if( aEvt
.PropertyName
== g_sPropertyNameForFetchSize
1137 || aEvt
.PropertyName
== g_sPropertyNameForFetchDirection
)
1140 //adjust my props 'RowCount' and 'IsRowCountFinal'
1141 if( aEvt
.PropertyName
== g_sPropertyNameForCount
)
1146 if( !( aEvt
.NewValue
>>= nNew
) )
1148 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1152 impl_changeRowCount( m_nKnownCount
, nNew
);
1154 else if( aEvt
.PropertyName
== g_sPropertyNameForFinalCount
)
1155 {//IsRowCountFinal changed
1159 if( !( aEvt
.NewValue
>>= bNew
) )
1161 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1164 impl_changeIsRowCountFinal( m_bFinalCount
, bNew
);
1170 impl_notifyPropertyChangeListeners( aEvt
);
1175 void CachedContentResultSet
1176 ::impl_vetoableChange( const PropertyChangeEvent
& rEvt
)
1178 impl_EnsureNotDisposed();
1180 //don't notify events on my properties, cause they are not vetoable
1181 if( CCRS_PropertySetInfo
1182 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1188 PropertyChangeEvent
aEvt( rEvt
);
1189 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1190 aEvt
.Further
= false;
1192 impl_notifyVetoableChangeListeners( aEvt
);
1196 // XContentAccess methods. ( inherited ) ( -- position dependent )
1199 #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1200 impl_EnsureNotDisposed(); \
1201 osl::ResettableMutexGuard aGuard(m_aMutex); \
1202 sal_Int32 nRow = m_nRow; \
1203 sal_Int32 nFetchSize = m_nFetchSize; \
1204 sal_Int32 nFetchDirection = m_nFetchDirection; \
1205 if( !m_aCache##XXX.hasRow( nRow ) ) \
1209 bool isCleared = false; \
1210 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1212 if( !m_xFetchProviderForContentAccess.is() ) \
1214 OSL_FAIL( "broadcaster was disposed already" ); \
1215 throw RuntimeException(); \
1219 if( impl_isForwardOnly() ) \
1220 applyPositionToOrigin( nRow ); \
1222 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1228 if( !m_aCache##XXX.hasRow( nRow ) ) \
1231 applyPositionToOrigin( nRow ); \
1232 TYPE aRet = ContentResultSetWrapper::queryXXX();\
1233 if( m_xContentIdentifierMapping.is() ) \
1234 return m_xContentIdentifierMapping->map##XXX( aRet );\
1238 catch (const RuntimeException&) \
1242 catch (const Exception& e) \
1244 Any a(cppu::getCaughtException()); \
1245 throw WrappedTargetRuntimeException( \
1246 "wrapped Exception " + e.Message, \
1247 Reference<XInterface>(), a); \
1250 return m_aCache##XXX.get##XXX( nRow );
1253 OUString SAL_CALL CachedContentResultSet
1254 ::queryContentIdentifierString()
1256 XCONTENTACCESS_queryXXX( queryContentIdentifierString
, ContentIdentifierString
, OUString
)
1261 Reference
< XContentIdentifier
> SAL_CALL CachedContentResultSet
1262 ::queryContentIdentifier()
1264 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1269 Reference
< XContent
> SAL_CALL CachedContentResultSet
1272 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1276 // XResultSet methods. ( inherited )
1280 sal_Bool SAL_CALL CachedContentResultSet
1283 impl_EnsureNotDisposed();
1285 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1295 m_bAfterLast
= true;
1299 //known valid position
1300 if( impl_isKnownValidPosition( m_nRow
+ 1 ) )
1307 sal_Int32 nRow
= m_nRow
;
1310 bool bValid
= applyPositionToOrigin( nRow
+ 1 );
1314 m_bAfterLast
= !bValid
;
1319 sal_Bool SAL_CALL CachedContentResultSet
1322 impl_EnsureNotDisposed();
1324 if( impl_isForwardOnly() )
1325 throw SQLException();
1327 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1329 if( !m_bAfterLast
&& !m_nRow
)
1332 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1335 m_bAfterLast
= false;
1338 //known valid position ?:
1339 if( impl_isKnownValidPosition( m_nRow
- 1 ) )
1342 m_bAfterLast
= false;
1346 sal_Int32 nRow
= m_nRow
;
1349 bool bValid
= applyPositionToOrigin( nRow
- 1 );
1353 m_bAfterLast
= false;
1358 sal_Bool SAL_CALL CachedContentResultSet
1359 ::absolute( sal_Int32 row
)
1361 impl_EnsureNotDisposed();
1364 throw SQLException();
1366 if( impl_isForwardOnly() )
1367 throw SQLException();
1369 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1371 if( !m_xResultSetOrigin
.is() )
1373 OSL_FAIL( "broadcaster was disposed already" );
1380 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1388 m_bAfterLast
= false;
1391 //unknown final count:
1394 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1399 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1402 m_nLastAppliedPos
= nNewRow
;
1404 m_bAfterLastApplied
= m_bAfterLast
= false;
1409 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1412 m_nLastAppliedPos
= nCurRow
;
1414 m_bAfterLast
= false;
1415 return nCurRow
!= 0;
1420 if( row
> m_nKnownCount
)
1422 m_nRow
= m_nKnownCount
+ 1;
1423 m_bAfterLast
= true;
1427 m_bAfterLast
= false;
1430 //unknown new position:
1433 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1438 sal_Int32 nNewRow
= row
;
1439 if( nNewRow
> m_nKnownCount
)
1441 nNewRow
= m_nKnownCount
+ 1;
1442 m_bAfterLastApplied
= m_bAfterLast
= true;
1445 m_bAfterLastApplied
= m_bAfterLast
= false;
1447 m_nLastAppliedPos
= nNewRow
;
1453 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1454 bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1457 m_nLastAppliedPos
= nCurRow
;
1459 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1460 return nCurRow
&& !bIsAfterLast
;
1464 sal_Bool SAL_CALL CachedContentResultSet
1465 ::relative( sal_Int32 rows
)
1467 impl_EnsureNotDisposed();
1469 if( impl_isForwardOnly() )
1470 throw SQLException();
1472 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1473 if( m_bAfterLast
|| impl_isKnownInvalidPosition( m_nRow
) )
1474 throw SQLException();
1479 sal_Int32 nNewRow
= m_nRow
+ rows
;
1483 if( impl_isKnownValidPosition( nNewRow
) )
1486 m_bAfterLast
= false;
1491 //known invalid new position:
1494 m_bAfterLast
= false;
1498 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1500 m_bAfterLast
= true;
1501 m_nRow
= m_nKnownCount
+ 1;
1504 //unknown new position:
1506 bool bValid
= applyPositionToOrigin( nNewRow
);
1510 m_bAfterLast
= !bValid
; // only nNewRow > 0 possible here
1517 sal_Bool SAL_CALL CachedContentResultSet
1520 impl_EnsureNotDisposed();
1522 if( impl_isForwardOnly() )
1523 throw SQLException();
1525 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1526 if( impl_isKnownValidPosition( 1 ) )
1529 m_bAfterLast
= false;
1532 if( impl_isKnownInvalidPosition( 1 ) )
1535 m_bAfterLast
= false;
1541 bool bValid
= applyPositionToOrigin( 1 );
1545 m_bAfterLast
= false;
1550 sal_Bool SAL_CALL CachedContentResultSet
1553 impl_EnsureNotDisposed();
1555 if( impl_isForwardOnly() )
1556 throw SQLException();
1558 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1561 m_nRow
= m_nKnownCount
;
1562 m_bAfterLast
= false;
1563 return m_nKnownCount
!= 0;
1566 if( !m_xResultSetOrigin
.is() )
1568 OSL_FAIL( "broadcaster was disposed already" );
1573 bool bValid
= m_xResultSetOrigin
->last();
1576 m_bAfterLastApplied
= m_bAfterLast
= false;
1579 m_nLastAppliedPos
= m_nKnownCount
;
1580 m_nRow
= m_nKnownCount
;
1585 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1588 m_nLastAppliedPos
= nCurRow
;
1590 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1591 m_nKnownCount
= nCurRow
;
1592 m_bFinalCount
= true;
1593 return nCurRow
!= 0;
1597 void SAL_CALL CachedContentResultSet
1600 impl_EnsureNotDisposed();
1602 if( impl_isForwardOnly() )
1603 throw SQLException();
1605 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1607 m_bAfterLast
= false;
1611 void SAL_CALL CachedContentResultSet
1614 impl_EnsureNotDisposed();
1616 if( impl_isForwardOnly() )
1617 throw SQLException();
1619 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1621 m_bAfterLast
= true;
1625 sal_Bool SAL_CALL CachedContentResultSet
1628 impl_EnsureNotDisposed();
1630 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1634 return m_bAfterLast
;
1638 if( !m_xResultSetOrigin
.is() )
1640 OSL_FAIL( "broadcaster was disposed already" );
1645 //find out whether the original resultset contains rows or not
1646 m_xResultSetOrigin
->afterLast();
1649 m_bAfterLastApplied
= true;
1652 return m_xResultSetOrigin
->isAfterLast();
1656 sal_Bool SAL_CALL CachedContentResultSet
1659 impl_EnsureNotDisposed();
1661 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1671 if( !m_xResultSetOrigin
.is() )
1673 OSL_FAIL( "broadcaster was disposed already" );
1678 //find out whether the original resultset contains rows or not
1679 m_xResultSetOrigin
->beforeFirst();
1682 m_bAfterLastApplied
= false;
1683 m_nLastAppliedPos
= 0;
1686 return m_xResultSetOrigin
->isBeforeFirst();
1690 sal_Bool SAL_CALL CachedContentResultSet
1693 impl_EnsureNotDisposed();
1696 Reference
< XResultSet
> xResultSetOrigin
;
1699 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1710 xResultSetOrigin
= m_xResultSetOrigin
;
1713 //need to ask origin
1715 if( applyPositionToOrigin( nRow
) )
1716 return xResultSetOrigin
->isFirst();
1723 sal_Bool SAL_CALL CachedContentResultSet
1726 impl_EnsureNotDisposed();
1729 Reference
< XResultSet
> xResultSetOrigin
;
1731 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1734 if( m_nRow
< m_nKnownCount
)
1737 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1740 xResultSetOrigin
= m_xResultSetOrigin
;
1743 //need to ask origin
1745 if( applyPositionToOrigin( nRow
) )
1746 return xResultSetOrigin
->isLast();
1754 sal_Int32 SAL_CALL CachedContentResultSet
1757 impl_EnsureNotDisposed();
1759 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1766 void SAL_CALL CachedContentResultSet
1769 impl_EnsureNotDisposed();
1771 //the ContentResultSet is static and will not change
1772 //therefore we don't need to reload anything
1776 sal_Bool SAL_CALL CachedContentResultSet
1779 impl_EnsureNotDisposed();
1781 //the ContentResultSet is static and will not change
1785 sal_Bool SAL_CALL CachedContentResultSet
1788 impl_EnsureNotDisposed();
1790 //the ContentResultSet is static and will not change
1795 sal_Bool SAL_CALL CachedContentResultSet
1798 impl_EnsureNotDisposed();
1800 //the ContentResultSet is static and will not change
1805 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1808 impl_EnsureNotDisposed();
1809 //@todo ?return anything
1810 return Reference
< XInterface
>();
1814 // XRow methods. ( inherited )
1818 sal_Bool SAL_CALL CachedContentResultSet
1821 impl_EnsureNotDisposed();
1822 impl_init_xRowOrigin();
1824 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1825 if( m_bLastReadWasFromCache
)
1826 return m_bLastCachedReadWasNull
;
1827 if( !m_xRowOrigin
.is() )
1829 OSL_FAIL( "broadcaster was disposed already" );
1833 return m_xRowOrigin
->wasNull();
1837 OUString SAL_CALL CachedContentResultSet
1838 ::getString( sal_Int32 columnIndex
)
1840 return rowOriginGet
<OUString
>(&css::sdbc::XRow::getString
, columnIndex
);
1844 sal_Bool SAL_CALL CachedContentResultSet
1845 ::getBoolean( sal_Int32 columnIndex
)
1847 return rowOriginGet
<sal_Bool
>(&css::sdbc::XRow::getBoolean
, columnIndex
);
1851 sal_Int8 SAL_CALL CachedContentResultSet
1852 ::getByte( sal_Int32 columnIndex
)
1854 return rowOriginGet
<sal_Int8
>(&css::sdbc::XRow::getByte
, columnIndex
);
1858 sal_Int16 SAL_CALL CachedContentResultSet
1859 ::getShort( sal_Int32 columnIndex
)
1861 return rowOriginGet
<sal_Int16
>(&css::sdbc::XRow::getShort
, columnIndex
);
1865 sal_Int32 SAL_CALL CachedContentResultSet
1866 ::getInt( sal_Int32 columnIndex
)
1868 return rowOriginGet
<sal_Int32
>(&css::sdbc::XRow::getInt
, columnIndex
);
1872 sal_Int64 SAL_CALL CachedContentResultSet
1873 ::getLong( sal_Int32 columnIndex
)
1875 return rowOriginGet
<sal_Int64
>(&css::sdbc::XRow::getLong
, columnIndex
);
1879 float SAL_CALL CachedContentResultSet
1880 ::getFloat( sal_Int32 columnIndex
)
1882 return rowOriginGet
<float>(&css::sdbc::XRow::getFloat
, columnIndex
);
1886 double SAL_CALL CachedContentResultSet
1887 ::getDouble( sal_Int32 columnIndex
)
1889 return rowOriginGet
<double>(&css::sdbc::XRow::getDouble
, columnIndex
);
1893 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
1894 ::getBytes( sal_Int32 columnIndex
)
1896 return rowOriginGet
< css::uno::Sequence
<sal_Int8
> >(
1897 &css::sdbc::XRow::getBytes
, columnIndex
);
1901 Date SAL_CALL CachedContentResultSet
1902 ::getDate( sal_Int32 columnIndex
)
1904 return rowOriginGet
<css::util::Date
>(
1905 &css::sdbc::XRow::getDate
, columnIndex
);
1909 Time SAL_CALL CachedContentResultSet
1910 ::getTime( sal_Int32 columnIndex
)
1912 return rowOriginGet
<css::util::Time
>(
1913 &css::sdbc::XRow::getTime
, columnIndex
);
1917 DateTime SAL_CALL CachedContentResultSet
1918 ::getTimestamp( sal_Int32 columnIndex
)
1920 return rowOriginGet
<css::util::DateTime
>(
1921 &css::sdbc::XRow::getTimestamp
, columnIndex
);
1925 Reference
< css::io::XInputStream
>
1926 SAL_CALL CachedContentResultSet
1927 ::getBinaryStream( sal_Int32 columnIndex
)
1929 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1930 &css::sdbc::XRow::getBinaryStream
, columnIndex
);
1934 Reference
< css::io::XInputStream
>
1935 SAL_CALL CachedContentResultSet
1936 ::getCharacterStream( sal_Int32 columnIndex
)
1938 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1939 &css::sdbc::XRow::getCharacterStream
, columnIndex
);
1943 Any SAL_CALL CachedContentResultSet
1944 ::getObject( sal_Int32 columnIndex
,
1946 css::container::XNameAccess
>& typeMap
)
1948 //if you change this function please pay attention to
1949 //function template rowOriginGet, where this is similar implemented
1951 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1952 sal_Int32 nRow
= m_nRow
;
1953 sal_Int32 nFetchSize
= m_nFetchSize
;
1954 sal_Int32 nFetchDirection
= m_nFetchDirection
;
1955 if( !m_aCache
.hasRow( nRow
) )
1957 bool isCleared
= false;
1958 if( !m_aCache
.hasCausedException( nRow
) )
1960 if( !m_xFetchProvider
.is() )
1962 OSL_FAIL( "broadcaster was disposed already" );
1968 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
1974 if( !m_aCache
.hasRow( nRow
) )
1976 m_bLastReadWasFromCache
= false;
1978 applyPositionToOrigin( nRow
);
1979 impl_init_xRowOrigin();
1980 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
1983 //@todo: pay attention to typeMap
1984 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
1985 m_bLastReadWasFromCache
= true;
1986 m_bLastCachedReadWasNull
= !rValue
.hasValue();
1991 Reference
< XRef
> SAL_CALL CachedContentResultSet
1992 ::getRef( sal_Int32 columnIndex
)
1994 return rowOriginGet
< css::uno::Reference
<css::sdbc::XRef
> >(
1995 &css::sdbc::XRow::getRef
, columnIndex
);
1999 Reference
< XBlob
> SAL_CALL CachedContentResultSet
2000 ::getBlob( sal_Int32 columnIndex
)
2002 return rowOriginGet
< css::uno::Reference
<css::sdbc::XBlob
> >(
2003 &css::sdbc::XRow::getBlob
, columnIndex
);
2007 Reference
< XClob
> SAL_CALL CachedContentResultSet
2008 ::getClob( sal_Int32 columnIndex
)
2010 return rowOriginGet
< css::uno::Reference
<css::sdbc::XClob
> >(
2011 &css::sdbc::XRow::getClob
, columnIndex
);
2015 Reference
< XArray
> SAL_CALL CachedContentResultSet
2016 ::getArray( sal_Int32 columnIndex
)
2018 return rowOriginGet
< css::uno::Reference
<css::sdbc::XArray
> >(
2019 &css::sdbc::XRow::getArray
, columnIndex
);
2023 // Type Converter Support
2026 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter()
2028 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2030 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
2032 m_bTriedToGetTypeConverter
= true;
2033 m_xTypeConverter
.set( Converter::create(m_xContext
) );
2035 OSL_ENSURE( m_xTypeConverter
.is(),
2036 "PropertyValueSet::getTypeConverter() - "
2037 "Service 'com.sun.star.script.Converter' n/a!" );
2039 return m_xTypeConverter
;
2045 CachedContentResultSetFactory::CachedContentResultSetFactory(
2046 const Reference
< XComponentContext
> & rxContext
)
2048 m_xContext
= rxContext
;
2051 CachedContentResultSetFactory::~CachedContentResultSetFactory()
2055 // CachedContentResultSetFactory XServiceInfo methods.
2057 OUString SAL_CALL
CachedContentResultSetFactory::getImplementationName()
2059 return "com.sun.star.comp.ucb.CachedContentResultSetFactory";
2061 sal_Bool SAL_CALL
CachedContentResultSetFactory::supportsService( const OUString
& ServiceName
)
2063 return cppu::supportsService( this, ServiceName
);
2065 css::uno::Sequence
< OUString
> SAL_CALL
CachedContentResultSetFactory::getSupportedServiceNames()
2067 return { "com.sun.star.ucb.CachedContentResultSetFactory" };
2070 // Service factory implementation.
2074 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
2075 ucb_CachedContentResultSetFactory_get_implementation(
2076 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
2078 return cppu::acquire(new CachedContentResultSetFactory(context
));
2082 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2086 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2087 ::createCachedContentResultSet(
2088 const Reference
< XResultSet
> & xSource
,
2089 const Reference
< XContentIdentifierMapping
> & xMapping
)
2091 Reference
< XResultSet
> xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2095 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */