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/getcomponentcontext.hxx>
35 #include <ucbhelper/macros.hxx>
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 impl_EnsureNotDisposed();
58 osl::ResettableMutexGuard
aGuard(m_aMutex
);
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 bool isCleared
= false;
65 if( !m_aCache
.hasCausedException( nRow
) )
67 if( !m_xFetchProvider
.is() )
69 OSL_FAIL( "broadcaster was disposed already" );
74 if( impl_isForwardOnly() )
75 applyPositionToOrigin( nRow
);
77 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
83 if( !m_aCache
.hasRow( nRow
) )
85 m_bLastReadWasFromCache
= false;
87 applyPositionToOrigin( nRow
);
88 impl_init_xRowOrigin();
89 return (m_xRowOrigin
.get()->*f
)( columnIndex
);
92 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
94 m_bLastReadWasFromCache
= true;
95 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
96 /* Last chance. Try type converter service... */
97 if ( m_bLastCachedReadWasNull
&& rValue
.hasValue() )
99 Reference
< XTypeConverter
> xConverter
= getTypeConverter();
100 if ( xConverter
.is() )
104 Any aConvAny
= xConverter
->convertTo(
106 cppu::UnoType
<T
>::get() );
107 m_bLastCachedReadWasNull
= !( aConvAny
>>= aRet
);
109 catch (const IllegalArgumentException
&)
112 catch (const CannotConvertException
&)
121 // CCRS_Cache methods
124 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
125 const Reference
< XContentIdentifierMapping
> & xMapping
)
126 : m_xContentIdentifierMapping( xMapping
)
130 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
134 void CachedContentResultSet::CCRS_Cache
138 clearMappedReminder();
141 void CachedContentResultSet::CCRS_Cache
142 ::loadData( const FetchResult
& rResult
)
145 m_pResult
.reset( new FetchResult( rResult
) );
148 bool CachedContentResultSet::CCRS_Cache
149 ::hasRow( sal_Int32 row
)
153 sal_Int32 nStart
= m_pResult
->StartIndex
;
154 sal_Int32 nEnd
= nStart
;
155 if( m_pResult
->Orientation
)
156 nEnd
+= m_pResult
->Rows
.getLength() - 1;
158 nStart
-= m_pResult
->Rows
.getLength() + 1;
160 return nStart
<= row
&& row
<= nEnd
;
163 sal_Int32
CachedContentResultSet::CCRS_Cache
168 sal_Int32 nEnd
= m_pResult
->StartIndex
;
169 if( m_pResult
->Orientation
)
170 return nEnd
+= m_pResult
->Rows
.getLength() - 1;
175 bool CachedContentResultSet::CCRS_Cache
176 ::hasKnownLast() const
181 return ( m_pResult
->FetchError
& FetchError::ENDOFDATA
)
182 && m_pResult
->Orientation
183 && m_pResult
->Rows
.hasElements();
186 bool CachedContentResultSet::CCRS_Cache
187 ::hasCausedException( sal_Int32 nRow
)
191 if( !( m_pResult
->FetchError
& FetchError::EXCEPTION
) )
194 sal_Int32 nEnd
= m_pResult
->StartIndex
;
195 if( m_pResult
->Orientation
)
196 nEnd
+= m_pResult
->Rows
.getLength();
198 return nRow
== nEnd
+1;
201 Any
& CachedContentResultSet::CCRS_Cache
202 ::getRowAny( sal_Int32 nRow
)
205 throw SQLException();
207 throw SQLException();
208 if( !hasRow( nRow
) )
209 throw SQLException();
211 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
215 return (m_pResult
->Rows
)[nDiff
];
218 void CachedContentResultSet::CCRS_Cache
219 ::remindMapped( sal_Int32 nRow
)
221 //remind that this row was mapped
224 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
227 Sequence
< sal_Bool
>* pMappedReminder
= getMappedReminder();
228 if( nDiff
< pMappedReminder
->getLength() )
229 (*pMappedReminder
)[nDiff
] = true;
232 bool CachedContentResultSet::CCRS_Cache
233 ::isRowMapped( sal_Int32 nRow
)
235 if( !m_pMappedReminder
|| !m_pResult
)
237 sal_Int32 nDiff
= nRow
- m_pResult
->StartIndex
;
240 if( nDiff
< m_pMappedReminder
->getLength() )
241 return (*m_pMappedReminder
)[nDiff
];
245 void CachedContentResultSet::CCRS_Cache
246 ::clearMappedReminder()
248 m_pMappedReminder
.reset();
251 Sequence
< sal_Bool
>* CachedContentResultSet::CCRS_Cache
252 ::getMappedReminder()
254 if( !m_pMappedReminder
)
256 sal_Int32 nCount
= m_pResult
->Rows
.getLength();
257 m_pMappedReminder
.reset(new Sequence
< sal_Bool
>( nCount
));
258 std::fill(m_pMappedReminder
->begin(), m_pMappedReminder
->end(), false);
260 return m_pMappedReminder
.get();
263 const Any
& CachedContentResultSet::CCRS_Cache
264 ::getAny( sal_Int32 nRow
, sal_Int32 nColumnIndex
)
267 throw SQLException();
268 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
270 Any
& rRow
= getRowAny( nRow
);
271 Sequence
< Any
> aValue
;
273 if( m_xContentIdentifierMapping
->mapRow( aValue
) )
276 remindMapped( nRow
);
279 m_xContentIdentifierMapping
.clear();
281 auto & rowAny
= getRowAny(nRow
);
282 auto rRow
= o3tl::doAccess
<Sequence
<Any
>>(rowAny
);
284 if( nColumnIndex
> rRow
->getLength() )
285 throw SQLException();
286 return (*rRow
)[nColumnIndex
-1];
289 OUString
const & CachedContentResultSet::CCRS_Cache
290 ::getContentIdentifierString( sal_Int32 nRow
)
294 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
296 Any
& rRow
= getRowAny( nRow
);
299 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifierString( aValue
);
300 remindMapped( nRow
);
302 return *o3tl::doAccess
<OUString
>(getRowAny(nRow
));
304 catch(const SQLException
& ex
)
306 css::uno::Any anyEx
= cppu::getCaughtException();
307 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
308 css::uno::Reference
< css::uno::XInterface
>(),
313 Reference
< XContentIdentifier
> CachedContentResultSet::CCRS_Cache
314 ::getContentIdentifier( sal_Int32 nRow
)
318 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
320 Any
& rRow
= getRowAny( nRow
);
321 Reference
< XContentIdentifier
> aValue
;
323 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifier( aValue
);
324 remindMapped( nRow
);
326 return *o3tl::doAccess
<Reference
<XContentIdentifier
>>(getRowAny(nRow
));
328 catch(const SQLException
& ex
)
330 css::uno::Any anyEx
= cppu::getCaughtException();
331 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
332 css::uno::Reference
< css::uno::XInterface
>(),
337 Reference
< XContent
> CachedContentResultSet::CCRS_Cache
338 ::getContent( sal_Int32 nRow
)
342 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
344 Any
& rRow
= getRowAny( nRow
);
345 Reference
< XContent
> aValue
;
347 rRow
<<= m_xContentIdentifierMapping
->mapContent( aValue
);
348 remindMapped( nRow
);
350 return *o3tl::doAccess
<Reference
<XContent
>>(getRowAny(nRow
));
352 catch (const SQLException
& ex
)
354 css::uno::Any anyEx
= cppu::getCaughtException();
355 throw css::lang::WrappedTargetRuntimeException( ex
.Message
,
356 css::uno::Reference
< css::uno::XInterface
>(),
362 // class CCRS_PropertySetInfo
365 class CCRS_PropertySetInfo
:
366 public cppu::OWeakObject
,
367 public css::lang::XTypeProvider
,
368 public css::beans::XPropertySetInfo
370 friend class CachedContentResultSet
;
373 std::unique_ptr
<Sequence
< css::beans::Property
>>
376 long m_nFetchSizePropertyHandle
;
377 long m_nFetchDirectionPropertyHandle
;
381 impl_getRemainedHandle() const;
385 const OUString
& rName
386 , css::beans::Property
& rProp
) const;
388 impl_getPos( const OUString
& rName
) const;
391 impl_isMyPropertyName( const OUString
& rName
);
394 explicit CCRS_PropertySetInfo( Reference
<
395 XPropertySetInfo
> const & xPropertySetInfoOrigin
);
398 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
) override
;
399 virtual void SAL_CALL
acquire()
401 virtual void SAL_CALL
release()
405 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
406 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes() override
;
409 virtual Sequence
< css::beans::Property
> SAL_CALL
410 getProperties() override
;
412 virtual css::beans::Property SAL_CALL
413 getPropertyByName( const OUString
& aName
) override
;
415 virtual sal_Bool SAL_CALL
416 hasPropertyByName( const OUString
& Name
) override
;
419 //some helping variables ( names for my special properties )
420 static const char g_sPropertyNameForCount
[] = "RowCount";
421 static const char g_sPropertyNameForFinalCount
[] = "IsRowCountFinal";
422 static const char g_sPropertyNameForFetchSize
[] = "FetchSize";
423 static const char g_sPropertyNameForFetchDirection
[] = "FetchDirection";
425 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
426 Reference
< XPropertySetInfo
> const & xInfo
)
427 : m_nFetchSizePropertyHandle( -1 )
428 , m_nFetchDirectionPropertyHandle( -1 )
430 //initialize list of properties:
432 // it is required, that the received xInfo contains the two
433 // properties with names 'g_sPropertyNameForCount' and
434 // 'g_sPropertyNameForFinalCount'
438 Sequence
<Property
> aProps
= xInfo
->getProperties();
439 m_pProperties
.reset( new Sequence
<Property
> ( aProps
) );
443 OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
444 m_pProperties
.reset( new Sequence
<Property
> );
447 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
448 sal_Int32 nFetchSize
= impl_getPos( g_sPropertyNameForFetchSize
);
449 sal_Int32 nFetchDirection
= impl_getPos( g_sPropertyNameForFetchDirection
);
450 sal_Int32 nDeleted
= 0;
451 if( nFetchSize
!= -1 )
453 if( nFetchDirection
!= -1 )
456 std::unique_ptr
<Sequence
< Property
> > pOrigProps(new Sequence
<Property
> ( *m_pProperties
));
457 sal_Int32 nOrigProps
= pOrigProps
->getLength();
459 m_pProperties
->realloc( nOrigProps
+ 2 - nDeleted
);//note that nDeleted is <= 2
460 for( sal_Int32 n
= 0, m
= 0; n
< nOrigProps
; n
++, m
++ )
462 if( n
== nFetchSize
|| n
== nFetchDirection
)
465 (*m_pProperties
)[ m
] = (*pOrigProps
)[ n
];
468 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
];
469 rMyProp
.Name
= g_sPropertyNameForFetchSize
;
470 rMyProp
.Type
= cppu::UnoType
<sal_Int32
>::get();
471 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
473 if( nFetchSize
!= -1 )
474 m_nFetchSizePropertyHandle
= (*pOrigProps
)[nFetchSize
].Handle
;
476 m_nFetchSizePropertyHandle
= impl_getRemainedHandle();
478 rMyProp
.Handle
= m_nFetchSizePropertyHandle
;
482 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
+ 1 ];
483 rMyProp
.Name
= g_sPropertyNameForFetchDirection
;
484 rMyProp
.Type
= cppu::UnoType
<sal_Bool
>::get();
485 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
487 m_nFetchDirectionPropertyHandle
= rMyProp
.Handle
;
491 // XInterface methods.
493 void SAL_CALL
CCRS_PropertySetInfo::acquire()
496 OWeakObject::acquire();
499 void SAL_CALL
CCRS_PropertySetInfo::release()
502 OWeakObject::release();
505 css::uno::Any SAL_CALL
CCRS_PropertySetInfo::queryInterface( const css::uno::Type
& rType
)
507 css::uno::Any aRet
= cppu::queryInterface( rType
,
508 static_cast< XTypeProvider
* >(this),
509 static_cast< XPropertySetInfo
* >(this)
511 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
514 // XTypeProvider methods.
516 //list all interfaces exclusive baseclasses
517 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
522 // XPropertySetInfo methods.
525 Sequence
< Property
> SAL_CALL CCRS_PropertySetInfo
528 return *m_pProperties
;
532 Property SAL_CALL CCRS_PropertySetInfo
533 ::getPropertyByName( const OUString
& aName
)
536 if ( impl_queryProperty( aName
, aProp
) )
539 throw UnknownPropertyException(aName
);
543 sal_Bool SAL_CALL CCRS_PropertySetInfo
544 ::hasPropertyByName( const OUString
& Name
)
546 return ( impl_getPos( Name
) != -1 );
553 sal_Int32 CCRS_PropertySetInfo
554 ::impl_getPos( const OUString
& rName
) const
556 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
558 const Property
& rMyProp
= (*m_pProperties
)[nN
];
559 if( rMyProp
.Name
== rName
)
565 bool CCRS_PropertySetInfo
566 ::impl_queryProperty( const OUString
& rName
, Property
& rProp
) const
568 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
570 const Property
& rMyProp
= (*m_pProperties
)[nN
];
571 if( rMyProp
.Name
== rName
)
573 rProp
.Name
= rMyProp
.Name
;
574 rProp
.Handle
= rMyProp
.Handle
;
575 rProp
.Type
= rMyProp
.Type
;
576 rProp
.Attributes
= rMyProp
.Attributes
;
585 bool CCRS_PropertySetInfo
586 ::impl_isMyPropertyName( const OUString
& rPropertyName
)
588 return ( rPropertyName
== g_sPropertyNameForCount
589 || rPropertyName
== g_sPropertyNameForFinalCount
590 || rPropertyName
== g_sPropertyNameForFetchSize
591 || rPropertyName
== g_sPropertyNameForFetchDirection
);
594 sal_Int32 CCRS_PropertySetInfo
595 ::impl_getRemainedHandle( ) const
597 sal_Int32 nHandle
= 1;
601 OSL_FAIL( "Properties not initialized yet" );
608 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
610 if( nHandle
== (*m_pProperties
)[nN
].Handle
)
622 // class CachedContentResultSet
625 CachedContentResultSet::CachedContentResultSet(
626 const Reference
< XComponentContext
> & rxContext
627 , const Reference
< XResultSet
> & xOrigin
628 , const Reference
< XContentIdentifierMapping
> &
629 xContentIdentifierMapping
)
630 : ContentResultSetWrapper( xOrigin
)
632 , m_xContext( rxContext
)
634 , m_xContentIdentifierMapping( xContentIdentifierMapping
)
635 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
636 , m_bAfterLast( false )
637 , m_nLastAppliedPos( 0 )
638 , m_bAfterLastApplied( false )
640 , m_bFinalCount( false )
642 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
)
644 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
)
646 , m_bLastReadWasFromCache( false )
647 , m_bLastCachedReadWasNull( true )
648 , m_aCache( m_xContentIdentifierMapping
)
649 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping
)
650 , m_aCacheContentIdentifier( m_xContentIdentifierMapping
)
651 , m_aCacheContent( m_xContentIdentifierMapping
)
652 , m_bTriedToGetTypeConverter( false )
654 m_xFetchProvider
.set( m_xResultSetOrigin
, UNO_QUERY
);
655 OSL_ENSURE( m_xFetchProvider
.is(), "interface XFetchProvider is required" );
657 m_xFetchProviderForContentAccess
.set( m_xResultSetOrigin
, UNO_QUERY
);
658 OSL_ENSURE( m_xFetchProviderForContentAccess
.is(), "interface XFetchProviderForContentAccess is required" );
663 CachedContentResultSet::~CachedContentResultSet()
666 //do not delete m_pMyPropSetInfo, cause it is hold via reference
673 bool CachedContentResultSet
674 ::applyPositionToOrigin( sal_Int32 nRow
)
676 impl_EnsureNotDisposed();
680 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
684 osl::ResettableMutexGuard
aGuard(m_aMutex
);
685 OSL_ENSURE( nRow
>= 0, "only positive values supported" );
686 if( !m_xResultSetOrigin
.is() )
688 OSL_FAIL( "broadcaster was disposed already" );
691 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
693 sal_Int32 nLastAppliedPos
= m_nLastAppliedPos
;
694 bool bAfterLastApplied
= m_bAfterLastApplied
;
695 bool bAfterLast
= m_bAfterLast
;
696 sal_Int32 nForwardOnly
= m_nForwardOnly
;
700 if( bAfterLastApplied
|| nLastAppliedPos
!= nRow
)
702 if( nForwardOnly
== 1 )
704 if( bAfterLastApplied
|| bAfterLast
|| !nRow
|| nRow
< nLastAppliedPos
)
705 throw SQLException();
707 sal_Int32 nN
= nRow
- nLastAppliedPos
;
709 for( nM
= 0; nN
--; nM
++ )
711 if( !m_xResultSetOrigin
->next() )
716 m_nLastAppliedPos
+= nM
;
717 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
718 return nRow
== m_nLastAppliedPos
;
721 if( !nRow
) //absolute( 0 ) will throw exception
723 m_xResultSetOrigin
->beforeFirst();
726 m_nLastAppliedPos
= 0;
727 m_bAfterLastApplied
= false;
732 //move absolute, if !nLastAppliedPos
733 //because move relative would throw exception
734 if( !nLastAppliedPos
|| bAfterLast
|| bAfterLastApplied
)
736 bool bValid
= m_xResultSetOrigin
->absolute( nRow
);
739 m_nLastAppliedPos
= nRow
;
740 m_bAfterLastApplied
= !bValid
;
745 bool bValid
= m_xResultSetOrigin
->relative( nRow
- nLastAppliedPos
);
748 m_nLastAppliedPos
+= ( nRow
- nLastAppliedPos
);
749 m_bAfterLastApplied
= !bValid
;
753 catch (const SQLException
&)
755 if( !bAfterLastApplied
&& !bAfterLast
&& nRow
> nLastAppliedPos
&& impl_isForwardOnly() )
757 sal_Int32 nN
= nRow
- nLastAppliedPos
;
759 for( nM
= 0; nN
--; nM
++ )
761 if( !m_xResultSetOrigin
->next() )
766 m_nLastAppliedPos
+= nM
;
767 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
773 return nRow
== m_nLastAppliedPos
;
779 //define for fetching data
782 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
783 bool bDirection = !!( \
784 nFetchDirection != FetchDirection::REVERSE ); \
785 FetchResult aResult = \
786 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
787 osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
788 aCache.loadData( aResult ); \
789 sal_Int32 nMax = aCache.getMaxRow(); \
790 sal_Int32 nCurCount = m_nKnownCount; \
791 bool bIsFinalCount = aCache.hasKnownLast(); \
792 bool bCurIsFinalCount = m_bFinalCount; \
794 if( nMax > nCurCount ) \
795 impl_changeRowCount( nCurCount, nMax ); \
796 if( bIsFinalCount && !bCurIsFinalCount ) \
797 impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
799 void CachedContentResultSet
800 ::impl_fetchData( sal_Int32 nRow
801 , sal_Int32 nFetchSize
, sal_Int32 nFetchDirection
)
803 FETCH_XXX( m_aCache
, m_xFetchProvider
, fetch
);
806 void CachedContentResultSet
807 ::impl_changeRowCount( sal_Int32 nOld
, sal_Int32 nNew
)
809 OSL_ENSURE( nNew
> nOld
, "RowCount only can grow" );
813 //create PropertyChangeEvent and set value
814 PropertyChangeEvent aEvt
;
816 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
817 aEvt
.Source
= static_cast< XPropertySet
* >( this );
818 aEvt
.Further
= false;
819 aEvt
.OldValue
<<= nOld
;
820 aEvt
.NewValue
<<= nNew
;
822 m_nKnownCount
= nNew
;
825 //send PropertyChangeEvent to listeners
826 impl_notifyPropertyChangeListeners( aEvt
);
829 void CachedContentResultSet
830 ::impl_changeIsRowCountFinal( bool bOld
, bool bNew
)
832 OSL_ENSURE( !bOld
&& bNew
, "This change is not allowed for IsRowCountFinal" );
833 if( ! (!bOld
&& bNew
) )
836 //create PropertyChangeEvent and set value
837 PropertyChangeEvent aEvt
;
839 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
840 aEvt
.Source
= static_cast< XPropertySet
* >( this );
841 aEvt
.Further
= false;
842 aEvt
.OldValue
<<= bOld
;
843 aEvt
.NewValue
<<= bNew
;
845 m_bFinalCount
= bNew
;
848 //send PropertyChangeEvent to listeners
849 impl_notifyPropertyChangeListeners( aEvt
);
852 bool CachedContentResultSet
853 ::impl_isKnownValidPosition( sal_Int32 nRow
)
855 return m_nKnownCount
&& nRow
856 && nRow
<= m_nKnownCount
;
859 bool CachedContentResultSet
860 ::impl_isKnownInvalidPosition( sal_Int32 nRow
)
866 return nRow
> m_nKnownCount
;
871 void CachedContentResultSet
872 ::impl_initPropertySetInfo()
874 ContentResultSetWrapper::impl_initPropertySetInfo();
876 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
877 if( m_xMyPropertySetInfo
.is() )
879 m_xMyPropertySetInfo
= new CCRS_PropertySetInfo( m_xPropertySetInfo
);
880 m_xPropertySetInfo
= m_xMyPropertySetInfo
.get();
884 // XInterface methods.
885 void SAL_CALL
CachedContentResultSet::acquire()
888 OWeakObject::acquire();
891 void SAL_CALL
CachedContentResultSet::release()
894 OWeakObject::release();
897 Any SAL_CALL CachedContentResultSet
898 ::queryInterface( const Type
& rType
)
900 //list all interfaces inclusive baseclasses of interfaces
902 Any aRet
= ContentResultSetWrapper::queryInterface( rType
);
903 if( aRet
.hasValue() )
906 aRet
= cppu::queryInterface( rType
,
907 static_cast< XTypeProvider
* >( this ),
908 static_cast< XServiceInfo
* >( this ) );
910 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
914 // XTypeProvider methods.
916 //list all interfaces exclusive baseclasses
917 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
922 , XResultSetMetaDataSupplier
925 , XPropertyChangeListener
926 , XVetoableChangeListener
934 // XServiceInfo methods.
936 OUString SAL_CALL
CachedContentResultSet::getImplementationName()
938 return "com.sun.star.comp.ucb.CachedContentResultSet";
941 sal_Bool SAL_CALL
CachedContentResultSet::supportsService( const OUString
& ServiceName
)
943 return cppu::supportsService( this, ServiceName
);
946 css::uno::Sequence
< OUString
> SAL_CALL
CachedContentResultSet::getSupportedServiceNames()
948 return { CACHED_CONTENT_RESULTSET_SERVICE_NAME
};
953 // XPropertySet methods. ( inherited )
957 void SAL_CALL CachedContentResultSet
958 ::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
960 impl_EnsureNotDisposed();
962 if( !getPropertySetInfo().is() )
964 OSL_FAIL( "broadcaster was disposed already" );
965 throw UnknownPropertyException();
968 Property aProp
= m_xMyPropertySetInfo
->getPropertyByName( aPropertyName
);
969 //throws UnknownPropertyException, if so
971 if( aProp
.Attributes
& PropertyAttribute::READONLY
)
973 //It is assumed, that the properties
974 //'RowCount' and 'IsRowCountFinal' are readonly!
975 throw IllegalArgumentException();
977 if( aProp
.Name
== g_sPropertyNameForFetchDirection
)
981 if( !( aValue
>>= nNew
) )
983 throw IllegalArgumentException();
986 if( nNew
== FetchDirection::UNKNOWN
)
988 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
;
990 else if( !( nNew
== FetchDirection::FORWARD
991 || nNew
== FetchDirection::REVERSE
) )
993 throw IllegalArgumentException();
996 //create PropertyChangeEvent and set value
997 PropertyChangeEvent aEvt
;
999 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1000 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1001 aEvt
.PropertyName
= aPropertyName
;
1002 aEvt
.Further
= false;
1003 aEvt
.PropertyHandle
= m_xMyPropertySetInfo
->
1004 m_nFetchDirectionPropertyHandle
;
1005 aEvt
.OldValue
<<= m_nFetchDirection
;
1006 aEvt
.NewValue
<<= nNew
;
1008 m_nFetchDirection
= nNew
;
1011 //send PropertyChangeEvent to listeners
1012 impl_notifyPropertyChangeListeners( aEvt
);
1014 else if( aProp
.Name
== g_sPropertyNameForFetchSize
)
1018 if( !( aValue
>>= nNew
) )
1020 throw IllegalArgumentException();
1025 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
;
1028 //create PropertyChangeEvent and set value
1029 PropertyChangeEvent aEvt
;
1031 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1032 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1033 aEvt
.PropertyName
= aPropertyName
;
1034 aEvt
.Further
= false;
1035 aEvt
.PropertyHandle
= m_xMyPropertySetInfo
->
1036 m_nFetchSizePropertyHandle
;
1037 aEvt
.OldValue
<<= m_nFetchSize
;
1038 aEvt
.NewValue
<<= nNew
;
1040 m_nFetchSize
= nNew
;
1043 //send PropertyChangeEvent to listeners
1044 impl_notifyPropertyChangeListeners( aEvt
);
1048 impl_init_xPropertySetOrigin();
1050 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1051 if( !m_xPropertySetOrigin
.is() )
1053 OSL_FAIL( "broadcaster was disposed already" );
1057 m_xPropertySetOrigin
->setPropertyValue( aPropertyName
, aValue
);
1063 Any SAL_CALL CachedContentResultSet
1064 ::getPropertyValue( const OUString
& rPropertyName
)
1066 impl_EnsureNotDisposed();
1068 if( !getPropertySetInfo().is() )
1070 OSL_FAIL( "broadcaster was disposed already" );
1071 throw UnknownPropertyException();
1074 m_xMyPropertySetInfo
->getPropertyByName( rPropertyName
);
1075 //throws UnknownPropertyException, if so
1078 if( rPropertyName
== g_sPropertyNameForCount
)
1080 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1081 aValue
<<= m_nKnownCount
;
1083 else if( rPropertyName
== g_sPropertyNameForFinalCount
)
1085 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1086 aValue
<<= m_bFinalCount
;
1088 else if( rPropertyName
== g_sPropertyNameForFetchSize
)
1090 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1091 aValue
<<= m_nFetchSize
;
1093 else if( rPropertyName
== g_sPropertyNameForFetchDirection
)
1095 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1096 aValue
<<= m_nFetchDirection
;
1100 impl_init_xPropertySetOrigin();
1102 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1103 if( !m_xPropertySetOrigin
.is() )
1105 OSL_FAIL( "broadcaster was disposed already" );
1106 throw UnknownPropertyException();
1109 aValue
= m_xPropertySetOrigin
->getPropertyValue( rPropertyName
);
1115 // own methods. ( inherited )
1119 void CachedContentResultSet
1120 ::impl_disposing( const EventObject
& rEventObject
)
1123 impl_EnsureNotDisposed();
1124 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1125 //release all references to the broadcaster:
1126 m_xFetchProvider
.clear();
1127 m_xFetchProviderForContentAccess
.clear();
1129 ContentResultSetWrapper::impl_disposing( rEventObject
);
1133 void CachedContentResultSet
1134 ::impl_propertyChange( const PropertyChangeEvent
& rEvt
)
1136 impl_EnsureNotDisposed();
1138 PropertyChangeEvent
aEvt( rEvt
);
1139 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1140 aEvt
.Further
= false;
1143 if( CCRS_PropertySetInfo
1144 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1146 //don't notify foreign events on fetchsize and fetchdirection
1147 if( aEvt
.PropertyName
== g_sPropertyNameForFetchSize
1148 || aEvt
.PropertyName
== g_sPropertyNameForFetchDirection
)
1151 //adjust my props 'RowCount' and 'IsRowCountFinal'
1152 if( aEvt
.PropertyName
== g_sPropertyNameForCount
)
1157 if( !( aEvt
.NewValue
>>= nNew
) )
1159 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1163 impl_changeRowCount( m_nKnownCount
, nNew
);
1165 else if( aEvt
.PropertyName
== g_sPropertyNameForFinalCount
)
1166 {//IsRowCountFinal changed
1170 if( !( aEvt
.NewValue
>>= bNew
) )
1172 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1175 impl_changeIsRowCountFinal( m_bFinalCount
, bNew
);
1181 impl_notifyPropertyChangeListeners( aEvt
);
1186 void CachedContentResultSet
1187 ::impl_vetoableChange( const PropertyChangeEvent
& rEvt
)
1189 impl_EnsureNotDisposed();
1191 //don't notify events on my properties, cause they are not vetoable
1192 if( CCRS_PropertySetInfo
1193 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1199 PropertyChangeEvent
aEvt( rEvt
);
1200 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1201 aEvt
.Further
= false;
1203 impl_notifyVetoableChangeListeners( aEvt
);
1207 // XContentAccess methods. ( inherited ) ( -- position dependent )
1210 #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1211 impl_EnsureNotDisposed(); \
1212 osl::ResettableMutexGuard aGuard(m_aMutex); \
1213 sal_Int32 nRow = m_nRow; \
1214 sal_Int32 nFetchSize = m_nFetchSize; \
1215 sal_Int32 nFetchDirection = m_nFetchDirection; \
1216 if( !m_aCache##XXX.hasRow( nRow ) ) \
1220 bool isCleared = false; \
1221 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1223 if( !m_xFetchProviderForContentAccess.is() ) \
1225 OSL_FAIL( "broadcaster was disposed already" ); \
1226 throw RuntimeException(); \
1230 if( impl_isForwardOnly() ) \
1231 applyPositionToOrigin( nRow ); \
1233 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1239 if( !m_aCache##XXX.hasRow( nRow ) ) \
1242 applyPositionToOrigin( nRow ); \
1243 TYPE aRet = ContentResultSetWrapper::queryXXX();\
1244 if( m_xContentIdentifierMapping.is() ) \
1245 return m_xContentIdentifierMapping->map##XXX( aRet );\
1249 catch (const RuntimeException&) \
1253 catch (const Exception& e) \
1255 Any a(cppu::getCaughtException()); \
1256 throw WrappedTargetRuntimeException( \
1257 "wrapped Exception " + e.Message, \
1258 Reference<XInterface>(), a); \
1261 return m_aCache##XXX.get##XXX( nRow );
1264 OUString SAL_CALL CachedContentResultSet
1265 ::queryContentIdentifierString()
1267 XCONTENTACCESS_queryXXX( queryContentIdentifierString
, ContentIdentifierString
, OUString
)
1272 Reference
< XContentIdentifier
> SAL_CALL CachedContentResultSet
1273 ::queryContentIdentifier()
1275 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1280 Reference
< XContent
> SAL_CALL CachedContentResultSet
1283 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1287 // XResultSet methods. ( inherited )
1291 sal_Bool SAL_CALL CachedContentResultSet
1294 impl_EnsureNotDisposed();
1296 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1306 m_bAfterLast
= true;
1310 //known valid position
1311 if( impl_isKnownValidPosition( m_nRow
+ 1 ) )
1318 sal_Int32 nRow
= m_nRow
;
1321 bool bValid
= applyPositionToOrigin( nRow
+ 1 );
1325 m_bAfterLast
= !bValid
;
1330 sal_Bool SAL_CALL CachedContentResultSet
1333 impl_EnsureNotDisposed();
1335 if( impl_isForwardOnly() )
1336 throw SQLException();
1338 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1340 if( !m_bAfterLast
&& !m_nRow
)
1343 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1346 m_bAfterLast
= false;
1349 //known valid position ?:
1350 if( impl_isKnownValidPosition( m_nRow
- 1 ) )
1353 m_bAfterLast
= false;
1357 sal_Int32 nRow
= m_nRow
;
1360 bool bValid
= applyPositionToOrigin( nRow
- 1 );
1364 m_bAfterLast
= false;
1369 sal_Bool SAL_CALL CachedContentResultSet
1370 ::absolute( sal_Int32 row
)
1372 impl_EnsureNotDisposed();
1375 throw SQLException();
1377 if( impl_isForwardOnly() )
1378 throw SQLException();
1380 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1382 if( !m_xResultSetOrigin
.is() )
1384 OSL_FAIL( "broadcaster was disposed already" );
1391 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1399 m_bAfterLast
= false;
1402 //unknown final count:
1405 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1410 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1413 m_nLastAppliedPos
= nNewRow
;
1415 m_bAfterLastApplied
= m_bAfterLast
= false;
1420 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1423 m_nLastAppliedPos
= nCurRow
;
1425 m_bAfterLast
= false;
1426 return nCurRow
!= 0;
1431 if( row
> m_nKnownCount
)
1433 m_nRow
= m_nKnownCount
+ 1;
1434 m_bAfterLast
= true;
1438 m_bAfterLast
= false;
1441 //unknown new position:
1444 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1449 sal_Int32 nNewRow
= row
;
1450 if( nNewRow
> m_nKnownCount
)
1452 nNewRow
= m_nKnownCount
+ 1;
1453 m_bAfterLastApplied
= m_bAfterLast
= true;
1456 m_bAfterLastApplied
= m_bAfterLast
= false;
1458 m_nLastAppliedPos
= nNewRow
;
1464 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1465 bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1468 m_nLastAppliedPos
= nCurRow
;
1470 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1471 return nCurRow
&& !bIsAfterLast
;
1475 sal_Bool SAL_CALL CachedContentResultSet
1476 ::relative( sal_Int32 rows
)
1478 impl_EnsureNotDisposed();
1480 if( impl_isForwardOnly() )
1481 throw SQLException();
1483 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1484 if( m_bAfterLast
|| impl_isKnownInvalidPosition( m_nRow
) )
1485 throw SQLException();
1490 sal_Int32 nNewRow
= m_nRow
+ rows
;
1494 if( impl_isKnownValidPosition( nNewRow
) )
1497 m_bAfterLast
= false;
1502 //known invalid new position:
1505 m_bAfterLast
= false;
1509 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1511 m_bAfterLast
= true;
1512 m_nRow
= m_nKnownCount
+ 1;
1515 //unknown new position:
1517 bool bValid
= applyPositionToOrigin( nNewRow
);
1521 m_bAfterLast
= !bValid
; // only nNewRow > 0 possible here
1528 sal_Bool SAL_CALL CachedContentResultSet
1531 impl_EnsureNotDisposed();
1533 if( impl_isForwardOnly() )
1534 throw SQLException();
1536 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1537 if( impl_isKnownValidPosition( 1 ) )
1540 m_bAfterLast
= false;
1543 if( impl_isKnownInvalidPosition( 1 ) )
1546 m_bAfterLast
= false;
1552 bool bValid
= applyPositionToOrigin( 1 );
1556 m_bAfterLast
= false;
1561 sal_Bool SAL_CALL CachedContentResultSet
1564 impl_EnsureNotDisposed();
1566 if( impl_isForwardOnly() )
1567 throw SQLException();
1569 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1572 m_nRow
= m_nKnownCount
;
1573 m_bAfterLast
= false;
1574 return m_nKnownCount
!= 0;
1577 if( !m_xResultSetOrigin
.is() )
1579 OSL_FAIL( "broadcaster was disposed already" );
1584 bool bValid
= m_xResultSetOrigin
->last();
1587 m_bAfterLastApplied
= m_bAfterLast
= false;
1590 m_nLastAppliedPos
= m_nKnownCount
;
1591 m_nRow
= m_nKnownCount
;
1596 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1599 m_nLastAppliedPos
= nCurRow
;
1601 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1602 m_nKnownCount
= nCurRow
;
1603 m_bFinalCount
= true;
1604 return nCurRow
!= 0;
1608 void SAL_CALL CachedContentResultSet
1611 impl_EnsureNotDisposed();
1613 if( impl_isForwardOnly() )
1614 throw SQLException();
1616 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1618 m_bAfterLast
= false;
1622 void SAL_CALL CachedContentResultSet
1625 impl_EnsureNotDisposed();
1627 if( impl_isForwardOnly() )
1628 throw SQLException();
1630 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1632 m_bAfterLast
= true;
1636 sal_Bool SAL_CALL CachedContentResultSet
1639 impl_EnsureNotDisposed();
1641 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1645 return m_bAfterLast
;
1649 if( !m_xResultSetOrigin
.is() )
1651 OSL_FAIL( "broadcaster was disposed already" );
1656 //find out whether the original resultset contains rows or not
1657 m_xResultSetOrigin
->afterLast();
1660 m_bAfterLastApplied
= true;
1663 return m_xResultSetOrigin
->isAfterLast();
1667 sal_Bool SAL_CALL CachedContentResultSet
1670 impl_EnsureNotDisposed();
1672 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1682 if( !m_xResultSetOrigin
.is() )
1684 OSL_FAIL( "broadcaster was disposed already" );
1689 //find out whether the original resultset contains rows or not
1690 m_xResultSetOrigin
->beforeFirst();
1693 m_bAfterLastApplied
= false;
1694 m_nLastAppliedPos
= 0;
1697 return m_xResultSetOrigin
->isBeforeFirst();
1701 sal_Bool SAL_CALL CachedContentResultSet
1704 impl_EnsureNotDisposed();
1707 Reference
< XResultSet
> xResultSetOrigin
;
1710 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1721 xResultSetOrigin
= m_xResultSetOrigin
;
1724 //need to ask origin
1726 if( applyPositionToOrigin( nRow
) )
1727 return xResultSetOrigin
->isFirst();
1734 sal_Bool SAL_CALL CachedContentResultSet
1737 impl_EnsureNotDisposed();
1740 Reference
< XResultSet
> xResultSetOrigin
;
1742 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1745 if( m_nRow
< m_nKnownCount
)
1748 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1751 xResultSetOrigin
= m_xResultSetOrigin
;
1754 //need to ask origin
1756 if( applyPositionToOrigin( nRow
) )
1757 return xResultSetOrigin
->isLast();
1765 sal_Int32 SAL_CALL CachedContentResultSet
1768 impl_EnsureNotDisposed();
1770 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1777 void SAL_CALL CachedContentResultSet
1780 impl_EnsureNotDisposed();
1782 //the ContentResultSet is static and will not change
1783 //therefore we don't need to reload anything
1787 sal_Bool SAL_CALL CachedContentResultSet
1790 impl_EnsureNotDisposed();
1792 //the ContentResultSet is static and will not change
1796 sal_Bool SAL_CALL CachedContentResultSet
1799 impl_EnsureNotDisposed();
1801 //the ContentResultSet is static and will not change
1806 sal_Bool SAL_CALL CachedContentResultSet
1809 impl_EnsureNotDisposed();
1811 //the ContentResultSet is static and will not change
1816 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1819 impl_EnsureNotDisposed();
1820 //@todo ?return anything
1821 return Reference
< XInterface
>();
1825 // XRow methods. ( inherited )
1829 sal_Bool SAL_CALL CachedContentResultSet
1832 impl_EnsureNotDisposed();
1833 impl_init_xRowOrigin();
1835 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1836 if( m_bLastReadWasFromCache
)
1837 return m_bLastCachedReadWasNull
;
1838 if( !m_xRowOrigin
.is() )
1840 OSL_FAIL( "broadcaster was disposed already" );
1844 return m_xRowOrigin
->wasNull();
1848 OUString SAL_CALL CachedContentResultSet
1849 ::getString( sal_Int32 columnIndex
)
1851 return rowOriginGet
<OUString
>(&css::sdbc::XRow::getString
, columnIndex
);
1855 sal_Bool SAL_CALL CachedContentResultSet
1856 ::getBoolean( sal_Int32 columnIndex
)
1858 return rowOriginGet
<sal_Bool
>(&css::sdbc::XRow::getBoolean
, columnIndex
);
1862 sal_Int8 SAL_CALL CachedContentResultSet
1863 ::getByte( sal_Int32 columnIndex
)
1865 return rowOriginGet
<sal_Int8
>(&css::sdbc::XRow::getByte
, columnIndex
);
1869 sal_Int16 SAL_CALL CachedContentResultSet
1870 ::getShort( sal_Int32 columnIndex
)
1872 return rowOriginGet
<sal_Int16
>(&css::sdbc::XRow::getShort
, columnIndex
);
1876 sal_Int32 SAL_CALL CachedContentResultSet
1877 ::getInt( sal_Int32 columnIndex
)
1879 return rowOriginGet
<sal_Int32
>(&css::sdbc::XRow::getInt
, columnIndex
);
1883 sal_Int64 SAL_CALL CachedContentResultSet
1884 ::getLong( sal_Int32 columnIndex
)
1886 return rowOriginGet
<sal_Int64
>(&css::sdbc::XRow::getLong
, columnIndex
);
1890 float SAL_CALL CachedContentResultSet
1891 ::getFloat( sal_Int32 columnIndex
)
1893 return rowOriginGet
<float>(&css::sdbc::XRow::getFloat
, columnIndex
);
1897 double SAL_CALL CachedContentResultSet
1898 ::getDouble( sal_Int32 columnIndex
)
1900 return rowOriginGet
<double>(&css::sdbc::XRow::getDouble
, columnIndex
);
1904 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
1905 ::getBytes( sal_Int32 columnIndex
)
1907 return rowOriginGet
< css::uno::Sequence
<sal_Int8
> >(
1908 &css::sdbc::XRow::getBytes
, columnIndex
);
1912 Date SAL_CALL CachedContentResultSet
1913 ::getDate( sal_Int32 columnIndex
)
1915 return rowOriginGet
<css::util::Date
>(
1916 &css::sdbc::XRow::getDate
, columnIndex
);
1920 Time SAL_CALL CachedContentResultSet
1921 ::getTime( sal_Int32 columnIndex
)
1923 return rowOriginGet
<css::util::Time
>(
1924 &css::sdbc::XRow::getTime
, columnIndex
);
1928 DateTime SAL_CALL CachedContentResultSet
1929 ::getTimestamp( sal_Int32 columnIndex
)
1931 return rowOriginGet
<css::util::DateTime
>(
1932 &css::sdbc::XRow::getTimestamp
, columnIndex
);
1936 Reference
< css::io::XInputStream
>
1937 SAL_CALL CachedContentResultSet
1938 ::getBinaryStream( sal_Int32 columnIndex
)
1940 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1941 &css::sdbc::XRow::getBinaryStream
, columnIndex
);
1945 Reference
< css::io::XInputStream
>
1946 SAL_CALL CachedContentResultSet
1947 ::getCharacterStream( sal_Int32 columnIndex
)
1949 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
1950 &css::sdbc::XRow::getCharacterStream
, columnIndex
);
1954 Any SAL_CALL CachedContentResultSet
1955 ::getObject( sal_Int32 columnIndex
,
1957 css::container::XNameAccess
>& typeMap
)
1959 //if you change this function please pay attention to
1960 //function template rowOriginGet, where this is similar implemented
1962 osl::ResettableMutexGuard
aGuard(m_aMutex
);
1963 sal_Int32 nRow
= m_nRow
;
1964 sal_Int32 nFetchSize
= m_nFetchSize
;
1965 sal_Int32 nFetchDirection
= m_nFetchDirection
;
1966 if( !m_aCache
.hasRow( nRow
) )
1968 bool isCleared
= false;
1969 if( !m_aCache
.hasCausedException( nRow
) )
1971 if( !m_xFetchProvider
.is() )
1973 OSL_FAIL( "broadcaster was disposed already" );
1979 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
1985 if( !m_aCache
.hasRow( nRow
) )
1987 m_bLastReadWasFromCache
= false;
1989 applyPositionToOrigin( nRow
);
1990 impl_init_xRowOrigin();
1991 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
1994 //@todo: pay attention to typeMap
1995 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
1996 m_bLastReadWasFromCache
= true;
1997 m_bLastCachedReadWasNull
= !rValue
.hasValue();
2002 Reference
< XRef
> SAL_CALL CachedContentResultSet
2003 ::getRef( sal_Int32 columnIndex
)
2005 return rowOriginGet
< css::uno::Reference
<css::sdbc::XRef
> >(
2006 &css::sdbc::XRow::getRef
, columnIndex
);
2010 Reference
< XBlob
> SAL_CALL CachedContentResultSet
2011 ::getBlob( sal_Int32 columnIndex
)
2013 return rowOriginGet
< css::uno::Reference
<css::sdbc::XBlob
> >(
2014 &css::sdbc::XRow::getBlob
, columnIndex
);
2018 Reference
< XClob
> SAL_CALL CachedContentResultSet
2019 ::getClob( sal_Int32 columnIndex
)
2021 return rowOriginGet
< css::uno::Reference
<css::sdbc::XClob
> >(
2022 &css::sdbc::XRow::getClob
, columnIndex
);
2026 Reference
< XArray
> SAL_CALL CachedContentResultSet
2027 ::getArray( sal_Int32 columnIndex
)
2029 return rowOriginGet
< css::uno::Reference
<css::sdbc::XArray
> >(
2030 &css::sdbc::XRow::getArray
, columnIndex
);
2034 // Type Converter Support
2037 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter()
2039 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2041 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
2043 m_bTriedToGetTypeConverter
= true;
2044 m_xTypeConverter
.set( Converter::create(m_xContext
) );
2046 OSL_ENSURE( m_xTypeConverter
.is(),
2047 "PropertyValueSet::getTypeConverter() - "
2048 "Service 'com.sun.star.script.Converter' n/a!" );
2050 return m_xTypeConverter
;
2054 // class CachedContentResultSetFactory
2057 CachedContentResultSetFactory::CachedContentResultSetFactory(
2058 const Reference
< XComponentContext
> & rxContext
)
2060 m_xContext
= rxContext
;
2063 CachedContentResultSetFactory::~CachedContentResultSetFactory()
2067 // CachedContentResultSetFactory XServiceInfo methods.
2069 XSERVICEINFO_COMMOM_IMPL( CachedContentResultSetFactory
,
2070 "com.sun.star.comp.ucb.CachedContentResultSetFactory" )
2071 /// @throws css::uno::Exception
2072 static css::uno::Reference
< css::uno::XInterface
>
2073 CachedContentResultSetFactory_CreateInstance( const css::uno::Reference
< css::lang::XMultiServiceFactory
> & rSMgr
)
2075 css::lang::XServiceInfo
* pX
= new CachedContentResultSetFactory( ucbhelper::getComponentContext(rSMgr
) );
2076 return css::uno::Reference
< css::uno::XInterface
>::query( pX
);
2079 css::uno::Sequence
< OUString
>
2080 CachedContentResultSetFactory::getSupportedServiceNames_Static()
2082 css::uno::Sequence
< OUString
> aSNS
{ CACHED_CONTENT_RESULTSET_FACTORY_NAME
};
2086 // Service factory implementation.
2089 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory
);
2092 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2096 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2097 ::createCachedContentResultSet(
2098 const Reference
< XResultSet
> & xSource
,
2099 const Reference
< XContentIdentifierMapping
> & xMapping
)
2101 Reference
< XResultSet
> xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2105 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */