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 <rtl/ustring.hxx>
29 #include <osl/diagnose.h>
30 #include <comphelper/processfactory.hxx>
32 using namespace com::sun::star::beans
;
33 using namespace com::sun::star::lang
;
34 using namespace com::sun::star::script
;
35 using namespace com::sun::star::sdbc
;
36 using namespace com::sun::star::ucb
;
37 using namespace com::sun::star::uno
;
38 using namespace com::sun::star::util
;
42 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
43 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
45 //if you change this function template please pay attention to
46 //function getObject, where this is similar implemented
48 template<typename T
> T
CachedContentResultSet::rowOriginGet(
49 T (SAL_CALL
css::sdbc::XRow::* f
)(sal_Int32
), sal_Int32 columnIndex
)
51 impl_EnsureNotDisposed();
52 ReacquireableGuard
aGuard( m_aMutex
);
53 sal_Int32 nRow
= m_nRow
;
54 sal_Int32 nFetchSize
= m_nFetchSize
;
55 sal_Int32 nFetchDirection
= m_nFetchDirection
;
56 if( !m_aCache
.hasRow( nRow
) )
58 if( !m_aCache
.hasCausedException( nRow
) )
60 if( !m_xFetchProvider
.is() )
62 OSL_FAIL( "broadcaster was disposed already" );
66 if( impl_isForwardOnly() )
67 applyPositionToOrigin( nRow
);
69 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
72 if( !m_aCache
.hasRow( nRow
) )
74 m_bLastReadWasFromCache
= false;
76 applyPositionToOrigin( nRow
);
77 impl_init_xRowOrigin();
78 return (m_xRowOrigin
.get()->*f
)( columnIndex
);
81 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
83 m_bLastReadWasFromCache
= true;
84 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
85 /* Last chance. Try type converter service... */
86 if ( m_bLastCachedReadWasNull
&& rValue
.hasValue() )
88 Reference
< XTypeConverter
> xConverter
= getTypeConverter();
89 if ( xConverter
.is() )
93 Any aConvAny
= xConverter
->convertTo(
95 getCppuType( static_cast<
97 m_bLastCachedReadWasNull
= !( aConvAny
>>= aRet
);
99 catch (const IllegalArgumentException
&)
102 catch (const CannotConvertException
&)
112 // CCRS_Cache methoeds.
116 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
117 const Reference
< XContentIdentifierMapping
> & xMapping
)
119 , m_xContentIdentifierMapping( xMapping
)
120 , m_pMappedReminder( NULL
)
124 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
129 void SAL_CALL
CachedContentResultSet::CCRS_Cache
137 clearMappedReminder();
140 void SAL_CALL
CachedContentResultSet::CCRS_Cache
141 ::loadData( const FetchResult
& rResult
)
144 m_pResult
= new FetchResult( rResult
);
147 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
148 ::hasRow( sal_Int32 row
)
152 long nStart
= m_pResult
->StartIndex
;
154 if( m_pResult
->Orientation
)
155 nEnd
+= m_pResult
->Rows
.getLength() - 1;
157 nStart
-= m_pResult
->Rows
.getLength() + 1;
159 return nStart
<= row
&& row
<= nEnd
;
162 sal_Int32 SAL_CALL
CachedContentResultSet::CCRS_Cache
167 long nEnd
= m_pResult
->StartIndex
;
168 if( m_pResult
->Orientation
)
169 return nEnd
+= m_pResult
->Rows
.getLength() - 1;
174 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
180 if( ( m_pResult
->FetchError
& FetchError::ENDOFDATA
)
181 && m_pResult
->Orientation
182 && m_pResult
->Rows
.getLength() )
188 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
189 ::hasCausedException( sal_Int32 nRow
)
193 if( !( m_pResult
->FetchError
& FetchError::EXCEPTION
) )
196 long nEnd
= m_pResult
->StartIndex
;
197 if( m_pResult
->Orientation
)
198 nEnd
+= m_pResult
->Rows
.getLength();
200 return nRow
== nEnd
+1;
203 Any
& SAL_CALL
CachedContentResultSet::CCRS_Cache
204 ::getRowAny( sal_Int32 nRow
)
209 throw SQLException();
211 throw SQLException();
212 if( !hasRow( nRow
) )
213 throw SQLException();
215 long nDiff
= nRow
- m_pResult
->StartIndex
;
219 return (m_pResult
->Rows
)[nDiff
];
222 void SAL_CALL
CachedContentResultSet::CCRS_Cache
223 ::remindMapped( sal_Int32 nRow
)
225 //remind that this row was mapped
228 long nDiff
= nRow
- m_pResult
->StartIndex
;
231 Sequence
< sal_Bool
>* pMappedReminder
= getMappedReminder();
232 if( nDiff
< pMappedReminder
->getLength() )
233 (*pMappedReminder
)[nDiff
] = sal_True
;
236 bool SAL_CALL
CachedContentResultSet::CCRS_Cache
237 ::isRowMapped( sal_Int32 nRow
)
239 if( !m_pMappedReminder
|| !m_pResult
)
241 long nDiff
= nRow
- m_pResult
->StartIndex
;
244 if( nDiff
< m_pMappedReminder
->getLength() )
245 return (*m_pMappedReminder
)[nDiff
];
249 void SAL_CALL
CachedContentResultSet::CCRS_Cache
250 ::clearMappedReminder()
252 delete m_pMappedReminder
;
253 m_pMappedReminder
= NULL
;
256 Sequence
< sal_Bool
>* SAL_CALL
CachedContentResultSet::CCRS_Cache
257 ::getMappedReminder()
259 if( !m_pMappedReminder
)
261 sal_Int32 nCount
= m_pResult
->Rows
.getLength();
262 m_pMappedReminder
= new Sequence
< sal_Bool
>( nCount
);
263 for( ;nCount
; nCount
-- )
264 (*m_pMappedReminder
)[nCount
] = sal_False
;
266 return m_pMappedReminder
;
269 const Any
& SAL_CALL
CachedContentResultSet::CCRS_Cache
270 ::getAny( sal_Int32 nRow
, sal_Int32 nColumnIndex
)
275 throw SQLException();
276 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
278 Any
& rRow
= getRowAny( nRow
);
279 Sequence
< Any
> aValue
;
281 if( m_xContentIdentifierMapping
->mapRow( aValue
) )
284 remindMapped( nRow
);
287 m_xContentIdentifierMapping
.clear();
289 const Sequence
< Any
>& rRow
=
290 (* reinterpret_cast< const Sequence
< Any
> * >
291 (getRowAny( nRow
).getValue() ));
293 if( nColumnIndex
> rRow
.getLength() )
294 throw SQLException();
295 return rRow
[nColumnIndex
-1];
298 const OUString
& SAL_CALL
CachedContentResultSet::CCRS_Cache
299 ::getContentIdentifierString( sal_Int32 nRow
)
300 throw( com::sun::star::uno::RuntimeException
)
304 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
306 Any
& rRow
= getRowAny( nRow
);
309 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifierString( aValue
);
310 remindMapped( nRow
);
312 return (* reinterpret_cast< const OUString
* >
313 (getRowAny( nRow
).getValue() ));
315 catch(const SQLException
&)
317 throw RuntimeException();
321 const Reference
< XContentIdentifier
>& SAL_CALL
CachedContentResultSet::CCRS_Cache
322 ::getContentIdentifier( sal_Int32 nRow
)
323 throw( com::sun::star::uno::RuntimeException
)
327 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
329 Any
& rRow
= getRowAny( nRow
);
330 Reference
< XContentIdentifier
> aValue
;
332 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifier( aValue
);
333 remindMapped( nRow
);
335 return (* reinterpret_cast< const Reference
< XContentIdentifier
> * >
336 (getRowAny( nRow
).getValue() ));
338 catch(const SQLException
&)
340 throw RuntimeException();
344 const Reference
< XContent
>& SAL_CALL
CachedContentResultSet::CCRS_Cache
345 ::getContent( sal_Int32 nRow
)
346 throw( com::sun::star::uno::RuntimeException
)
350 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
352 Any
& rRow
= getRowAny( nRow
);
353 Reference
< XContent
> aValue
;
355 rRow
<<= m_xContentIdentifierMapping
->mapContent( aValue
);
356 remindMapped( nRow
);
358 return (* reinterpret_cast< const Reference
< XContent
> * >
359 (getRowAny( nRow
).getValue() ));
361 catch (const SQLException
&)
363 throw RuntimeException();
369 // class CCRS_PropertySetInfo
373 class CCRS_PropertySetInfo
:
374 public cppu::OWeakObject
,
375 public com::sun::star::lang::XTypeProvider
,
376 public com::sun::star::beans::XPropertySetInfo
378 friend class CachedContentResultSet
;
381 Sequence
< com::sun::star::beans::Property
>*
384 //some helping variables ( names for my special properties )
385 static OUString m_aPropertyNameForCount
;
386 static OUString m_aPropertyNameForFinalCount
;
387 static OUString m_aPropertyNameForFetchSize
;
388 static OUString m_aPropertyNameForFetchDirection
;
390 long m_nFetchSizePropertyHandle
;
391 long m_nFetchDirectionPropertyHandle
;
395 impl_getRemainedHandle() const;
399 const OUString
& rName
400 , com::sun::star::beans::Property
& rProp
) const;
402 impl_getPos( const OUString
& rName
) const;
405 impl_isMyPropertyName( const OUString
& rName
);
408 CCRS_PropertySetInfo( Reference
<
409 XPropertySetInfo
> xPropertySetInfoOrigin
);
411 virtual ~CCRS_PropertySetInfo();
414 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
)
415 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
416 virtual void SAL_CALL
acquire()
417 throw() SAL_OVERRIDE
;
418 virtual void SAL_CALL
release()
419 throw() SAL_OVERRIDE
;
422 virtual css::uno::Sequence
< sal_Int8
> SAL_CALL
getImplementationId()
423 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
424 virtual css::uno::Sequence
< com::sun::star::uno::Type
> SAL_CALL
getTypes()
425 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
428 virtual Sequence
< com::sun::star::beans::Property
> SAL_CALL
430 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
432 virtual com::sun::star::beans::Property SAL_CALL
433 getPropertyByName( const OUString
& aName
)
434 throw( com::sun::star::beans::UnknownPropertyException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
436 virtual sal_Bool SAL_CALL
437 hasPropertyByName( const OUString
& Name
)
438 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
441 OUString
CCRS_PropertySetInfo::m_aPropertyNameForCount( "RowCount" );
442 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( "IsRowCountFinal" );
443 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( "FetchSize" );
444 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( "FetchDirection" );
446 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
447 Reference
< XPropertySetInfo
> xInfo
)
448 : m_pProperties( NULL
)
449 , m_nFetchSizePropertyHandle( -1 )
450 , m_nFetchDirectionPropertyHandle( -1 )
452 //initialize list of properties:
454 // it is required, that the received xInfo contains the two
455 // properties with names 'm_aPropertyNameForCount' and
456 // 'm_aPropertyNameForFinalCount'
460 Sequence
<Property
> aProps
= xInfo
->getProperties();
461 m_pProperties
= new Sequence
<Property
> ( aProps
);
465 OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
466 m_pProperties
= new Sequence
<Property
>;
469 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
470 sal_Int32 nFetchSize
= impl_getPos( m_aPropertyNameForFetchSize
);
471 sal_Int32 nFetchDirection
= impl_getPos( m_aPropertyNameForFetchDirection
);
472 sal_Int32 nDeleted
= 0;
473 if( nFetchSize
!= -1 )
475 if( nFetchDirection
!= -1 )
478 Sequence
< Property
>* pOrigProps
= new Sequence
<Property
> ( *m_pProperties
);
479 sal_Int32 nOrigProps
= pOrigProps
->getLength();
481 m_pProperties
->realloc( nOrigProps
+ 2 - nDeleted
);//note that nDeleted is <= 2
482 for( sal_Int32 n
= 0, m
= 0; n
< nOrigProps
; n
++, m
++ )
484 if( n
== nFetchSize
|| n
== nFetchDirection
)
487 (*m_pProperties
)[ m
] = (*pOrigProps
)[ n
];
490 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
];
491 rMyProp
.Name
= m_aPropertyNameForFetchSize
;
492 rMyProp
.Type
= cppu::UnoType
<sal_Int32
>::get();
493 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
495 if( nFetchSize
!= -1 )
496 m_nFetchSizePropertyHandle
= (*pOrigProps
)[nFetchSize
].Handle
;
498 m_nFetchSizePropertyHandle
= impl_getRemainedHandle();
500 rMyProp
.Handle
= m_nFetchSizePropertyHandle
;
504 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
+ 1 ];
505 rMyProp
.Name
= m_aPropertyNameForFetchDirection
;
506 rMyProp
.Type
= cppu::UnoType
<sal_Bool
>::get();
507 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
509 if( nFetchDirection
!= -1 )
510 m_nFetchDirectionPropertyHandle
= (*pOrigProps
)[nFetchDirection
].Handle
;
512 m_nFetchDirectionPropertyHandle
= impl_getRemainedHandle();
514 m_nFetchDirectionPropertyHandle
= rMyProp
.Handle
;
519 CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
521 delete m_pProperties
;
525 // XInterface methods.
527 void SAL_CALL
CCRS_PropertySetInfo::acquire()
530 OWeakObject::acquire();
533 void SAL_CALL
CCRS_PropertySetInfo::release()
536 OWeakObject::release();
539 css::uno::Any SAL_CALL
CCRS_PropertySetInfo::queryInterface( const css::uno::Type
& rType
)
540 throw( css::uno::RuntimeException
, std::exception
)
542 css::uno::Any aRet
= cppu::queryInterface( rType
,
543 (static_cast< XTypeProvider
* >(this)),
544 (static_cast< XPropertySetInfo
* >(this))
546 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
549 // XTypeProvider methods.
551 //list all interfaces exclusive baseclasses
552 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
557 // XPropertySetInfo methods.
560 Sequence
< Property
> SAL_CALL CCRS_PropertySetInfo
561 ::getProperties() throw( RuntimeException
, std::exception
)
563 return *m_pProperties
;
567 Property SAL_CALL CCRS_PropertySetInfo
568 ::getPropertyByName( const OUString
& aName
)
569 throw( UnknownPropertyException
, RuntimeException
, std::exception
)
571 if ( aName
.isEmpty() )
572 throw UnknownPropertyException();
575 if ( impl_queryProperty( aName
, aProp
) )
578 throw UnknownPropertyException();
582 sal_Bool SAL_CALL CCRS_PropertySetInfo
583 ::hasPropertyByName( const OUString
& Name
)
584 throw( RuntimeException
, std::exception
)
586 return ( impl_getPos( Name
) != -1 );
593 sal_Int32 SAL_CALL CCRS_PropertySetInfo
594 ::impl_getPos( const OUString
& rName
) const
596 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
598 const Property
& rMyProp
= (*m_pProperties
)[nN
];
599 if( rMyProp
.Name
== rName
)
605 bool SAL_CALL CCRS_PropertySetInfo
606 ::impl_queryProperty( const OUString
& rName
, Property
& rProp
) const
608 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
610 const Property
& rMyProp
= (*m_pProperties
)[nN
];
611 if( rMyProp
.Name
== rName
)
613 rProp
.Name
= rMyProp
.Name
;
614 rProp
.Handle
= rMyProp
.Handle
;
615 rProp
.Type
= rMyProp
.Type
;
616 rProp
.Attributes
= rMyProp
.Attributes
;
625 bool SAL_CALL CCRS_PropertySetInfo
626 ::impl_isMyPropertyName( const OUString
& rPropertyName
)
628 return ( rPropertyName
== m_aPropertyNameForCount
629 || rPropertyName
== m_aPropertyNameForFinalCount
630 || rPropertyName
== m_aPropertyNameForFetchSize
631 || rPropertyName
== m_aPropertyNameForFetchDirection
);
634 sal_Int32 SAL_CALL CCRS_PropertySetInfo
635 ::impl_getRemainedHandle( ) const
637 sal_Int32 nHandle
= 1;
641 OSL_FAIL( "Properties not initialized yet" );
648 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
650 if( nHandle
== (*m_pProperties
)[nN
].Handle
)
663 // class CachedContentResultSet
667 CachedContentResultSet::CachedContentResultSet(
668 const Reference
< XComponentContext
> & rxContext
669 , const Reference
< XResultSet
> & xOrigin
670 , const Reference
< XContentIdentifierMapping
> &
671 xContentIdentifierMapping
)
672 : ContentResultSetWrapper( xOrigin
)
674 , m_xContext( rxContext
)
675 , m_xFetchProvider( NULL
)
676 , m_xFetchProviderForContentAccess( NULL
)
678 , m_xMyPropertySetInfo( NULL
)
679 , m_pMyPropSetInfo( NULL
)
681 , m_xContentIdentifierMapping( xContentIdentifierMapping
)
682 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
683 , m_bAfterLast( false )
684 , m_nLastAppliedPos( 0 )
685 , m_bAfterLastApplied( false )
687 , m_bFinalCount( false )
689 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
)
691 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
)
693 , m_bLastReadWasFromCache( false )
694 , m_bLastCachedReadWasNull( true )
695 , m_aCache( m_xContentIdentifierMapping
)
696 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping
)
697 , m_aCacheContentIdentifier( m_xContentIdentifierMapping
)
698 , m_aCacheContent( m_xContentIdentifierMapping
)
699 , m_bTriedToGetTypeConverter( false )
700 , m_xTypeConverter( NULL
)
702 m_xFetchProvider
= Reference
< XFetchProvider
>( m_xResultSetOrigin
, UNO_QUERY
);
703 OSL_ENSURE( m_xFetchProvider
.is(), "interface XFetchProvider is required" );
705 m_xFetchProviderForContentAccess
= Reference
< XFetchProviderForContentAccess
>( m_xResultSetOrigin
, UNO_QUERY
);
706 OSL_ENSURE( m_xFetchProviderForContentAccess
.is(), "interface XFetchProviderForContentAccess is required" );
711 CachedContentResultSet::~CachedContentResultSet()
714 //do not delete m_pMyPropSetInfo, cause it is hold via reference
721 bool SAL_CALL CachedContentResultSet
722 ::applyPositionToOrigin( sal_Int32 nRow
)
726 impl_EnsureNotDisposed();
730 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
734 ReacquireableGuard
aGuard( m_aMutex
);
735 OSL_ENSURE( nRow
>= 0, "only positive values supported" );
736 if( !m_xResultSetOrigin
.is() )
738 OSL_FAIL( "broadcaster was disposed already" );
741 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
743 sal_Int32 nLastAppliedPos
= m_nLastAppliedPos
;
744 bool bAfterLastApplied
= m_bAfterLastApplied
;
745 bool bAfterLast
= m_bAfterLast
;
746 sal_Int32 nForwardOnly
= m_nForwardOnly
;
750 if( bAfterLastApplied
|| nLastAppliedPos
!= nRow
)
752 if( nForwardOnly
== 1 )
754 if( bAfterLastApplied
|| bAfterLast
|| !nRow
|| nRow
< nLastAppliedPos
)
755 throw SQLException();
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
;
768 return nRow
== m_nLastAppliedPos
;
771 if( !nRow
) //absolute( 0 ) will throw exception
773 m_xResultSetOrigin
->beforeFirst();
776 m_nLastAppliedPos
= 0;
777 m_bAfterLastApplied
= false;
782 //move absolute, if !nLastAppliedPos
783 //because move relative would throw exception
784 if( !nLastAppliedPos
|| bAfterLast
|| bAfterLastApplied
)
786 bool bValid
= m_xResultSetOrigin
->absolute( nRow
);
789 m_nLastAppliedPos
= nRow
;
790 m_bAfterLastApplied
= !bValid
;
795 bool bValid
= m_xResultSetOrigin
->relative( nRow
- nLastAppliedPos
);
798 m_nLastAppliedPos
+= ( nRow
- nLastAppliedPos
);
799 m_bAfterLastApplied
= !bValid
;
803 catch (const SQLException
&)
805 if( !bAfterLastApplied
&& !bAfterLast
&& nRow
> nLastAppliedPos
&& impl_isForwardOnly() )
807 sal_Int32 nN
= nRow
- nLastAppliedPos
;
809 for( nM
= 0; nN
--; nM
++ )
811 if( !m_xResultSetOrigin
->next() )
816 m_nLastAppliedPos
+= nM
;
817 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
823 return nRow
== m_nLastAppliedPos
;
830 //define for fetching data
834 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
835 bool bDirection = !!( \
836 nFetchDirection != FetchDirection::REVERSE ); \
837 FetchResult aResult = \
838 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
839 osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
840 aCache.loadData( aResult ); \
841 sal_Int32 nMax = aCache.getMaxRow(); \
842 sal_Int32 nCurCount = m_nKnownCount; \
843 bool bIsFinalCount = aCache.hasKnownLast(); \
844 bool bCurIsFinalCount = m_bFinalCount; \
846 if( nMax > nCurCount ) \
847 impl_changeRowCount( nCurCount, nMax ); \
848 if( bIsFinalCount && !bCurIsFinalCount ) \
849 impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
851 void SAL_CALL CachedContentResultSet
852 ::impl_fetchData( sal_Int32 nRow
853 , sal_Int32 nFetchSize
, sal_Int32 nFetchDirection
)
854 throw( com::sun::star::uno::RuntimeException
)
856 FETCH_XXX( m_aCache
, m_xFetchProvider
, fetch
);
859 void SAL_CALL CachedContentResultSet
860 ::impl_changeRowCount( sal_Int32 nOld
, sal_Int32 nNew
)
862 OSL_ENSURE( nNew
> nOld
, "RowCount only can grow" );
866 //create PropertyChangeEvent and set value
867 PropertyChangeEvent aEvt
;
869 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
870 aEvt
.Source
= static_cast< XPropertySet
* >( this );
871 aEvt
.Further
= sal_False
;
872 aEvt
.OldValue
<<= nOld
;
873 aEvt
.NewValue
<<= nNew
;
875 m_nKnownCount
= nNew
;
878 //send PropertyChangeEvent to listeners
879 impl_notifyPropertyChangeListeners( aEvt
);
882 void SAL_CALL CachedContentResultSet
883 ::impl_changeIsRowCountFinal( bool bOld
, bool bNew
)
885 OSL_ENSURE( !bOld
&& bNew
, "This change is not allowed for IsRowCountFinal" );
886 if( ! (!bOld
&& bNew
) )
889 //create PropertyChangeEvent and set value
890 PropertyChangeEvent aEvt
;
892 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
893 aEvt
.Source
= static_cast< XPropertySet
* >( this );
894 aEvt
.Further
= sal_False
;
895 aEvt
.OldValue
<<= bOld
;
896 aEvt
.NewValue
<<= bNew
;
898 m_bFinalCount
= bNew
;
901 //send PropertyChangeEvent to listeners
902 impl_notifyPropertyChangeListeners( aEvt
);
905 bool SAL_CALL CachedContentResultSet
906 ::impl_isKnownValidPosition( sal_Int32 nRow
)
908 return m_nKnownCount
&& nRow
909 && nRow
<= m_nKnownCount
;
912 bool SAL_CALL CachedContentResultSet
913 ::impl_isKnownInvalidPosition( sal_Int32 nRow
)
919 return nRow
> m_nKnownCount
;
924 void SAL_CALL CachedContentResultSet
925 ::impl_initPropertySetInfo()
927 ContentResultSetWrapper::impl_initPropertySetInfo();
929 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
930 if( m_pMyPropSetInfo
)
932 m_pMyPropSetInfo
= new CCRS_PropertySetInfo( m_xPropertySetInfo
);
933 m_xMyPropertySetInfo
= m_pMyPropSetInfo
;
934 m_xPropertySetInfo
= m_xMyPropertySetInfo
;
938 // XInterface methods.
939 void SAL_CALL
CachedContentResultSet::acquire()
942 OWeakObject::acquire();
945 void SAL_CALL
CachedContentResultSet::release()
948 OWeakObject::release();
951 Any SAL_CALL CachedContentResultSet
952 ::queryInterface( const Type
& rType
)
953 throw ( RuntimeException
, std::exception
)
955 //list all interfaces inclusive baseclasses of interfaces
957 Any aRet
= ContentResultSetWrapper::queryInterface( rType
);
958 if( aRet
.hasValue() )
961 aRet
= cppu::queryInterface( rType
,
962 static_cast< XTypeProvider
* >( this ),
963 static_cast< XServiceInfo
* >( this ) );
965 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
969 // XTypeProvider methods.
971 //list all interfaces exclusive baseclasses
972 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
977 , XResultSetMetaDataSupplier
980 , XPropertyChangeListener
981 , XVetoableChangeListener
989 // XServiceInfo methods.
992 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet
,
994 "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 ) ) \
1286 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1288 if( !m_xFetchProviderForContentAccess.is() ) \
1290 OSL_FAIL( "broadcaster was disposed already" );\
1291 throw RuntimeException(); \
1294 if( impl_isForwardOnly() ) \
1295 applyPositionToOrigin( nRow ); \
1297 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1299 aGuard.reacquire(); \
1300 if( !m_aCache##XXX.hasRow( nRow ) ) \
1303 applyPositionToOrigin( nRow ); \
1304 TYPE aRet = ContentResultSetWrapper::queryXXX(); \
1305 if( m_xContentIdentifierMapping.is() ) \
1306 return m_xContentIdentifierMapping->map##XXX( aRet );\
1310 return m_aCache##XXX.get##XXX( nRow );
1314 OUString SAL_CALL CachedContentResultSet
1315 ::queryContentIdentifierString()
1316 throw( RuntimeException
, std::exception
)
1318 XCONTENTACCESS_queryXXX( queryContentIdentifierString
, ContentIdentifierString
, OUString
)
1323 Reference
< XContentIdentifier
> SAL_CALL CachedContentResultSet
1324 ::queryContentIdentifier()
1325 throw( RuntimeException
, std::exception
)
1327 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1332 Reference
< XContent
> SAL_CALL CachedContentResultSet
1334 throw( RuntimeException
, std::exception
)
1336 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1340 // XResultSet methods. ( inherited )
1344 sal_Bool SAL_CALL CachedContentResultSet
1346 throw( SQLException
,
1347 RuntimeException
, std::exception
)
1349 impl_EnsureNotDisposed();
1351 ReacquireableGuard
aGuard( m_aMutex
);
1361 m_bAfterLast
= true;
1365 //known valid position
1366 if( impl_isKnownValidPosition( m_nRow
+ 1 ) )
1373 sal_Int32 nRow
= m_nRow
;
1376 bool bValid
= applyPositionToOrigin( nRow
+ 1 );
1380 m_bAfterLast
= !bValid
;
1385 sal_Bool SAL_CALL CachedContentResultSet
1387 throw( SQLException
,
1388 RuntimeException
, std::exception
)
1390 impl_EnsureNotDisposed();
1392 if( impl_isForwardOnly() )
1393 throw SQLException();
1395 ReacquireableGuard
aGuard( m_aMutex
);
1397 if( !m_bAfterLast
&& !m_nRow
)
1400 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1403 m_bAfterLast
= false;
1406 //known valid position ?:
1407 if( impl_isKnownValidPosition( m_nRow
- 1 ) )
1410 m_bAfterLast
= false;
1414 sal_Int32 nRow
= m_nRow
;
1417 bool bValid
= applyPositionToOrigin( nRow
- 1 );
1421 m_bAfterLast
= false;
1426 sal_Bool SAL_CALL CachedContentResultSet
1427 ::absolute( sal_Int32 row
)
1428 throw( SQLException
,
1429 RuntimeException
, std::exception
)
1431 impl_EnsureNotDisposed();
1434 throw SQLException();
1436 if( impl_isForwardOnly() )
1437 throw SQLException();
1439 ReacquireableGuard
aGuard( m_aMutex
);
1441 if( !m_xResultSetOrigin
.is() )
1443 OSL_FAIL( "broadcaster was disposed already" );
1450 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1458 m_bAfterLast
= false;
1461 //unknown final count:
1464 // Solaris has problems catching or propagating derived exceptions
1465 // when only the base class is known, so make ResultSetException
1466 // (derived from SQLException) known here:
1470 bValid
= m_xResultSetOrigin
->absolute( row
);
1472 catch (const ResultSetException
&)
1480 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1483 m_nLastAppliedPos
= nNewRow
;
1485 m_bAfterLastApplied
= m_bAfterLast
= false;
1490 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1493 m_nLastAppliedPos
= nCurRow
;
1495 m_bAfterLast
= false;
1496 return nCurRow
!= 0;
1501 if( row
> m_nKnownCount
)
1503 m_nRow
= m_nKnownCount
+ 1;
1504 m_bAfterLast
= true;
1508 m_bAfterLast
= false;
1511 //unknown new position:
1514 bool bValid
= m_xResultSetOrigin
->absolute( row
);
1519 sal_Int32 nNewRow
= row
;
1520 if( nNewRow
> m_nKnownCount
)
1522 nNewRow
= m_nKnownCount
+ 1;
1523 m_bAfterLastApplied
= m_bAfterLast
= true;
1526 m_bAfterLastApplied
= m_bAfterLast
= false;
1528 m_nLastAppliedPos
= nNewRow
;
1534 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1535 bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1538 m_nLastAppliedPos
= nCurRow
;
1540 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1541 return nCurRow
&& !bIsAfterLast
;
1545 sal_Bool SAL_CALL CachedContentResultSet
1546 ::relative( sal_Int32 rows
)
1547 throw( SQLException
,
1548 RuntimeException
, std::exception
)
1550 impl_EnsureNotDisposed();
1552 if( impl_isForwardOnly() )
1553 throw SQLException();
1555 ReacquireableGuard
aGuard( m_aMutex
);
1556 if( m_bAfterLast
|| impl_isKnownInvalidPosition( m_nRow
) )
1557 throw SQLException();
1562 sal_Int32 nNewRow
= m_nRow
+ rows
;
1566 if( impl_isKnownValidPosition( nNewRow
) )
1569 m_bAfterLast
= false;
1574 //known invalid new position:
1577 m_bAfterLast
= false;
1581 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1583 m_bAfterLast
= true;
1584 m_nRow
= m_nKnownCount
+ 1;
1587 //unknown new position:
1589 bool bValid
= applyPositionToOrigin( nNewRow
);
1593 m_bAfterLast
= !bValid
&& nNewRow
> 0;
1600 sal_Bool SAL_CALL CachedContentResultSet
1602 throw( SQLException
,
1603 RuntimeException
, std::exception
)
1605 impl_EnsureNotDisposed();
1607 if( impl_isForwardOnly() )
1608 throw SQLException();
1610 ReacquireableGuard
aGuard( m_aMutex
);
1611 if( impl_isKnownValidPosition( 1 ) )
1614 m_bAfterLast
= false;
1617 if( impl_isKnownInvalidPosition( 1 ) )
1620 m_bAfterLast
= false;
1626 bool bValid
= applyPositionToOrigin( 1 );
1630 m_bAfterLast
= false;
1635 sal_Bool SAL_CALL CachedContentResultSet
1637 throw( SQLException
,
1638 RuntimeException
, std::exception
)
1640 impl_EnsureNotDisposed();
1642 if( impl_isForwardOnly() )
1643 throw SQLException();
1645 ReacquireableGuard
aGuard( m_aMutex
);
1648 m_nRow
= m_nKnownCount
;
1649 m_bAfterLast
= false;
1650 return m_nKnownCount
!= 0;
1653 if( !m_xResultSetOrigin
.is() )
1655 OSL_FAIL( "broadcaster was disposed already" );
1660 bool bValid
= m_xResultSetOrigin
->last();
1663 m_bAfterLastApplied
= m_bAfterLast
= false;
1666 m_nLastAppliedPos
= m_nKnownCount
;
1667 m_nRow
= m_nKnownCount
;
1672 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1675 m_nLastAppliedPos
= nCurRow
;
1677 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1678 m_nKnownCount
= nCurRow
;
1679 m_bFinalCount
= true;
1680 return nCurRow
!= 0;
1684 void SAL_CALL CachedContentResultSet
1686 throw( SQLException
,
1687 RuntimeException
, std::exception
)
1689 impl_EnsureNotDisposed();
1691 if( impl_isForwardOnly() )
1692 throw SQLException();
1694 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1696 m_bAfterLast
= false;
1700 void SAL_CALL CachedContentResultSet
1702 throw( SQLException
,
1703 RuntimeException
, std::exception
)
1705 impl_EnsureNotDisposed();
1707 if( impl_isForwardOnly() )
1708 throw SQLException();
1710 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1712 m_bAfterLast
= true;
1716 sal_Bool SAL_CALL CachedContentResultSet
1718 throw( SQLException
,
1719 RuntimeException
, std::exception
)
1721 impl_EnsureNotDisposed();
1723 ReacquireableGuard
aGuard( m_aMutex
);
1727 return m_bAfterLast
;
1731 if( !m_xResultSetOrigin
.is() )
1733 OSL_FAIL( "broadcaster was disposed already" );
1738 //find out whethter the original resultset contains rows or not
1739 m_xResultSetOrigin
->afterLast();
1742 m_bAfterLastApplied
= true;
1745 return m_xResultSetOrigin
->isAfterLast();
1749 sal_Bool SAL_CALL CachedContentResultSet
1751 throw( SQLException
,
1752 RuntimeException
, std::exception
)
1754 impl_EnsureNotDisposed();
1756 ReacquireableGuard
aGuard( m_aMutex
);
1766 if( !m_xResultSetOrigin
.is() )
1768 OSL_FAIL( "broadcaster was disposed already" );
1773 //find out whethter the original resultset contains rows or not
1774 m_xResultSetOrigin
->beforeFirst();
1777 m_bAfterLastApplied
= false;
1778 m_nLastAppliedPos
= 0;
1781 return m_xResultSetOrigin
->isBeforeFirst();
1785 sal_Bool SAL_CALL CachedContentResultSet
1787 throw( SQLException
,
1788 RuntimeException
, std::exception
)
1790 impl_EnsureNotDisposed();
1793 Reference
< XResultSet
> xResultSetOrigin
;
1796 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1807 xResultSetOrigin
= m_xResultSetOrigin
;
1810 //need to ask origin
1812 if( applyPositionToOrigin( nRow
) )
1813 return xResultSetOrigin
->isFirst();
1820 sal_Bool SAL_CALL CachedContentResultSet
1822 throw( SQLException
,
1823 RuntimeException
, std::exception
)
1825 impl_EnsureNotDisposed();
1828 Reference
< XResultSet
> xResultSetOrigin
;
1830 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1833 if( m_nRow
< m_nKnownCount
)
1836 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1839 xResultSetOrigin
= m_xResultSetOrigin
;
1842 //need to ask origin
1844 if( applyPositionToOrigin( nRow
) )
1845 return xResultSetOrigin
->isLast();
1853 sal_Int32 SAL_CALL CachedContentResultSet
1855 throw( SQLException
,
1856 RuntimeException
, std::exception
)
1858 impl_EnsureNotDisposed();
1860 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1867 void SAL_CALL CachedContentResultSet
1869 throw( SQLException
,
1870 RuntimeException
, std::exception
)
1872 impl_EnsureNotDisposed();
1874 //the ContentResultSet is static and will not change
1875 //therefore we don't need to reload anything
1879 sal_Bool SAL_CALL CachedContentResultSet
1881 throw( SQLException
,
1882 RuntimeException
, std::exception
)
1884 impl_EnsureNotDisposed();
1886 //the ContentResultSet is static and will not change
1890 sal_Bool SAL_CALL CachedContentResultSet
1892 throw( SQLException
,
1893 RuntimeException
, std::exception
)
1895 impl_EnsureNotDisposed();
1897 //the ContentResultSet is static and will not change
1902 sal_Bool SAL_CALL CachedContentResultSet
1904 throw( SQLException
,
1905 RuntimeException
, std::exception
)
1907 impl_EnsureNotDisposed();
1909 //the ContentResultSet is static and will not change
1914 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1916 throw( SQLException
,
1917 RuntimeException
, std::exception
)
1919 impl_EnsureNotDisposed();
1920 //@todo ?return anything
1921 return Reference
< XInterface
>();
1925 // XRow methods. ( inherited )
1929 sal_Bool SAL_CALL CachedContentResultSet
1931 throw( SQLException
,
1932 RuntimeException
, std::exception
)
1934 impl_EnsureNotDisposed();
1935 impl_init_xRowOrigin();
1937 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1938 if( m_bLastReadWasFromCache
)
1939 return m_bLastCachedReadWasNull
;
1940 if( !m_xRowOrigin
.is() )
1942 OSL_FAIL( "broadcaster was disposed already" );
1946 return m_xRowOrigin
->wasNull();
1950 OUString SAL_CALL CachedContentResultSet
1951 ::getString( sal_Int32 columnIndex
)
1952 throw( SQLException
,
1953 RuntimeException
, std::exception
)
1955 return rowOriginGet
<OUString
>(&css::sdbc::XRow::getString
, columnIndex
);
1959 sal_Bool SAL_CALL CachedContentResultSet
1960 ::getBoolean( sal_Int32 columnIndex
)
1961 throw( SQLException
,
1962 RuntimeException
, std::exception
)
1964 return rowOriginGet
<sal_Bool
>(&css::sdbc::XRow::getBoolean
, columnIndex
);
1968 sal_Int8 SAL_CALL CachedContentResultSet
1969 ::getByte( sal_Int32 columnIndex
)
1970 throw( SQLException
,
1971 RuntimeException
, std::exception
)
1973 return rowOriginGet
<sal_Int8
>(&css::sdbc::XRow::getByte
, columnIndex
);
1977 sal_Int16 SAL_CALL CachedContentResultSet
1978 ::getShort( sal_Int32 columnIndex
)
1979 throw( SQLException
,
1980 RuntimeException
, std::exception
)
1982 return rowOriginGet
<sal_Int16
>(&css::sdbc::XRow::getShort
, columnIndex
);
1986 sal_Int32 SAL_CALL CachedContentResultSet
1987 ::getInt( sal_Int32 columnIndex
)
1988 throw( SQLException
,
1989 RuntimeException
, std::exception
)
1991 return rowOriginGet
<sal_Int32
>(&css::sdbc::XRow::getInt
, columnIndex
);
1995 sal_Int64 SAL_CALL CachedContentResultSet
1996 ::getLong( sal_Int32 columnIndex
)
1997 throw( SQLException
,
1998 RuntimeException
, std::exception
)
2000 return rowOriginGet
<sal_Int64
>(&css::sdbc::XRow::getLong
, columnIndex
);
2004 float SAL_CALL CachedContentResultSet
2005 ::getFloat( sal_Int32 columnIndex
)
2006 throw( SQLException
,
2007 RuntimeException
, std::exception
)
2009 return rowOriginGet
<float>(&css::sdbc::XRow::getFloat
, columnIndex
);
2013 double SAL_CALL CachedContentResultSet
2014 ::getDouble( sal_Int32 columnIndex
)
2015 throw( SQLException
,
2016 RuntimeException
, std::exception
)
2018 return rowOriginGet
<double>(&css::sdbc::XRow::getDouble
, columnIndex
);
2022 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
2023 ::getBytes( sal_Int32 columnIndex
)
2024 throw( SQLException
,
2025 RuntimeException
, std::exception
)
2027 return rowOriginGet
< css::uno::Sequence
<sal_Int8
> >(
2028 &css::sdbc::XRow::getBytes
, columnIndex
);
2032 Date SAL_CALL CachedContentResultSet
2033 ::getDate( sal_Int32 columnIndex
)
2034 throw( SQLException
,
2035 RuntimeException
, std::exception
)
2037 return rowOriginGet
<css::util::Date
>(
2038 &css::sdbc::XRow::getDate
, columnIndex
);
2042 Time SAL_CALL CachedContentResultSet
2043 ::getTime( sal_Int32 columnIndex
)
2044 throw( SQLException
,
2045 RuntimeException
, std::exception
)
2047 return rowOriginGet
<css::util::Time
>(
2048 &css::sdbc::XRow::getTime
, columnIndex
);
2052 DateTime SAL_CALL CachedContentResultSet
2053 ::getTimestamp( sal_Int32 columnIndex
)
2054 throw( SQLException
,
2055 RuntimeException
, std::exception
)
2057 return rowOriginGet
<css::util::DateTime
>(
2058 &css::sdbc::XRow::getTimestamp
, columnIndex
);
2062 Reference
< com::sun::star::io::XInputStream
>
2063 SAL_CALL CachedContentResultSet
2064 ::getBinaryStream( sal_Int32 columnIndex
)
2065 throw( SQLException
,
2066 RuntimeException
, std::exception
)
2068 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
2069 &css::sdbc::XRow::getBinaryStream
, columnIndex
);
2073 Reference
< com::sun::star::io::XInputStream
>
2074 SAL_CALL CachedContentResultSet
2075 ::getCharacterStream( sal_Int32 columnIndex
)
2076 throw( SQLException
,
2077 RuntimeException
, std::exception
)
2079 return rowOriginGet
< css::uno::Reference
<css::io::XInputStream
> >(
2080 &css::sdbc::XRow::getCharacterStream
, columnIndex
);
2084 Any SAL_CALL CachedContentResultSet
2085 ::getObject( sal_Int32 columnIndex
,
2087 com::sun::star::container::XNameAccess
>& typeMap
)
2088 throw( SQLException
,
2089 RuntimeException
, std::exception
)
2091 //if you change this function please pay attention to
2092 //function template rowOriginGet, where this is similar implemented
2094 ReacquireableGuard
aGuard( m_aMutex
);
2095 sal_Int32 nRow
= m_nRow
;
2096 sal_Int32 nFetchSize
= m_nFetchSize
;
2097 sal_Int32 nFetchDirection
= m_nFetchDirection
;
2098 if( !m_aCache
.hasRow( nRow
) )
2100 if( !m_aCache
.hasCausedException( nRow
) )
2102 if( !m_xFetchProvider
.is() )
2104 OSL_FAIL( "broadcaster was disposed already" );
2109 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
2112 if( !m_aCache
.hasRow( nRow
) )
2114 m_bLastReadWasFromCache
= false;
2116 applyPositionToOrigin( nRow
);
2117 impl_init_xRowOrigin();
2118 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
2121 //@todo: pay attention to typeMap
2122 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
2124 m_bLastReadWasFromCache
= true;
2125 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
2130 Reference
< XRef
> SAL_CALL CachedContentResultSet
2131 ::getRef( sal_Int32 columnIndex
)
2132 throw( SQLException
,
2133 RuntimeException
, std::exception
)
2135 return rowOriginGet
< css::uno::Reference
<css::sdbc::XRef
> >(
2136 &css::sdbc::XRow::getRef
, columnIndex
);
2140 Reference
< XBlob
> SAL_CALL CachedContentResultSet
2141 ::getBlob( sal_Int32 columnIndex
)
2142 throw( SQLException
,
2143 RuntimeException
, std::exception
)
2145 return rowOriginGet
< css::uno::Reference
<css::sdbc::XBlob
> >(
2146 &css::sdbc::XRow::getBlob
, columnIndex
);
2150 Reference
< XClob
> SAL_CALL CachedContentResultSet
2151 ::getClob( sal_Int32 columnIndex
)
2152 throw( SQLException
,
2153 RuntimeException
, std::exception
)
2155 return rowOriginGet
< css::uno::Reference
<css::sdbc::XClob
> >(
2156 &css::sdbc::XRow::getClob
, columnIndex
);
2160 Reference
< XArray
> SAL_CALL CachedContentResultSet
2161 ::getArray( sal_Int32 columnIndex
)
2162 throw( SQLException
,
2163 RuntimeException
, std::exception
)
2165 return rowOriginGet
< css::uno::Reference
<css::sdbc::XArray
> >(
2166 &css::sdbc::XRow::getArray
, columnIndex
);
2170 // Type Converter Support
2173 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter()
2175 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2177 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
2179 m_bTriedToGetTypeConverter
= true;
2180 m_xTypeConverter
= Reference
< XTypeConverter
>( Converter::create(m_xContext
) );
2182 OSL_ENSURE( m_xTypeConverter
.is(),
2183 "PropertyValueSet::getTypeConverter() - "
2184 "Service 'com.sun.star.script.Converter' n/a!" );
2186 return m_xTypeConverter
;
2191 // class CachedContentResultSetFactory
2195 CachedContentResultSetFactory::CachedContentResultSetFactory(
2196 const Reference
< XComponentContext
> & rxContext
)
2198 m_xContext
= rxContext
;
2201 CachedContentResultSetFactory::~CachedContentResultSetFactory()
2206 // CachedContentResultSetFactory XInterface methods.
2207 void SAL_CALL
CachedContentResultSetFactory::acquire()
2210 OWeakObject::acquire();
2213 void SAL_CALL
CachedContentResultSetFactory::release()
2216 OWeakObject::release();
2219 css::uno::Any SAL_CALL
CachedContentResultSetFactory::queryInterface( const css::uno::Type
& rType
)
2220 throw( css::uno::RuntimeException
, std::exception
)
2222 css::uno::Any aRet
= cppu::queryInterface( rType
,
2223 (static_cast< XTypeProvider
* >(this)),
2224 (static_cast< XServiceInfo
* >(this)),
2225 (static_cast< XCachedContentResultSetFactory
* >(this))
2227 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
2230 // CachedContentResultSetFactory XTypeProvider methods.
2233 XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory
,
2236 XCachedContentResultSetFactory
);
2239 // CachedContentResultSetFactory XServiceInfo methods.
2242 XSERVICEINFO_IMPL_1_CTX( CachedContentResultSetFactory
,
2243 OUString( "com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
2244 OUString( CACHED_CONTENT_RESULTSET_FACTORY_NAME
) );
2247 // Service factory implementation.
2250 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory
);
2253 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2257 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2258 ::createCachedContentResultSet(
2259 const Reference
< XResultSet
> & xSource
,
2260 const Reference
< XContentIdentifierMapping
> & xMapping
)
2261 throw( com::sun::star::uno::RuntimeException
, std::exception
)
2263 Reference
< XResultSet
> xRet
;
2264 xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */