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/ucb/FetchError.hpp>
24 #include <com/sun/star/ucb/ResultSetException.hpp>
25 #include <com/sun/star/beans/PropertyAttribute.hpp>
26 #include <com/sun/star/script/Converter.hpp>
27 #include <com/sun/star/sdbc/ResultSetType.hpp>
28 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
29 #include <rtl/ustring.hxx>
30 #include <osl/diagnose.h>
31 #include <comphelper/processfactory.hxx>
32 #include <cppuhelper/exc_hlp.hxx>
33 #include <boost/scoped_ptr.hpp>
35 using namespace com::sun::star::beans
;
36 using namespace com::sun::star::lang
;
37 using namespace com::sun::star::script
;
38 using namespace com::sun::star::sdbc
;
39 using namespace com::sun::star::ucb
;
40 using namespace com::sun::star::uno
;
41 using namespace com::sun::star::util
;
45 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
46 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
48 //if you change this function template please pay attention to
49 //function getObject, where this is similar implemented
51 template<typename T
> T
CachedContentResultSet::rowOriginGet(
52 T (SAL_CALL
css::sdbc::XRow::* f
)(sal_Int32
), sal_Int32 columnIndex
)
54 impl_EnsureNotDisposed();
55 ReacquireableGuard
aGuard( m_aMutex
);
56 sal_Int32 nRow
= m_nRow
;
57 sal_Int32 nFetchSize
= m_nFetchSize
;
58 sal_Int32 nFetchDirection
= m_nFetchDirection
;
59 if( !m_aCache
.hasRow( nRow
) )
61 if( !m_aCache
.hasCausedException( nRow
) )
63 if( !m_xFetchProvider
.is() )
65 OSL_FAIL( "broadcaster was disposed already" );
69 if( impl_isForwardOnly() )
70 applyPositionToOrigin( nRow
);
72 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
75 if( !m_aCache
.hasRow( nRow
) )
77 m_bLastReadWasFromCache
= false;
79 applyPositionToOrigin( nRow
);
80 impl_init_xRowOrigin();
81 return (m_xRowOrigin
.get()->*f
)( columnIndex
);
84 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
86 m_bLastReadWasFromCache
= true;
87 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
88 /* Last chance. Try type converter service... */
89 if ( m_bLastCachedReadWasNull
&& rValue
.hasValue() )
91 Reference
< XTypeConverter
> xConverter
= getTypeConverter();
92 if ( xConverter
.is() )
96 Any aConvAny
= xConverter
->convertTo(
98 cppu::UnoType
<T
>::get() );
99 m_bLastCachedReadWasNull
= !( aConvAny
>>= aRet
);
101 catch (const IllegalArgumentException
&)
104 catch (const CannotConvertException
&)
114 // CCRS_Cache methoeds.
118 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
119 const Reference
< XContentIdentifierMapping
> & xMapping
)
121 , m_xContentIdentifierMapping( xMapping
)
122 , m_pMappedReminder( NULL
)
126 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
131 void SAL_CALL
CachedContentResultSet::CCRS_Cache
139 clearMappedReminder();
142 void SAL_CALL
CachedContentResultSet::CCRS_Cache
143 ::loadData( const FetchResult
& rResult
)
146 m_pResult
= new FetchResult( rResult
);
149 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
150 ::hasRow( sal_Int32 row
)
154 long nStart
= m_pResult
->StartIndex
;
156 if( m_pResult
->Orientation
)
157 nEnd
+= m_pResult
->Rows
.getLength() - 1;
159 nStart
-= m_pResult
->Rows
.getLength() + 1;
161 return nStart
<= row
&& row
<= nEnd
;
164 sal_Int32 SAL_CALL
CachedContentResultSet::CCRS_Cache
169 long nEnd
= m_pResult
->StartIndex
;
170 if( m_pResult
->Orientation
)
171 return nEnd
+= m_pResult
->Rows
.getLength() - 1;
176 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
182 if( ( m_pResult
->FetchError
& FetchError::ENDOFDATA
)
183 && m_pResult
->Orientation
184 && m_pResult
->Rows
.getLength() )
190 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
191 ::hasCausedException( sal_Int32 nRow
)
195 if( !( m_pResult
->FetchError
& FetchError::EXCEPTION
) )
198 long nEnd
= m_pResult
->StartIndex
;
199 if( m_pResult
->Orientation
)
200 nEnd
+= m_pResult
->Rows
.getLength();
202 return nRow
== nEnd
+1;
205 Any
& SAL_CALL
CachedContentResultSet::CCRS_Cache
206 ::getRowAny( sal_Int32 nRow
)
211 throw SQLException();
213 throw SQLException();
214 if( !hasRow( nRow
) )
215 throw SQLException();
217 long nDiff
= nRow
- m_pResult
->StartIndex
;
221 return (m_pResult
->Rows
)[nDiff
];
224 void SAL_CALL
CachedContentResultSet::CCRS_Cache
225 ::remindMapped( sal_Int32 nRow
)
227 //remind that this row was mapped
230 long nDiff
= nRow
- m_pResult
->StartIndex
;
233 Sequence
< sal_Bool
>* pMappedReminder
= getMappedReminder();
234 if( nDiff
< pMappedReminder
->getLength() )
235 (*pMappedReminder
)[nDiff
] = sal_True
;
238 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
239 ::isRowMapped( sal_Int32 nRow
)
241 if( !m_pMappedReminder
|| !m_pResult
)
243 long nDiff
= nRow
- m_pResult
->StartIndex
;
246 if( nDiff
< m_pMappedReminder
->getLength() )
247 return (*m_pMappedReminder
)[nDiff
];
251 void SAL_CALL
CachedContentResultSet::CCRS_Cache
252 ::clearMappedReminder()
254 delete m_pMappedReminder
;
255 m_pMappedReminder
= NULL
;
258 Sequence
< sal_Bool
>* SAL_CALL
CachedContentResultSet::CCRS_Cache
259 ::getMappedReminder()
261 if( !m_pMappedReminder
)
263 sal_Int32 nCount
= m_pResult
->Rows
.getLength();
264 m_pMappedReminder
= new Sequence
< sal_Bool
>( nCount
);
265 for( ;nCount
; nCount
-- )
266 (*m_pMappedReminder
)[nCount
] = sal_False
;
268 return m_pMappedReminder
;
271 const Any
& SAL_CALL
CachedContentResultSet::CCRS_Cache
272 ::getAny( sal_Int32 nRow
, sal_Int32 nColumnIndex
)
277 throw SQLException();
278 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
280 Any
& rRow
= getRowAny( nRow
);
281 Sequence
< Any
> aValue
;
283 if( m_xContentIdentifierMapping
->mapRow( aValue
) )
286 remindMapped( nRow
);
289 m_xContentIdentifierMapping
.clear();
291 const Sequence
< Any
>& rRow
=
292 (* static_cast< const Sequence
< Any
> * >
293 (getRowAny( nRow
).getValue() ));
295 if( nColumnIndex
> rRow
.getLength() )
296 throw SQLException();
297 return rRow
[nColumnIndex
-1];
300 const OUString
& SAL_CALL
CachedContentResultSet::CCRS_Cache
301 ::getContentIdentifierString( sal_Int32 nRow
)
302 throw( com::sun::star::uno::RuntimeException
)
306 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
308 Any
& rRow
= getRowAny( nRow
);
311 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifierString( aValue
);
312 remindMapped( nRow
);
314 return (* static_cast< const OUString
* >
315 (getRowAny( nRow
).getValue() ));
317 catch(const SQLException
&)
319 throw RuntimeException();
323 const Reference
< XContentIdentifier
>& SAL_CALL
CachedContentResultSet::CCRS_Cache
324 ::getContentIdentifier( sal_Int32 nRow
)
325 throw( com::sun::star::uno::RuntimeException
)
329 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
331 Any
& rRow
= getRowAny( nRow
);
332 Reference
< XContentIdentifier
> aValue
;
334 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifier( aValue
);
335 remindMapped( nRow
);
337 return (* static_cast< const Reference
< XContentIdentifier
> * >
338 (getRowAny( nRow
).getValue() ));
340 catch(const SQLException
&)
342 throw RuntimeException();
346 const Reference
< XContent
>& SAL_CALL
CachedContentResultSet::CCRS_Cache
347 ::getContent( sal_Int32 nRow
)
348 throw( com::sun::star::uno::RuntimeException
)
352 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
354 Any
& rRow
= getRowAny( nRow
);
355 Reference
< XContent
> aValue
;
357 rRow
<<= m_xContentIdentifierMapping
->mapContent( aValue
);
358 remindMapped( nRow
);
360 return (* static_cast< const Reference
< XContent
> * >
361 (getRowAny( nRow
).getValue() ));
363 catch (const SQLException
&)
365 throw RuntimeException();
371 // class CCRS_PropertySetInfo
375 class CCRS_PropertySetInfo
:
376 public cppu::OWeakObject
,
377 public com::sun::star::lang::XTypeProvider
,
378 public com::sun::star::beans::XPropertySetInfo
380 friend class CachedContentResultSet
;
383 Sequence
< com::sun::star::beans::Property
>*
386 //some helping variables ( names for my special properties )
387 static OUString m_aPropertyNameForCount
;
388 static OUString m_aPropertyNameForFinalCount
;
389 static OUString m_aPropertyNameForFetchSize
;
390 static OUString m_aPropertyNameForFetchDirection
;
392 long m_nFetchSizePropertyHandle
;
393 long m_nFetchDirectionPropertyHandle
;
397 impl_getRemainedHandle() const;
401 const OUString
& rName
402 , com::sun::star::beans::Property
& rProp
) const;
404 impl_getPos( const OUString
& rName
) const;
407 impl_isMyPropertyName( const OUString
& rName
);
410 CCRS_PropertySetInfo( Reference
<
411 XPropertySetInfo
> xPropertySetInfoOrigin
);
413 virtual ~CCRS_PropertySetInfo();
416 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
)
417 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
418 virtual void SAL_CALL
acquire()
419 throw() SAL_OVERRIDE
;
420 virtual void SAL_CALL
release()
421 throw() SAL_OVERRIDE
;
424 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId()
425 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
426 virtual css::uno::Sequence
< com::sun::star::uno::Type
> SAL_CALL
getTypes()
427 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
430 virtual Sequence
< com::sun::star::beans::Property
> SAL_CALL
432 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
434 virtual com::sun::star::beans::Property SAL_CALL
435 getPropertyByName( const OUString
& aName
)
436 throw( com::sun::star::beans::UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
438 virtual sal_Bool SAL_CALL
439 hasPropertyByName( const OUString
& Name
)
440 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
443 OUString
CCRS_PropertySetInfo::m_aPropertyNameForCount( "RowCount" );
444 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( "IsRowCountFinal" );
445 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( "FetchSize" );
446 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( "FetchDirection" );
448 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
449 Reference
< XPropertySetInfo
> xInfo
)
450 : m_pProperties( NULL
)
451 , m_nFetchSizePropertyHandle( -1 )
452 , m_nFetchDirectionPropertyHandle( -1 )
454 //initialize list of properties:
456 // it is required, that the received xInfo contains the two
457 // properties with names 'm_aPropertyNameForCount' and
458 // 'm_aPropertyNameForFinalCount'
462 Sequence
<Property
> aProps
= xInfo
->getProperties();
463 m_pProperties
= new Sequence
<Property
> ( aProps
);
467 OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
468 m_pProperties
= new Sequence
<Property
>;
471 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
472 sal_Int32 nFetchSize
= impl_getPos( m_aPropertyNameForFetchSize
);
473 sal_Int32 nFetchDirection
= impl_getPos( m_aPropertyNameForFetchDirection
);
474 sal_Int32 nDeleted
= 0;
475 if( nFetchSize
!= -1 )
477 if( nFetchDirection
!= -1 )
480 boost::scoped_ptr
<Sequence
< Property
> > pOrigProps(new Sequence
<Property
> ( *m_pProperties
));
481 sal_Int32 nOrigProps
= pOrigProps
->getLength();
483 m_pProperties
->realloc( nOrigProps
+ 2 - nDeleted
);//note that nDeleted is <= 2
484 for( sal_Int32 n
= 0, m
= 0; n
< nOrigProps
; n
++, m
++ )
486 if( n
== nFetchSize
|| n
== nFetchDirection
)
489 (*m_pProperties
)[ m
] = (*pOrigProps
)[ n
];
492 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
];
493 rMyProp
.Name
= m_aPropertyNameForFetchSize
;
494 rMyProp
.Type
= cppu::UnoType
<sal_Int32
>::get();
495 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
497 if( nFetchSize
!= -1 )
498 m_nFetchSizePropertyHandle
= (*pOrigProps
)[nFetchSize
].Handle
;
500 m_nFetchSizePropertyHandle
= impl_getRemainedHandle();
502 rMyProp
.Handle
= m_nFetchSizePropertyHandle
;
506 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
+ 1 ];
507 rMyProp
.Name
= m_aPropertyNameForFetchDirection
;
508 rMyProp
.Type
= cppu::UnoType
<sal_Bool
>::get();
509 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
511 if( nFetchDirection
!= -1 )
512 m_nFetchDirectionPropertyHandle
= (*pOrigProps
)[nFetchDirection
].Handle
;
514 m_nFetchDirectionPropertyHandle
= impl_getRemainedHandle();
516 m_nFetchDirectionPropertyHandle
= rMyProp
.Handle
;
520 CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
522 delete m_pProperties
;
526 // XInterface methods.
528 void SAL_CALL
CCRS_PropertySetInfo::acquire()
531 OWeakObject::acquire();
534 void SAL_CALL
CCRS_PropertySetInfo::release()
537 OWeakObject::release();
540 css::uno::Any SAL_CALL
CCRS_PropertySetInfo::queryInterface( const css::uno::Type
& rType
)
541 throw( css::uno::RuntimeException
, std::exception
)
543 css::uno::Any aRet
= cppu::queryInterface( rType
,
544 (static_cast< XTypeProvider
* >(this)),
545 (static_cast< XPropertySetInfo
* >(this))
547 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
550 // XTypeProvider methods.
552 //list all interfaces exclusive baseclasses
553 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
558 // XPropertySetInfo methods.
561 Sequence
< Property
> SAL_CALL CCRS_PropertySetInfo
562 ::getProperties() throw( RuntimeException
, std::exception
)
564 return *m_pProperties
;
568 Property SAL_CALL CCRS_PropertySetInfo
569 ::getPropertyByName( const OUString
& aName
)
570 throw( UnknownPropertyException
, RuntimeException
, std::exception
)
572 if ( aName
.isEmpty() )
573 throw UnknownPropertyException();
576 if ( impl_queryProperty( aName
, aProp
) )
579 throw UnknownPropertyException();
583 sal_Bool SAL_CALL CCRS_PropertySetInfo
584 ::hasPropertyByName( const OUString
& Name
)
585 throw( RuntimeException
, std::exception
)
587 return ( impl_getPos( Name
) != -1 );
594 sal_Int32 SAL_CALL CCRS_PropertySetInfo
595 ::impl_getPos( const OUString
& rName
) const
597 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
599 const Property
& rMyProp
= (*m_pProperties
)[nN
];
600 if( rMyProp
.Name
== rName
)
606 bool SAL_CALL CCRS_PropertySetInfo
607 ::impl_queryProperty( const OUString
& rName
, Property
& rProp
) const
609 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
611 const Property
& rMyProp
= (*m_pProperties
)[nN
];
612 if( rMyProp
.Name
== rName
)
614 rProp
.Name
= rMyProp
.Name
;
615 rProp
.Handle
= rMyProp
.Handle
;
616 rProp
.Type
= rMyProp
.Type
;
617 rProp
.Attributes
= rMyProp
.Attributes
;
626 bool SAL_CALL CCRS_PropertySetInfo
627 ::impl_isMyPropertyName( const OUString
& rPropertyName
)
629 return ( rPropertyName
== m_aPropertyNameForCount
630 || rPropertyName
== m_aPropertyNameForFinalCount
631 || rPropertyName
== m_aPropertyNameForFetchSize
632 || rPropertyName
== m_aPropertyNameForFetchDirection
);
635 sal_Int32 SAL_CALL CCRS_PropertySetInfo
636 ::impl_getRemainedHandle( ) const
638 sal_Int32 nHandle
= 1;
642 OSL_FAIL( "Properties not initialized yet" );
649 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
651 if( nHandle
== (*m_pProperties
)[nN
].Handle
)
664 // class CachedContentResultSet
668 CachedContentResultSet::CachedContentResultSet(
669 const Reference
< XComponentContext
> & rxContext
670 , const Reference
< XResultSet
> & xOrigin
671 , const Reference
< XContentIdentifierMapping
> &
672 xContentIdentifierMapping
)
673 : ContentResultSetWrapper( xOrigin
)
675 , m_xContext( rxContext
)
676 , m_xFetchProvider( NULL
)
677 , m_xFetchProviderForContentAccess( NULL
)
679 , m_xMyPropertySetInfo( NULL
)
680 , m_pMyPropSetInfo( NULL
)
682 , m_xContentIdentifierMapping( xContentIdentifierMapping
)
683 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
684 , m_bAfterLast( false )
685 , m_nLastAppliedPos( 0 )
686 , m_bAfterLastApplied( false )
688 , m_bFinalCount( false )
690 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
)
692 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
)
694 , m_bLastReadWasFromCache( false )
695 , m_bLastCachedReadWasNull( true )
696 , m_aCache( m_xContentIdentifierMapping
)
697 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping
)
698 , m_aCacheContentIdentifier( m_xContentIdentifierMapping
)
699 , m_aCacheContent( m_xContentIdentifierMapping
)
700 , m_bTriedToGetTypeConverter( false )
701 , m_xTypeConverter( NULL
)
703 m_xFetchProvider
= Reference
< XFetchProvider
>( m_xResultSetOrigin
, UNO_QUERY
);
704 OSL_ENSURE( m_xFetchProvider
.is(), "interface XFetchProvider is required" );
706 m_xFetchProviderForContentAccess
= Reference
< XFetchProviderForContentAccess
>( m_xResultSetOrigin
, UNO_QUERY
);
707 OSL_ENSURE( m_xFetchProviderForContentAccess
.is(), "interface XFetchProviderForContentAccess is required" );
712 CachedContentResultSet::~CachedContentResultSet()
715 //do not delete m_pMyPropSetInfo, cause it is hold via reference
722 bool SAL_CALL CachedContentResultSet
723 ::applyPositionToOrigin( sal_Int32 nRow
)
727 impl_EnsureNotDisposed();
731 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
735 ReacquireableGuard
aGuard( m_aMutex
);
736 OSL_ENSURE( nRow
>= 0, "only positive values supported" );
737 if( !m_xResultSetOrigin
.is() )
739 OSL_FAIL( "broadcaster was disposed already" );
742 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
744 sal_Int32 nLastAppliedPos
= m_nLastAppliedPos
;
745 bool bAfterLastApplied
= m_bAfterLastApplied
;
746 bool bAfterLast
= m_bAfterLast
;
747 sal_Int32 nForwardOnly
= m_nForwardOnly
;
751 if( bAfterLastApplied
|| nLastAppliedPos
!= nRow
)
753 if( nForwardOnly
== 1 )
755 if( bAfterLastApplied
|| bAfterLast
|| !nRow
|| nRow
< nLastAppliedPos
)
756 throw SQLException();
758 sal_Int32 nN
= nRow
- nLastAppliedPos
;
760 for( nM
= 0; nN
--; nM
++ )
762 if( !m_xResultSetOrigin
->next() )
767 m_nLastAppliedPos
+= nM
;
768 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
769 return nRow
== m_nLastAppliedPos
;
772 if( !nRow
) //absolute( 0 ) will throw exception
774 m_xResultSetOrigin
->beforeFirst();
777 m_nLastAppliedPos
= 0;
778 m_bAfterLastApplied
= false;
783 //move absolute, if !nLastAppliedPos
784 //because move relative would throw exception
785 if( !nLastAppliedPos
|| bAfterLast
|| bAfterLastApplied
)
787 bool bValid
= m_xResultSetOrigin
->absolute( nRow
);
790 m_nLastAppliedPos
= nRow
;
791 m_bAfterLastApplied
= !bValid
;
796 bool bValid
= m_xResultSetOrigin
->relative( nRow
- nLastAppliedPos
);
799 m_nLastAppliedPos
+= ( nRow
- nLastAppliedPos
);
800 m_bAfterLastApplied
= !bValid
;
804 catch (const SQLException
&)
806 if( !bAfterLastApplied
&& !bAfterLast
&& nRow
> nLastAppliedPos
&& impl_isForwardOnly() )
808 sal_Int32 nN
= nRow
- nLastAppliedPos
;
810 for( nM
= 0; nN
--; nM
++ )
812 if( !m_xResultSetOrigin
->next() )
817 m_nLastAppliedPos
+= nM
;
818 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
824 return nRow
== m_nLastAppliedPos
;
831 //define for fetching data
835 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
836 bool bDirection = !!( \
837 nFetchDirection != FetchDirection::REVERSE ); \
838 FetchResult aResult = \
839 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
840 osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
841 aCache.loadData( aResult ); \
842 sal_Int32 nMax = aCache.getMaxRow(); \
843 sal_Int32 nCurCount = m_nKnownCount; \
844 bool bIsFinalCount = aCache.hasKnownLast(); \
845 bool bCurIsFinalCount = m_bFinalCount; \
847 if( nMax > nCurCount ) \
848 impl_changeRowCount( nCurCount, nMax ); \
849 if( bIsFinalCount && !bCurIsFinalCount ) \
850 impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
852 void SAL_CALL CachedContentResultSet
853 ::impl_fetchData( sal_Int32 nRow
854 , sal_Int32 nFetchSize
, sal_Int32 nFetchDirection
)
855 throw( com::sun::star::uno::RuntimeException
)
857 FETCH_XXX( m_aCache
, m_xFetchProvider
, fetch
);
860 void SAL_CALL CachedContentResultSet
861 ::impl_changeRowCount( sal_Int32 nOld
, sal_Int32 nNew
)
863 OSL_ENSURE( nNew
> nOld
, "RowCount only can grow" );
867 //create PropertyChangeEvent and set value
868 PropertyChangeEvent aEvt
;
870 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
871 aEvt
.Source
= static_cast< XPropertySet
* >( this );
872 aEvt
.Further
= sal_False
;
873 aEvt
.OldValue
<<= nOld
;
874 aEvt
.NewValue
<<= nNew
;
876 m_nKnownCount
= nNew
;
879 //send PropertyChangeEvent to listeners
880 impl_notifyPropertyChangeListeners( aEvt
);
883 void SAL_CALL CachedContentResultSet
884 ::impl_changeIsRowCountFinal( bool bOld
, bool bNew
)
886 OSL_ENSURE( !bOld
&& bNew
, "This change is not allowed for IsRowCountFinal" );
887 if( ! (!bOld
&& bNew
) )
890 //create PropertyChangeEvent and set value
891 PropertyChangeEvent aEvt
;
893 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
894 aEvt
.Source
= static_cast< XPropertySet
* >( this );
895 aEvt
.Further
= sal_False
;
896 aEvt
.OldValue
<<= bOld
;
897 aEvt
.NewValue
<<= bNew
;
899 m_bFinalCount
= bNew
;
902 //send PropertyChangeEvent to listeners
903 impl_notifyPropertyChangeListeners( aEvt
);
906 bool SAL_CALL CachedContentResultSet
907 ::impl_isKnownValidPosition( sal_Int32 nRow
)
909 return m_nKnownCount
&& nRow
910 && nRow
<= m_nKnownCount
;
913 bool SAL_CALL CachedContentResultSet
914 ::impl_isKnownInvalidPosition( sal_Int32 nRow
)
920 return nRow
> m_nKnownCount
;
925 void SAL_CALL CachedContentResultSet
926 ::impl_initPropertySetInfo()
928 ContentResultSetWrapper::impl_initPropertySetInfo();
930 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
931 if( m_pMyPropSetInfo
)
933 m_pMyPropSetInfo
= new CCRS_PropertySetInfo( m_xPropertySetInfo
);
934 m_xMyPropertySetInfo
= m_pMyPropSetInfo
;
935 m_xPropertySetInfo
= m_xMyPropertySetInfo
;
939 // XInterface methods.
940 void SAL_CALL
CachedContentResultSet::acquire()
943 OWeakObject::acquire();
946 void SAL_CALL
CachedContentResultSet::release()
949 OWeakObject::release();
952 Any SAL_CALL CachedContentResultSet
953 ::queryInterface( const Type
& rType
)
954 throw ( RuntimeException
, std::exception
)
956 //list all interfaces inclusive baseclasses of interfaces
958 Any aRet
= ContentResultSetWrapper::queryInterface( rType
);
959 if( aRet
.hasValue() )
962 aRet
= cppu::queryInterface( rType
,
963 static_cast< XTypeProvider
* >( this ),
964 static_cast< XServiceInfo
* >( this ) );
966 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
970 // XTypeProvider methods.
972 //list all interfaces exclusive baseclasses
973 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
978 , XResultSetMetaDataSupplier
981 , XPropertyChangeListener
982 , XVetoableChangeListener
990 // XServiceInfo methods.
993 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet
,
995 "com.sun.star.comp.ucb.CachedContentResultSet" ),
996 CACHED_CONTENT_RESULTSET_SERVICE_NAME
);
999 // XPropertySet methods. ( inherited )
1003 void SAL_CALL CachedContentResultSet
1004 ::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
1005 throw( UnknownPropertyException
,
1006 PropertyVetoException
,
1007 IllegalArgumentException
,
1008 WrappedTargetException
,
1009 RuntimeException
, std::exception
)
1011 impl_EnsureNotDisposed();
1013 if( !getPropertySetInfo().is() )
1015 OSL_FAIL( "broadcaster was disposed already" );
1016 throw UnknownPropertyException();
1019 Property aProp
= m_pMyPropSetInfo
->getPropertyByName( aPropertyName
);
1020 //throws UnknownPropertyException, if so
1022 if( aProp
.Attributes
& PropertyAttribute::READONLY
)
1024 //It is assumed, that the properties
1025 //'RowCount' and 'IsRowCountFinal' are readonly!
1026 throw IllegalArgumentException();
1028 if( aProp
.Name
== CCRS_PropertySetInfo
1029 ::m_aPropertyNameForFetchDirection
)
1033 if( !( aValue
>>= nNew
) )
1035 throw IllegalArgumentException();
1038 if( nNew
== FetchDirection::UNKNOWN
)
1040 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
;
1042 else if( !( nNew
== FetchDirection::FORWARD
1043 || nNew
== FetchDirection::REVERSE
) )
1045 throw IllegalArgumentException();
1048 //create PropertyChangeEvent and set value
1049 PropertyChangeEvent aEvt
;
1051 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1052 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1053 aEvt
.PropertyName
= aPropertyName
;
1054 aEvt
.Further
= sal_False
;
1055 aEvt
.PropertyHandle
= m_pMyPropSetInfo
->
1056 m_nFetchDirectionPropertyHandle
;
1057 aEvt
.OldValue
<<= m_nFetchDirection
;
1058 aEvt
.NewValue
<<= nNew
;
1060 m_nFetchDirection
= nNew
;
1063 //send PropertyChangeEvent to listeners
1064 impl_notifyPropertyChangeListeners( aEvt
);
1066 else if( aProp
.Name
== CCRS_PropertySetInfo
1067 ::m_aPropertyNameForFetchSize
)
1071 if( !( aValue
>>= nNew
) )
1073 throw IllegalArgumentException();
1078 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
;
1081 //create PropertyChangeEvent and set value
1082 PropertyChangeEvent aEvt
;
1084 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1085 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1086 aEvt
.PropertyName
= aPropertyName
;
1087 aEvt
.Further
= sal_False
;
1088 aEvt
.PropertyHandle
= m_pMyPropSetInfo
->
1089 m_nFetchSizePropertyHandle
;
1090 aEvt
.OldValue
<<= m_nFetchSize
;
1091 aEvt
.NewValue
<<= nNew
;
1093 m_nFetchSize
= nNew
;
1096 //send PropertyChangeEvent to listeners
1097 impl_notifyPropertyChangeListeners( aEvt
);
1101 impl_init_xPropertySetOrigin();
1103 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1104 if( !m_xPropertySetOrigin
.is() )
1106 OSL_FAIL( "broadcaster was disposed already" );
1110 m_xPropertySetOrigin
->setPropertyValue( aPropertyName
, aValue
);
1116 Any SAL_CALL CachedContentResultSet
1117 ::getPropertyValue( const OUString
& rPropertyName
)
1118 throw( UnknownPropertyException
,
1119 WrappedTargetException
,
1120 RuntimeException
, std::exception
)
1122 impl_EnsureNotDisposed();
1124 if( !getPropertySetInfo().is() )
1126 OSL_FAIL( "broadcaster was disposed already" );
1127 throw UnknownPropertyException();
1130 Property aProp
= m_pMyPropSetInfo
->getPropertyByName( rPropertyName
);
1131 //throws UnknownPropertyException, if so
1134 if( rPropertyName
== CCRS_PropertySetInfo
1135 ::m_aPropertyNameForCount
)
1137 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1138 aValue
<<= m_nKnownCount
;
1140 else if( rPropertyName
== CCRS_PropertySetInfo
1141 ::m_aPropertyNameForFinalCount
)
1143 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1144 aValue
<<= m_bFinalCount
;
1146 else if( rPropertyName
== CCRS_PropertySetInfo
1147 ::m_aPropertyNameForFetchSize
)
1149 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1150 aValue
<<= m_nFetchSize
;
1152 else if( rPropertyName
== CCRS_PropertySetInfo
1153 ::m_aPropertyNameForFetchDirection
)
1155 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1156 aValue
<<= m_nFetchDirection
;
1160 impl_init_xPropertySetOrigin();
1162 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1163 if( !m_xPropertySetOrigin
.is() )
1165 OSL_FAIL( "broadcaster was disposed already" );
1166 throw UnknownPropertyException();
1169 aValue
= m_xPropertySetOrigin
->getPropertyValue( rPropertyName
);
1175 // own methods. ( inherited )
1179 void SAL_CALL CachedContentResultSet
1180 ::impl_disposing( const EventObject
& rEventObject
)
1181 throw( RuntimeException
)
1184 impl_EnsureNotDisposed();
1185 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1186 //release all references to the broadcaster:
1187 m_xFetchProvider
.clear();
1188 m_xFetchProviderForContentAccess
.clear();
1190 ContentResultSetWrapper::impl_disposing( rEventObject
);
1194 void SAL_CALL CachedContentResultSet
1195 ::impl_propertyChange( const PropertyChangeEvent
& rEvt
)
1196 throw( RuntimeException
)
1198 impl_EnsureNotDisposed();
1200 PropertyChangeEvent
aEvt( rEvt
);
1201 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1202 aEvt
.Further
= sal_False
;
1205 if( CCRS_PropertySetInfo
1206 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1208 //don't notify foreign events on fetchsize and fetchdirection
1209 if( aEvt
.PropertyName
== CCRS_PropertySetInfo
1210 ::m_aPropertyNameForFetchSize
1211 || aEvt
.PropertyName
== CCRS_PropertySetInfo
1212 ::m_aPropertyNameForFetchDirection
)
1215 //adjust my props 'RowCount' and 'IsRowCountFinal'
1216 if( aEvt
.PropertyName
== CCRS_PropertySetInfo
1217 ::m_aPropertyNameForCount
)
1222 if( !( aEvt
.NewValue
>>= nNew
) )
1224 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1228 impl_changeRowCount( m_nKnownCount
, nNew
);
1230 else if( aEvt
.PropertyName
== CCRS_PropertySetInfo
1231 ::m_aPropertyNameForFinalCount
)
1232 {//IsRowCountFinal changed
1236 if( !( aEvt
.NewValue
>>= bNew
) )
1238 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1241 impl_changeIsRowCountFinal( m_bFinalCount
, bNew
);
1247 impl_notifyPropertyChangeListeners( aEvt
);
1252 void SAL_CALL CachedContentResultSet
1253 ::impl_vetoableChange( const PropertyChangeEvent
& rEvt
)
1254 throw( PropertyVetoException
,
1257 impl_EnsureNotDisposed();
1259 //don't notify events on my properties, cause they are not vetoable
1260 if( CCRS_PropertySetInfo
1261 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1267 PropertyChangeEvent
aEvt( rEvt
);
1268 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1269 aEvt
.Further
= sal_False
;
1271 impl_notifyVetoableChangeListeners( aEvt
);
1275 // XContentAccess methods. ( inherited ) ( -- position dependent )
1278 #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1279 impl_EnsureNotDisposed(); \
1280 ReacquireableGuard aGuard( m_aMutex ); \
1281 sal_Int32 nRow = m_nRow; \
1282 sal_Int32 nFetchSize = m_nFetchSize; \
1283 sal_Int32 nFetchDirection = m_nFetchDirection; \
1284 if( !m_aCache##XXX.hasRow( nRow ) ) \
1288 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1290 if( !m_xFetchProviderForContentAccess.is() ) \
1292 OSL_FAIL( "broadcaster was disposed already" ); \
1293 throw RuntimeException(); \
1296 if( impl_isForwardOnly() ) \
1297 applyPositionToOrigin( nRow ); \
1299 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1301 aGuard.reacquire(); \
1302 if( !m_aCache##XXX.hasRow( nRow ) ) \
1305 applyPositionToOrigin( nRow ); \
1306 TYPE aRet = ContentResultSetWrapper::queryXXX();\
1307 if( m_xContentIdentifierMapping.is() ) \
1308 return m_xContentIdentifierMapping->map##XXX( aRet );\
1312 catch (const RuntimeException&) \
1316 catch (const Exception& e) \
1318 Any a(cppu::getCaughtException()); \
1319 throw WrappedTargetRuntimeException( \
1320 "wrapped Exception " + e.Message, \
1321 Reference<XInterface>(), a); \
1324 return m_aCache##XXX.get##XXX( nRow );
1327 OUString SAL_CALL CachedContentResultSet
1328 ::queryContentIdentifierString()
1329 throw( RuntimeException
, std::exception
)
1331 XCONTENTACCESS_queryXXX( queryContentIdentifierString
, ContentIdentifierString
, OUString
)
1336 Reference
< XContentIdentifier
> SAL_CALL CachedContentResultSet
1337 ::queryContentIdentifier()
1338 throw( RuntimeException
, std::exception
)
1340 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1345 Reference
< XContent
> SAL_CALL CachedContentResultSet
1347 throw( RuntimeException
, std::exception
)
1349 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1353 // XResultSet methods. ( inherited )
1357 sal_Bool SAL_CALL CachedContentResultSet
1359 throw( SQLException
,
1360 RuntimeException
, std::exception
)
1362 impl_EnsureNotDisposed();
1364 ReacquireableGuard
aGuard( m_aMutex
);
1374 m_bAfterLast
= true;
1378 //known valid position
1379 if( impl_isKnownValidPosition( m_nRow
+ 1 ) )
1386 sal_Int32 nRow
= m_nRow
;
1389 bool bValid
= applyPositionToOrigin( nRow
+ 1 );
1393 m_bAfterLast
= !bValid
;
1398 sal_Bool SAL_CALL CachedContentResultSet
1400 throw( SQLException
,
1401 RuntimeException
, std::exception
)
1403 impl_EnsureNotDisposed();
1405 if( impl_isForwardOnly() )
1406 throw SQLException();
1408 ReacquireableGuard
aGuard( m_aMutex
);
1410 if( !m_bAfterLast
&& !m_nRow
)
1413 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1416 m_bAfterLast
= false;
1419 //known valid position ?:
1420 if( impl_isKnownValidPosition( m_nRow
- 1 ) )
1423 m_bAfterLast
= false;
1427 sal_Int32 nRow
= m_nRow
;
1430 bool bValid
= applyPositionToOrigin( nRow
- 1 );
1434 m_bAfterLast
= false;
1439 sal_Bool SAL_CALL CachedContentResultSet
1440 ::absolute( sal_Int32 row
)
1441 throw( SQLException
,
1442 RuntimeException
, std::exception
)
1444 impl_EnsureNotDisposed();
1447 throw SQLException();
1449 if( impl_isForwardOnly() )
1450 throw SQLException();
1452 ReacquireableGuard
aGuard( m_aMutex
);
1454 if( !m_xResultSetOrigin
.is() )
1456 OSL_FAIL( "broadcaster was disposed already" );
1463 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1471 m_bAfterLast
= false;
1474 //unknown final count:
1477 // Solaris has problems catching or propagating derived exceptions
1478 // when only the base class is known, so make ResultSetException
1479 // (derived from SQLException) known here:
1483 bValid
= m_xResultSetOrigin
->absolute( row
);
1485 catch (const ResultSetException
&)
1493 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1496 m_nLastAppliedPos
= nNewRow
;
1498 m_bAfterLastApplied
= m_bAfterLast
= false;
1503 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1506 m_nLastAppliedPos
= nCurRow
;
1508 m_bAfterLast
= false;
1509 return nCurRow
!= 0;
1514 if( row
> m_nKnownCount
)
1516 m_nRow
= m_nKnownCount
+ 1;
1517 m_bAfterLast
= true;
1521 m_bAfterLast
= false;
1524 //unknown new position:
1527 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1532 sal_Int32 nNewRow
= row
;
1533 if( nNewRow
> m_nKnownCount
)
1535 nNewRow
= m_nKnownCount
+ 1;
1536 m_bAfterLastApplied
= m_bAfterLast
= true;
1539 m_bAfterLastApplied
= m_bAfterLast
= false;
1541 m_nLastAppliedPos
= nNewRow
;
1547 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1548 bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1551 m_nLastAppliedPos
= nCurRow
;
1553 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1554 return nCurRow
&& !bIsAfterLast
;
1558 sal_Bool SAL_CALL CachedContentResultSet
1559 ::relative( sal_Int32 rows
)
1560 throw( SQLException
,
1561 RuntimeException
, std::exception
)
1563 impl_EnsureNotDisposed();
1565 if( impl_isForwardOnly() )
1566 throw SQLException();
1568 ReacquireableGuard
aGuard( m_aMutex
);
1569 if( m_bAfterLast
|| impl_isKnownInvalidPosition( m_nRow
) )
1570 throw SQLException();
1575 sal_Int32 nNewRow
= m_nRow
+ rows
;
1579 if( impl_isKnownValidPosition( nNewRow
) )
1582 m_bAfterLast
= false;
1587 //known invalid new position:
1590 m_bAfterLast
= false;
1594 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1596 m_bAfterLast
= true;
1597 m_nRow
= m_nKnownCount
+ 1;
1600 //unknown new position:
1602 bool bValid
= applyPositionToOrigin( nNewRow
);
1606 m_bAfterLast
= !bValid
&& nNewRow
> 0;
1613 sal_Bool SAL_CALL CachedContentResultSet
1615 throw( SQLException
,
1616 RuntimeException
, std::exception
)
1618 impl_EnsureNotDisposed();
1620 if( impl_isForwardOnly() )
1621 throw SQLException();
1623 ReacquireableGuard
aGuard( m_aMutex
);
1624 if( impl_isKnownValidPosition( 1 ) )
1627 m_bAfterLast
= false;
1630 if( impl_isKnownInvalidPosition( 1 ) )
1633 m_bAfterLast
= false;
1639 bool bValid
= applyPositionToOrigin( 1 );
1643 m_bAfterLast
= false;
1648 sal_Bool SAL_CALL CachedContentResultSet
1650 throw( SQLException
,
1651 RuntimeException
, std::exception
)
1653 impl_EnsureNotDisposed();
1655 if( impl_isForwardOnly() )
1656 throw SQLException();
1658 ReacquireableGuard
aGuard( m_aMutex
);
1661 m_nRow
= m_nKnownCount
;
1662 m_bAfterLast
= false;
1663 return m_nKnownCount
!= 0;
1666 if( !m_xResultSetOrigin
.is() )
1668 OSL_FAIL( "broadcaster was disposed already" );
1673 bool bValid
= m_xResultSetOrigin
->last();
1676 m_bAfterLastApplied
= m_bAfterLast
= false;
1679 m_nLastAppliedPos
= m_nKnownCount
;
1680 m_nRow
= m_nKnownCount
;
1685 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1688 m_nLastAppliedPos
= nCurRow
;
1690 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1691 m_nKnownCount
= nCurRow
;
1692 m_bFinalCount
= true;
1693 return nCurRow
!= 0;
1697 void SAL_CALL CachedContentResultSet
1699 throw( SQLException
,
1700 RuntimeException
, std::exception
)
1702 impl_EnsureNotDisposed();
1704 if( impl_isForwardOnly() )
1705 throw SQLException();
1707 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1709 m_bAfterLast
= false;
1713 void SAL_CALL CachedContentResultSet
1715 throw( SQLException
,
1716 RuntimeException
, std::exception
)
1718 impl_EnsureNotDisposed();
1720 if( impl_isForwardOnly() )
1721 throw SQLException();
1723 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1725 m_bAfterLast
= true;
1729 sal_Bool SAL_CALL CachedContentResultSet
1731 throw( SQLException
,
1732 RuntimeException
, std::exception
)
1734 impl_EnsureNotDisposed();
1736 ReacquireableGuard
aGuard( m_aMutex
);
1740 return m_bAfterLast
;
1744 if( !m_xResultSetOrigin
.is() )
1746 OSL_FAIL( "broadcaster was disposed already" );
1751 //find out whethter the original resultset contains rows or not
1752 m_xResultSetOrigin
->afterLast();
1755 m_bAfterLastApplied
= true;
1758 return m_xResultSetOrigin
->isAfterLast();
1762 sal_Bool SAL_CALL CachedContentResultSet
1764 throw( SQLException
,
1765 RuntimeException
, std::exception
)
1767 impl_EnsureNotDisposed();
1769 ReacquireableGuard
aGuard( m_aMutex
);
1779 if( !m_xResultSetOrigin
.is() )
1781 OSL_FAIL( "broadcaster was disposed already" );
1786 //find out whethter the original resultset contains rows or not
1787 m_xResultSetOrigin
->beforeFirst();
1790 m_bAfterLastApplied
= false;
1791 m_nLastAppliedPos
= 0;
1794 return m_xResultSetOrigin
->isBeforeFirst();
1798 sal_Bool SAL_CALL CachedContentResultSet
1800 throw( SQLException
,
1801 RuntimeException
, std::exception
)
1803 impl_EnsureNotDisposed();
1806 Reference
< XResultSet
> xResultSetOrigin
;
1809 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1820 xResultSetOrigin
= m_xResultSetOrigin
;
1823 //need to ask origin
1825 if( applyPositionToOrigin( nRow
) )
1826 return xResultSetOrigin
->isFirst();
1833 sal_Bool SAL_CALL CachedContentResultSet
1835 throw( SQLException
,
1836 RuntimeException
, std::exception
)
1838 impl_EnsureNotDisposed();
1841 Reference
< XResultSet
> xResultSetOrigin
;
1843 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1846 if( m_nRow
< m_nKnownCount
)
1849 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1852 xResultSetOrigin
= m_xResultSetOrigin
;
1855 //need to ask origin
1857 if( applyPositionToOrigin( nRow
) )
1858 return xResultSetOrigin
->isLast();
1866 sal_Int32 SAL_CALL CachedContentResultSet
1868 throw( SQLException
,
1869 RuntimeException
, std::exception
)
1871 impl_EnsureNotDisposed();
1873 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1880 void SAL_CALL CachedContentResultSet
1882 throw( SQLException
,
1883 RuntimeException
, std::exception
)
1885 impl_EnsureNotDisposed();
1887 //the ContentResultSet is static and will not change
1888 //therefore we don't need to reload anything
1892 sal_Bool SAL_CALL CachedContentResultSet
1894 throw( SQLException
,
1895 RuntimeException
, std::exception
)
1897 impl_EnsureNotDisposed();
1899 //the ContentResultSet is static and will not change
1903 sal_Bool SAL_CALL CachedContentResultSet
1905 throw( SQLException
,
1906 RuntimeException
, std::exception
)
1908 impl_EnsureNotDisposed();
1910 //the ContentResultSet is static and will not change
1915 sal_Bool SAL_CALL CachedContentResultSet
1917 throw( SQLException
,
1918 RuntimeException
, std::exception
)
1920 impl_EnsureNotDisposed();
1922 //the ContentResultSet is static and will not change
1927 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1929 throw( SQLException
,
1930 RuntimeException
, std::exception
)
1932 impl_EnsureNotDisposed();
1933 //@todo ?return anything
1934 return Reference
< XInterface
>();
1938 // XRow methods. ( inherited )
1942 sal_Bool SAL_CALL CachedContentResultSet
1944 throw( SQLException
,
1945 RuntimeException
, std::exception
)
1947 impl_EnsureNotDisposed();
1948 impl_init_xRowOrigin();
1950 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1951 if( m_bLastReadWasFromCache
)
1952 return m_bLastCachedReadWasNull
;
1953 if( !m_xRowOrigin
.is() )
1955 OSL_FAIL( "broadcaster was disposed already" );
1959 return m_xRowOrigin
->wasNull();
1963 OUString SAL_CALL CachedContentResultSet
1964 ::getString( sal_Int32 columnIndex
)
1965 throw( SQLException
,
1966 RuntimeException
, std::exception
)
1968 return rowOriginGet
<OUString
>(&css::sdbc::XRow::getString
, columnIndex
);
1972 sal_Bool SAL_CALL CachedContentResultSet
1973 ::getBoolean( sal_Int32 columnIndex
)
1974 throw( SQLException
,
1975 RuntimeException
, std::exception
)
1977 return rowOriginGet
<sal_Bool
>(&css::sdbc::XRow::getBoolean
, columnIndex
);
1981 sal_Int8 SAL_CALL CachedContentResultSet
1982 ::getByte( sal_Int32 columnIndex
)
1983 throw( SQLException
,
1984 RuntimeException
, std::exception
)
1986 return rowOriginGet
<sal_Int8
>(&css::sdbc::XRow::getByte
, columnIndex
);
1990 sal_Int16 SAL_CALL CachedContentResultSet
1991 ::getShort( sal_Int32 columnIndex
)
1992 throw( SQLException
,
1993 RuntimeException
, std::exception
)
1995 return rowOriginGet
<sal_Int16
>(&css::sdbc::XRow::getShort
, columnIndex
);
1999 sal_Int32 SAL_CALL CachedContentResultSet
2000 ::getInt( sal_Int32 columnIndex
)
2001 throw( SQLException
,
2002 RuntimeException
, std::exception
)
2004 return rowOriginGet
<sal_Int32
>(&css::sdbc::XRow::getInt
, columnIndex
);
2008 sal_Int64 SAL_CALL CachedContentResultSet
2009 ::getLong( sal_Int32 columnIndex
)
2010 throw( SQLException
,
2011 RuntimeException
, std::exception
)
2013 return rowOriginGet
<sal_Int64
>(&css::sdbc::XRow::getLong
, columnIndex
);
2017 float SAL_CALL CachedContentResultSet
2018 ::getFloat( sal_Int32 columnIndex
)
2019 throw( SQLException
,
2020 RuntimeException
, std::exception
)
2022 return rowOriginGet
<float>(&css::sdbc::XRow::getFloat
, columnIndex
);
2026 double SAL_CALL CachedContentResultSet
2027 ::getDouble( sal_Int32 columnIndex
)
2028 throw( SQLException
,
2029 RuntimeException
, std::exception
)
2031 return rowOriginGet
<double>(&css::sdbc::XRow::getDouble
, columnIndex
);
2035 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
2036 ::getBytes( sal_Int32 columnIndex
)
2037 throw( SQLException
,
2038 RuntimeException
, std::exception
)
2040 return rowOriginGet
< css::uno::Sequence
<sal_Int8
> >(
2041 &css::sdbc::XRow::getBytes
, columnIndex
);
2045 Date SAL_CALL CachedContentResultSet
2046 ::getDate( sal_Int32 columnIndex
)
2047 throw( SQLException
,
2048 RuntimeException
, std::exception
)
2050 return rowOriginGet
<css::util::Date
>(
2051 &css::sdbc::XRow::getDate
, columnIndex
);
2055 Time SAL_CALL CachedContentResultSet
2056 ::getTime( sal_Int32 columnIndex
)
2057 throw( SQLException
,
2058 RuntimeException
, std::exception
)
2060 return rowOriginGet
<css::util::Time
>(
2061 &css::sdbc::XRow::getTime
, columnIndex
);
2065 DateTime SAL_CALL CachedContentResultSet
2066 ::getTimestamp( sal_Int32 columnIndex
)
2067 throw( SQLException
,
2068 RuntimeException
, std::exception
)
2070 return rowOriginGet
<css::util::DateTime
>(
2071 &css::sdbc::XRow::getTimestamp
, columnIndex
);
2075 Reference
< com::sun::star::io::XInputStream
>
2076 SAL_CALL CachedContentResultSet
2077 ::getBinaryStream( sal_Int32 columnIndex
)
2078 throw( SQLException
,
2079 RuntimeException
, std::exception
)
2081 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
2082 &css::sdbc::XRow::getBinaryStream
, columnIndex
);
2086 Reference
< com::sun::star::io::XInputStream
>
2087 SAL_CALL CachedContentResultSet
2088 ::getCharacterStream( sal_Int32 columnIndex
)
2089 throw( SQLException
,
2090 RuntimeException
, std::exception
)
2092 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
2093 &css::sdbc::XRow::getCharacterStream
, columnIndex
);
2097 Any SAL_CALL CachedContentResultSet
2098 ::getObject( sal_Int32 columnIndex
,
2100 com::sun::star::container::XNameAccess
>& typeMap
)
2101 throw( SQLException
,
2102 RuntimeException
, std::exception
)
2104 //if you change this function please pay attention to
2105 //function template rowOriginGet, where this is similar implemented
2107 ReacquireableGuard
aGuard( m_aMutex
);
2108 sal_Int32 nRow
= m_nRow
;
2109 sal_Int32 nFetchSize
= m_nFetchSize
;
2110 sal_Int32 nFetchDirection
= m_nFetchDirection
;
2111 if( !m_aCache
.hasRow( nRow
) )
2113 if( !m_aCache
.hasCausedException( nRow
) )
2115 if( !m_xFetchProvider
.is() )
2117 OSL_FAIL( "broadcaster was disposed already" );
2122 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
2125 if( !m_aCache
.hasRow( nRow
) )
2127 m_bLastReadWasFromCache
= false;
2129 applyPositionToOrigin( nRow
);
2130 impl_init_xRowOrigin();
2131 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
2134 //@todo: pay attention to typeMap
2135 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
2137 m_bLastReadWasFromCache
= true;
2138 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
2143 Reference
< XRef
> SAL_CALL CachedContentResultSet
2144 ::getRef( sal_Int32 columnIndex
)
2145 throw( SQLException
,
2146 RuntimeException
, std::exception
)
2148 return rowOriginGet
< css::uno::Reference
<css::sdbc::XRef
> >(
2149 &css::sdbc::XRow::getRef
, columnIndex
);
2153 Reference
< XBlob
> SAL_CALL CachedContentResultSet
2154 ::getBlob( sal_Int32 columnIndex
)
2155 throw( SQLException
,
2156 RuntimeException
, std::exception
)
2158 return rowOriginGet
< css::uno::Reference
<css::sdbc::XBlob
> >(
2159 &css::sdbc::XRow::getBlob
, columnIndex
);
2163 Reference
< XClob
> SAL_CALL CachedContentResultSet
2164 ::getClob( sal_Int32 columnIndex
)
2165 throw( SQLException
,
2166 RuntimeException
, std::exception
)
2168 return rowOriginGet
< css::uno::Reference
<css::sdbc::XClob
> >(
2169 &css::sdbc::XRow::getClob
, columnIndex
);
2173 Reference
< XArray
> SAL_CALL CachedContentResultSet
2174 ::getArray( sal_Int32 columnIndex
)
2175 throw( SQLException
,
2176 RuntimeException
, std::exception
)
2178 return rowOriginGet
< css::uno::Reference
<css::sdbc::XArray
> >(
2179 &css::sdbc::XRow::getArray
, columnIndex
);
2183 // Type Converter Support
2186 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter()
2188 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2190 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
2192 m_bTriedToGetTypeConverter
= true;
2193 m_xTypeConverter
= Reference
< XTypeConverter
>( Converter::create(m_xContext
) );
2195 OSL_ENSURE( m_xTypeConverter
.is(),
2196 "PropertyValueSet::getTypeConverter() - "
2197 "Service 'com.sun.star.script.Converter' n/a!" );
2199 return m_xTypeConverter
;
2204 // class CachedContentResultSetFactory
2208 CachedContentResultSetFactory::CachedContentResultSetFactory(
2209 const Reference
< XComponentContext
> & rxContext
)
2211 m_xContext
= rxContext
;
2214 CachedContentResultSetFactory::~CachedContentResultSetFactory()
2219 // CachedContentResultSetFactory XInterface methods.
2220 void SAL_CALL
CachedContentResultSetFactory::acquire()
2223 OWeakObject::acquire();
2226 void SAL_CALL
CachedContentResultSetFactory::release()
2229 OWeakObject::release();
2232 css::uno::Any SAL_CALL
CachedContentResultSetFactory::queryInterface( const css::uno::Type
& rType
)
2233 throw( css::uno::RuntimeException
, std::exception
)
2235 css::uno::Any aRet
= cppu::queryInterface( rType
,
2236 (static_cast< XTypeProvider
* >(this)),
2237 (static_cast< XServiceInfo
* >(this)),
2238 (static_cast< XCachedContentResultSetFactory
* >(this))
2240 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
2243 // CachedContentResultSetFactory XTypeProvider methods.
2246 XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory
,
2249 XCachedContentResultSetFactory
);
2252 // CachedContentResultSetFactory XServiceInfo methods.
2255 XSERVICEINFO_IMPL_1_CTX( CachedContentResultSetFactory
,
2256 OUString( "com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
2257 CACHED_CONTENT_RESULTSET_FACTORY_NAME
);
2260 // Service factory implementation.
2263 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory
);
2266 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2270 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2271 ::createCachedContentResultSet(
2272 const Reference
< XResultSet
> & xSource
,
2273 const Reference
< XContentIdentifierMapping
> & xMapping
)
2274 throw( com::sun::star::uno::RuntimeException
, std::exception
)
2276 Reference
< XResultSet
> xRet
;
2277 xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2281 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */