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 //--------------------------------------------------------------------------
46 //--------------------------------------------------------------------------
47 //define for getXXX methods of interface XRow
48 //--------------------------------------------------------------------------
49 //--------------------------------------------------------------------------
51 //if you change this macro please pay attention to
52 //function ::getObject, where this is similar implemented
54 #define XROW_GETXXX( getXXX, Type ) \
55 impl_EnsureNotDisposed(); \
56 ReacquireableGuard aGuard( m_aMutex ); \
57 sal_Int32 nRow = m_nRow; \
58 sal_Int32 nFetchSize = m_nFetchSize; \
59 sal_Int32 nFetchDirection = m_nFetchDirection; \
60 if( !m_aCache.hasRow( nRow ) ) \
62 if( !m_aCache.hasCausedException( nRow ) ) \
64 if( !m_xFetchProvider.is() ) \
66 OSL_FAIL( "broadcaster was disposed already" ); \
67 throw SQLException(); \
70 if( impl_isForwardOnly() ) \
71 applyPositionToOrigin( nRow ); \
73 impl_fetchData( nRow, nFetchSize, nFetchDirection ); \
76 if( !m_aCache.hasRow( nRow ) ) \
78 m_bLastReadWasFromCache = sal_False; \
80 applyPositionToOrigin( nRow ); \
81 impl_init_xRowOrigin(); \
82 return m_xRowOrigin->getXXX( columnIndex ); \
85 const Any& rValue = m_aCache.getAny( nRow, columnIndex );\
87 m_bLastReadWasFromCache = sal_True; \
88 m_bLastCachedReadWasNull = !( rValue >>= aRet ); \
89 /* Last chance. Try type converter service... */ \
90 if ( m_bLastCachedReadWasNull && rValue.hasValue() ) \
92 Reference< XTypeConverter > xConverter \
93 = getTypeConverter(); \
94 if ( xConverter.is() ) \
98 Any aConvAny = xConverter->convertTo( \
100 getCppuType( static_cast< \
101 const Type * >( 0 ) ) ); \
102 m_bLastCachedReadWasNull = !( aConvAny >>= aRet ); \
104 catch (const IllegalArgumentException&) \
107 catch (const CannotConvertException&) \
114 //--------------------------------------------------------------------------
115 //--------------------------------------------------------------------------
116 // CCRS_Cache methoeds.
117 //--------------------------------------------------------------------------
118 //--------------------------------------------------------------------------
120 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
121 const Reference
< XContentIdentifierMapping
> & xMapping
)
123 , m_xContentIdentifierMapping( xMapping
)
124 , m_pMappedReminder( NULL
)
128 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
133 void SAL_CALL
CachedContentResultSet::CCRS_Cache
141 clearMappedReminder();
144 void SAL_CALL
CachedContentResultSet::CCRS_Cache
145 ::loadData( const FetchResult
& rResult
)
148 m_pResult
= new FetchResult( rResult
);
151 sal_Bool SAL_CALL
CachedContentResultSet::CCRS_Cache
152 ::hasRow( sal_Int32 row
)
156 long nStart
= m_pResult
->StartIndex
;
158 if( m_pResult
->Orientation
)
159 nEnd
+= m_pResult
->Rows
.getLength() - 1;
161 nStart
-= m_pResult
->Rows
.getLength() + 1;
163 return nStart
<= row
&& row
<= nEnd
;
166 sal_Int32 SAL_CALL
CachedContentResultSet::CCRS_Cache
171 long nEnd
= m_pResult
->StartIndex
;
172 if( m_pResult
->Orientation
)
173 return nEnd
+= m_pResult
->Rows
.getLength() - 1;
178 sal_Bool SAL_CALL
CachedContentResultSet::CCRS_Cache
184 if( ( m_pResult
->FetchError
& FetchError::ENDOFDATA
)
185 && m_pResult
->Orientation
186 && m_pResult
->Rows
.getLength() )
192 sal_Bool SAL_CALL
CachedContentResultSet::CCRS_Cache
193 ::hasCausedException( sal_Int32 nRow
)
197 if( !( m_pResult
->FetchError
& FetchError::EXCEPTION
) )
200 long nEnd
= m_pResult
->StartIndex
;
201 if( m_pResult
->Orientation
)
202 nEnd
+= m_pResult
->Rows
.getLength();
204 return nRow
== nEnd
+1;
207 Any
& SAL_CALL
CachedContentResultSet::CCRS_Cache
208 ::getRowAny( sal_Int32 nRow
)
213 throw SQLException();
215 throw SQLException();
216 if( !hasRow( nRow
) )
217 throw SQLException();
219 long nDiff
= nRow
- m_pResult
->StartIndex
;
223 return (m_pResult
->Rows
)[nDiff
];
226 void SAL_CALL
CachedContentResultSet::CCRS_Cache
227 ::remindMapped( sal_Int32 nRow
)
229 //remind that this row was mapped
232 long nDiff
= nRow
- m_pResult
->StartIndex
;
235 Sequence
< sal_Bool
>* pMappedReminder
= getMappedReminder();
236 if( nDiff
< pMappedReminder
->getLength() )
237 (*pMappedReminder
)[nDiff
] = sal_True
;
240 sal_Bool SAL_CALL
CachedContentResultSet::CCRS_Cache
241 ::isRowMapped( sal_Int32 nRow
)
243 if( !m_pMappedReminder
|| !m_pResult
)
245 long nDiff
= nRow
- m_pResult
->StartIndex
;
248 if( nDiff
< m_pMappedReminder
->getLength() )
249 return (*m_pMappedReminder
)[nDiff
];
253 void SAL_CALL
CachedContentResultSet::CCRS_Cache
254 ::clearMappedReminder()
256 delete m_pMappedReminder
;
257 m_pMappedReminder
= NULL
;
260 Sequence
< sal_Bool
>* SAL_CALL
CachedContentResultSet::CCRS_Cache
261 ::getMappedReminder()
263 if( !m_pMappedReminder
)
265 sal_Int32 nCount
= m_pResult
->Rows
.getLength();
266 m_pMappedReminder
= new Sequence
< sal_Bool
>( nCount
);
267 for( ;nCount
; nCount
-- )
268 (*m_pMappedReminder
)[nCount
] = sal_False
;
270 return m_pMappedReminder
;
273 const Any
& SAL_CALL
CachedContentResultSet::CCRS_Cache
274 ::getAny( sal_Int32 nRow
, sal_Int32 nColumnIndex
)
279 throw SQLException();
280 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
282 Any
& rRow
= getRowAny( nRow
);
283 Sequence
< Any
> aValue
;
285 if( m_xContentIdentifierMapping
->mapRow( aValue
) )
288 remindMapped( nRow
);
291 m_xContentIdentifierMapping
.clear();
293 const Sequence
< Any
>& rRow
=
294 (* reinterpret_cast< const Sequence
< Any
> * >
295 (getRowAny( nRow
).getValue() ));
297 if( nColumnIndex
> rRow
.getLength() )
298 throw SQLException();
299 return rRow
[nColumnIndex
-1];
302 const OUString
& SAL_CALL
CachedContentResultSet::CCRS_Cache
303 ::getContentIdentifierString( sal_Int32 nRow
)
304 throw( com::sun::star::uno::RuntimeException
)
308 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
310 Any
& rRow
= getRowAny( nRow
);
313 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifierString( aValue
);
314 remindMapped( nRow
);
316 return (* reinterpret_cast< const OUString
* >
317 (getRowAny( nRow
).getValue() ));
319 catch(const SQLException
&)
321 throw RuntimeException();
325 const Reference
< XContentIdentifier
>& SAL_CALL
CachedContentResultSet::CCRS_Cache
326 ::getContentIdentifier( sal_Int32 nRow
)
327 throw( com::sun::star::uno::RuntimeException
)
331 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
333 Any
& rRow
= getRowAny( nRow
);
334 Reference
< XContentIdentifier
> aValue
;
336 rRow
<<= m_xContentIdentifierMapping
->mapContentIdentifier( aValue
);
337 remindMapped( nRow
);
339 return (* reinterpret_cast< const Reference
< XContentIdentifier
> * >
340 (getRowAny( nRow
).getValue() ));
342 catch(const SQLException
&)
344 throw RuntimeException();
348 const Reference
< XContent
>& SAL_CALL
CachedContentResultSet::CCRS_Cache
349 ::getContent( sal_Int32 nRow
)
350 throw( com::sun::star::uno::RuntimeException
)
354 if( m_xContentIdentifierMapping
.is() && !isRowMapped( nRow
) )
356 Any
& rRow
= getRowAny( nRow
);
357 Reference
< XContent
> aValue
;
359 rRow
<<= m_xContentIdentifierMapping
->mapContent( aValue
);
360 remindMapped( nRow
);
362 return (* reinterpret_cast< const Reference
< XContent
> * >
363 (getRowAny( nRow
).getValue() ));
365 catch (const SQLException
&)
367 throw RuntimeException();
371 //--------------------------------------------------------------------------
372 //--------------------------------------------------------------------------
373 // class CCRS_PropertySetInfo
374 //--------------------------------------------------------------------------
375 //--------------------------------------------------------------------------
377 class CCRS_PropertySetInfo
:
378 public cppu::OWeakObject
,
379 public com::sun::star::lang::XTypeProvider
,
380 public com::sun::star::beans::XPropertySetInfo
382 friend class CachedContentResultSet
;
385 Sequence
< com::sun::star::beans::Property
>*
388 //some helping variables ( names for my special properties )
389 static OUString m_aPropertyNameForCount
;
390 static OUString m_aPropertyNameForFinalCount
;
391 static OUString m_aPropertyNameForFetchSize
;
392 static OUString m_aPropertyNameForFetchDirection
;
394 long m_nFetchSizePropertyHandle
;
395 long m_nFetchDirectionPropertyHandle
;
399 impl_getRemainedHandle() const;
403 const OUString
& rName
404 , com::sun::star::beans::Property
& rProp
) const;
406 impl_getPos( const OUString
& rName
) const;
408 static sal_Bool SAL_CALL
409 impl_isMyPropertyName( const OUString
& rName
);
412 CCRS_PropertySetInfo( Reference
<
413 XPropertySetInfo
> xPropertySetInfoOrigin
);
415 virtual ~CCRS_PropertySetInfo();
424 virtual Sequence
< com::sun::star::beans::Property
> SAL_CALL
426 throw( RuntimeException
);
428 virtual com::sun::star::beans::Property SAL_CALL
429 getPropertyByName( const OUString
& aName
)
430 throw( com::sun::star::beans::UnknownPropertyException
, RuntimeException
);
432 virtual sal_Bool SAL_CALL
433 hasPropertyByName( const OUString
& Name
)
434 throw( RuntimeException
);
437 OUString
CCRS_PropertySetInfo::m_aPropertyNameForCount( "RowCount" );
438 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( "IsRowCountFinal" );
439 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( "FetchSize" );
440 OUString
CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( "FetchDirection" );
442 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
443 Reference
< XPropertySetInfo
> xInfo
)
444 : m_pProperties( NULL
)
445 , m_nFetchSizePropertyHandle( -1 )
446 , m_nFetchDirectionPropertyHandle( -1 )
448 //initialize list of properties:
450 // it is required, that the received xInfo contains the two
451 // properties with names 'm_aPropertyNameForCount' and
452 // 'm_aPropertyNameForFinalCount'
456 Sequence
<Property
> aProps
= xInfo
->getProperties();
457 m_pProperties
= new Sequence
<Property
> ( aProps
);
461 OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
462 m_pProperties
= new Sequence
<Property
>;
465 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
466 sal_Int32 nFetchSize
= impl_getPos( m_aPropertyNameForFetchSize
);
467 sal_Int32 nFetchDirection
= impl_getPos( m_aPropertyNameForFetchDirection
);
468 sal_Int32 nDeleted
= 0;
469 if( nFetchSize
!= -1 )
471 if( nFetchDirection
!= -1 )
474 Sequence
< Property
>* pOrigProps
= new Sequence
<Property
> ( *m_pProperties
);
475 sal_Int32 nOrigProps
= pOrigProps
->getLength();
477 m_pProperties
->realloc( nOrigProps
+ 2 - nDeleted
);//note that nDeleted is <= 2
478 for( sal_Int32 n
= 0, m
= 0; n
< nOrigProps
; n
++, m
++ )
480 if( n
== nFetchSize
|| n
== nFetchDirection
)
483 (*m_pProperties
)[ m
] = (*pOrigProps
)[ n
];
486 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
];
487 rMyProp
.Name
= m_aPropertyNameForFetchSize
;
488 rMyProp
.Type
= getCppuType( static_cast< const sal_Int32
* >( 0 ) );
489 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
491 if( nFetchSize
!= -1 )
492 m_nFetchSizePropertyHandle
= (*pOrigProps
)[nFetchSize
].Handle
;
494 m_nFetchSizePropertyHandle
= impl_getRemainedHandle();
496 rMyProp
.Handle
= m_nFetchSizePropertyHandle
;
500 Property
& rMyProp
= (*m_pProperties
)[ nOrigProps
- nDeleted
+ 1 ];
501 rMyProp
.Name
= m_aPropertyNameForFetchDirection
;
502 rMyProp
.Type
= getCppuType( static_cast< const sal_Bool
* >( 0 ) );
503 rMyProp
.Attributes
= PropertyAttribute::BOUND
| PropertyAttribute::MAYBEDEFAULT
;
505 if( nFetchDirection
!= -1 )
506 m_nFetchDirectionPropertyHandle
= (*pOrigProps
)[nFetchDirection
].Handle
;
508 m_nFetchDirectionPropertyHandle
= impl_getRemainedHandle();
510 m_nFetchDirectionPropertyHandle
= rMyProp
.Handle
;
515 CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
517 delete m_pProperties
;
520 //--------------------------------------------------------------------------
521 // XInterface methods.
522 //--------------------------------------------------------------------------
523 //list all interfaces inclusive baseclasses of interfaces
524 XINTERFACE_IMPL_2( CCRS_PropertySetInfo
529 //--------------------------------------------------------------------------
530 // XTypeProvider methods.
531 //--------------------------------------------------------------------------
532 //list all interfaces exclusive baseclasses
533 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
537 //--------------------------------------------------------------------------
538 // XPropertySetInfo methods.
539 //--------------------------------------------------------------------------
541 Sequence
< Property
> SAL_CALL CCRS_PropertySetInfo
542 ::getProperties() throw( RuntimeException
)
544 return *m_pProperties
;
548 Property SAL_CALL CCRS_PropertySetInfo
549 ::getPropertyByName( const OUString
& aName
)
550 throw( UnknownPropertyException
, RuntimeException
)
552 if ( aName
.isEmpty() )
553 throw UnknownPropertyException();
556 if ( impl_queryProperty( aName
, aProp
) )
559 throw UnknownPropertyException();
563 sal_Bool SAL_CALL CCRS_PropertySetInfo
564 ::hasPropertyByName( const OUString
& Name
)
565 throw( RuntimeException
)
567 return ( impl_getPos( Name
) != -1 );
570 //--------------------------------------------------------------------------
572 //--------------------------------------------------------------------------
574 sal_Int32 SAL_CALL CCRS_PropertySetInfo
575 ::impl_getPos( const OUString
& rName
) const
577 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
579 const Property
& rMyProp
= (*m_pProperties
)[nN
];
580 if( rMyProp
.Name
== rName
)
586 sal_Bool SAL_CALL CCRS_PropertySetInfo
587 ::impl_queryProperty( const OUString
& rName
, Property
& rProp
) const
589 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
591 const Property
& rMyProp
= (*m_pProperties
)[nN
];
592 if( rMyProp
.Name
== rName
)
594 rProp
.Name
= rMyProp
.Name
;
595 rProp
.Handle
= rMyProp
.Handle
;
596 rProp
.Type
= rMyProp
.Type
;
597 rProp
.Attributes
= rMyProp
.Attributes
;
606 sal_Bool SAL_CALL CCRS_PropertySetInfo
607 ::impl_isMyPropertyName( const OUString
& rPropertyName
)
609 return ( rPropertyName
== m_aPropertyNameForCount
610 || rPropertyName
== m_aPropertyNameForFinalCount
611 || rPropertyName
== m_aPropertyNameForFetchSize
612 || rPropertyName
== m_aPropertyNameForFetchDirection
);
615 sal_Int32 SAL_CALL CCRS_PropertySetInfo
616 ::impl_getRemainedHandle( ) const
618 sal_Int32 nHandle
= 1;
622 OSL_FAIL( "Properties not initialized yet" );
625 sal_Bool bFound
= sal_True
;
629 for( sal_Int32 nN
= m_pProperties
->getLength(); nN
--; )
631 if( nHandle
== (*m_pProperties
)[nN
].Handle
)
642 //--------------------------------------------------------------------------
643 //--------------------------------------------------------------------------
644 // class CachedContentResultSet
645 //--------------------------------------------------------------------------
646 //--------------------------------------------------------------------------
648 CachedContentResultSet::CachedContentResultSet(
649 const Reference
< XComponentContext
> & rxContext
650 , const Reference
< XResultSet
> & xOrigin
651 , const Reference
< XContentIdentifierMapping
> &
652 xContentIdentifierMapping
)
653 : ContentResultSetWrapper( xOrigin
)
655 , m_xContext( rxContext
)
656 , m_xFetchProvider( NULL
)
657 , m_xFetchProviderForContentAccess( NULL
)
659 , m_xMyPropertySetInfo( NULL
)
660 , m_pMyPropSetInfo( NULL
)
662 , m_xContentIdentifierMapping( xContentIdentifierMapping
)
663 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
664 , m_bAfterLast( sal_False
)
665 , m_nLastAppliedPos( 0 )
666 , m_bAfterLastApplied( sal_False
)
668 , m_bFinalCount( sal_False
)
670 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
)
672 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
)
674 , m_bLastReadWasFromCache( sal_False
)
675 , m_bLastCachedReadWasNull( sal_True
)
676 , m_aCache( m_xContentIdentifierMapping
)
677 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping
)
678 , m_aCacheContentIdentifier( m_xContentIdentifierMapping
)
679 , m_aCacheContent( m_xContentIdentifierMapping
)
680 , m_bTriedToGetTypeConverter( sal_False
)
681 , m_xTypeConverter( NULL
)
683 m_xFetchProvider
= Reference
< XFetchProvider
>( m_xResultSetOrigin
, UNO_QUERY
);
684 OSL_ENSURE( m_xFetchProvider
.is(), "interface XFetchProvider is required" );
686 m_xFetchProviderForContentAccess
= Reference
< XFetchProviderForContentAccess
>( m_xResultSetOrigin
, UNO_QUERY
);
687 OSL_ENSURE( m_xFetchProviderForContentAccess
.is(), "interface XFetchProviderForContentAccess is required" );
692 CachedContentResultSet::~CachedContentResultSet()
695 //do not delete m_pMyPropSetInfo, cause it is hold via reference
698 //--------------------------------------------------------------------------
700 //--------------------------------------------------------------------------
702 sal_Bool SAL_CALL CachedContentResultSet
703 ::applyPositionToOrigin( sal_Int32 nRow
)
707 impl_EnsureNotDisposed();
708 //-------------------------------------------------------------------------
711 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
715 ReacquireableGuard
aGuard( m_aMutex
);
716 OSL_ENSURE( nRow
>= 0, "only positive values supported" );
717 if( !m_xResultSetOrigin
.is() )
719 OSL_FAIL( "broadcaster was disposed already" );
722 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
724 sal_Int32 nLastAppliedPos
= m_nLastAppliedPos
;
725 sal_Bool bAfterLastApplied
= m_bAfterLastApplied
;
726 sal_Bool bAfterLast
= m_bAfterLast
;
727 sal_Int32 nForwardOnly
= m_nForwardOnly
;
731 if( bAfterLastApplied
|| nLastAppliedPos
!= nRow
)
733 if( nForwardOnly
== 1 )
735 if( bAfterLastApplied
|| bAfterLast
|| !nRow
|| nRow
< nLastAppliedPos
)
736 throw SQLException();
738 sal_Int32 nN
= nRow
- nLastAppliedPos
;
740 for( nM
= 0; nN
--; nM
++ )
742 if( !m_xResultSetOrigin
->next() )
747 m_nLastAppliedPos
+= nM
;
748 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
749 return nRow
== m_nLastAppliedPos
;
752 if( !nRow
) //absolute( 0 ) will throw exception
754 m_xResultSetOrigin
->beforeFirst();
757 m_nLastAppliedPos
= 0;
758 m_bAfterLastApplied
= sal_False
;
763 //move absolute, if !nLastAppliedPos
764 //because move relative would throw exception
765 if( !nLastAppliedPos
|| bAfterLast
|| bAfterLastApplied
)
767 sal_Bool bValid
= m_xResultSetOrigin
->absolute( nRow
);
770 m_nLastAppliedPos
= nRow
;
771 m_bAfterLastApplied
= !bValid
;
776 sal_Bool bValid
= m_xResultSetOrigin
->relative( nRow
- nLastAppliedPos
);
779 m_nLastAppliedPos
+= ( nRow
- nLastAppliedPos
);
780 m_bAfterLastApplied
= !bValid
;
784 catch (const SQLException
&)
786 if( !bAfterLastApplied
&& !bAfterLast
&& nRow
> nLastAppliedPos
&& impl_isForwardOnly() )
788 sal_Int32 nN
= nRow
- nLastAppliedPos
;
790 for( nM
= 0; nN
--; nM
++ )
792 if( !m_xResultSetOrigin
->next() )
797 m_nLastAppliedPos
+= nM
;
798 m_bAfterLastApplied
= nRow
!= m_nLastAppliedPos
;
804 return nRow
== m_nLastAppliedPos
;
809 //--------------------------------------------------------------------------
810 //--------------------------------------------------------------------------
811 //define for fetching data
812 //--------------------------------------------------------------------------
813 //--------------------------------------------------------------------------
815 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
816 sal_Bool bDirection = !!( \
817 nFetchDirection != FetchDirection::REVERSE ); \
818 FetchResult aResult = \
819 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
820 osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
821 aCache.loadData( aResult ); \
822 sal_Int32 nMax = aCache.getMaxRow(); \
823 sal_Int32 nCurCount = m_nKnownCount; \
824 sal_Bool bIsFinalCount = aCache.hasKnownLast(); \
825 sal_Bool bCurIsFinalCount = m_bFinalCount; \
827 if( nMax > nCurCount ) \
828 impl_changeRowCount( nCurCount, nMax ); \
829 if( bIsFinalCount && !bCurIsFinalCount ) \
830 impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
832 void SAL_CALL CachedContentResultSet
833 ::impl_fetchData( sal_Int32 nRow
834 , sal_Int32 nFetchSize
, sal_Int32 nFetchDirection
)
835 throw( com::sun::star::uno::RuntimeException
)
837 FETCH_XXX( m_aCache
, m_xFetchProvider
, fetch
);
840 void SAL_CALL CachedContentResultSet
841 ::impl_changeRowCount( sal_Int32 nOld
, sal_Int32 nNew
)
843 OSL_ENSURE( nNew
> nOld
, "RowCount only can grow" );
847 //create PropertyChangeEvent and set value
848 PropertyChangeEvent aEvt
;
850 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
851 aEvt
.Source
= static_cast< XPropertySet
* >( this );
852 aEvt
.Further
= sal_False
;
853 aEvt
.OldValue
<<= nOld
;
854 aEvt
.NewValue
<<= nNew
;
856 m_nKnownCount
= nNew
;
859 //send PropertyChangeEvent to listeners
860 impl_notifyPropertyChangeListeners( aEvt
);
863 void SAL_CALL CachedContentResultSet
864 ::impl_changeIsRowCountFinal( sal_Bool bOld
, sal_Bool bNew
)
866 OSL_ENSURE( !bOld
&& bNew
, "This change is not allowed for IsRowCountFinal" );
867 if( ! (!bOld
&& bNew
) )
870 //create PropertyChangeEvent and set value
871 PropertyChangeEvent aEvt
;
873 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
874 aEvt
.Source
= static_cast< XPropertySet
* >( this );
875 aEvt
.Further
= sal_False
;
876 aEvt
.OldValue
<<= bOld
;
877 aEvt
.NewValue
<<= bNew
;
879 m_bFinalCount
= bNew
;
882 //send PropertyChangeEvent to listeners
883 impl_notifyPropertyChangeListeners( aEvt
);
886 sal_Bool SAL_CALL CachedContentResultSet
887 ::impl_isKnownValidPosition( sal_Int32 nRow
)
889 return m_nKnownCount
&& nRow
890 && nRow
<= m_nKnownCount
;
893 sal_Bool SAL_CALL CachedContentResultSet
894 ::impl_isKnownInvalidPosition( sal_Int32 nRow
)
900 return nRow
> m_nKnownCount
;
905 void SAL_CALL CachedContentResultSet
906 ::impl_initPropertySetInfo()
908 ContentResultSetWrapper::impl_initPropertySetInfo();
910 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
911 if( m_pMyPropSetInfo
)
913 m_pMyPropSetInfo
= new CCRS_PropertySetInfo( m_xPropertySetInfo
);
914 m_xMyPropertySetInfo
= m_pMyPropSetInfo
;
915 m_xPropertySetInfo
= m_xMyPropertySetInfo
;
918 //--------------------------------------------------------------------------
919 // XInterface methods. ( inherited )
920 //--------------------------------------------------------------------------
921 XINTERFACE_COMMON_IMPL( CachedContentResultSet
)
923 Any SAL_CALL CachedContentResultSet
924 ::queryInterface( const Type
& rType
)
925 throw ( RuntimeException
)
927 //list all interfaces inclusive baseclasses of interfaces
929 Any aRet
= ContentResultSetWrapper::queryInterface( rType
);
930 if( aRet
.hasValue() )
933 aRet
= cppu::queryInterface( rType
,
934 static_cast< XTypeProvider
* >( this ),
935 static_cast< XServiceInfo
* >( this ) );
937 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
940 //--------------------------------------------------------------------------
941 // XTypeProvider methods.
942 //--------------------------------------------------------------------------
943 //list all interfaces exclusive baseclasses
944 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
949 , XResultSetMetaDataSupplier
952 , XPropertyChangeListener
953 , XVetoableChangeListener
960 //--------------------------------------------------------------------------
961 // XServiceInfo methods.
962 //--------------------------------------------------------------------------
964 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet
,
966 "com.sun.star.comp.ucb.CachedContentResultSet" ),
968 CACHED_CONTENT_RESULTSET_SERVICE_NAME
) );
970 //--------------------------------------------------------------------------
971 // XPropertySet methods. ( inherited )
972 //--------------------------------------------------------------------------
975 void SAL_CALL CachedContentResultSet
976 ::setPropertyValue( const OUString
& aPropertyName
, const Any
& aValue
)
977 throw( UnknownPropertyException
,
978 PropertyVetoException
,
979 IllegalArgumentException
,
980 WrappedTargetException
,
983 impl_EnsureNotDisposed();
985 if( !getPropertySetInfo().is() )
987 OSL_FAIL( "broadcaster was disposed already" );
988 throw UnknownPropertyException();
991 Property aProp
= m_pMyPropSetInfo
->getPropertyByName( aPropertyName
);
992 //throws UnknownPropertyException, if so
994 if( aProp
.Attributes
& PropertyAttribute::READONLY
)
996 //It is assumed, that the properties
997 //'RowCount' and 'IsRowCountFinal' are readonly!
998 throw IllegalArgumentException();
1000 if( aProp
.Name
== CCRS_PropertySetInfo
1001 ::m_aPropertyNameForFetchDirection
)
1005 if( !( aValue
>>= nNew
) )
1007 throw IllegalArgumentException();
1010 if( nNew
== FetchDirection::UNKNOWN
)
1012 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION
;
1014 else if( !( nNew
== FetchDirection::FORWARD
1015 || nNew
== FetchDirection::REVERSE
) )
1017 throw IllegalArgumentException();
1020 //create PropertyChangeEvent and set value
1021 PropertyChangeEvent aEvt
;
1023 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1024 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1025 aEvt
.PropertyName
= aPropertyName
;
1026 aEvt
.Further
= sal_False
;
1027 aEvt
.PropertyHandle
= m_pMyPropSetInfo
->
1028 m_nFetchDirectionPropertyHandle
;
1029 aEvt
.OldValue
<<= m_nFetchDirection
;
1030 aEvt
.NewValue
<<= nNew
;
1032 m_nFetchDirection
= nNew
;
1035 //send PropertyChangeEvent to listeners
1036 impl_notifyPropertyChangeListeners( aEvt
);
1038 else if( aProp
.Name
== CCRS_PropertySetInfo
1039 ::m_aPropertyNameForFetchSize
)
1043 if( !( aValue
>>= nNew
) )
1045 throw IllegalArgumentException();
1050 nNew
= COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE
;
1053 //create PropertyChangeEvent and set value
1054 PropertyChangeEvent aEvt
;
1056 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1057 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1058 aEvt
.PropertyName
= aPropertyName
;
1059 aEvt
.Further
= sal_False
;
1060 aEvt
.PropertyHandle
= m_pMyPropSetInfo
->
1061 m_nFetchSizePropertyHandle
;
1062 aEvt
.OldValue
<<= m_nFetchSize
;
1063 aEvt
.NewValue
<<= nNew
;
1065 m_nFetchSize
= nNew
;
1068 //send PropertyChangeEvent to listeners
1069 impl_notifyPropertyChangeListeners( aEvt
);
1073 impl_init_xPropertySetOrigin();
1075 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1076 if( !m_xPropertySetOrigin
.is() )
1078 OSL_FAIL( "broadcaster was disposed already" );
1082 m_xPropertySetOrigin
->setPropertyValue( aPropertyName
, aValue
);
1086 //--------------------------------------------------------------------------
1088 Any SAL_CALL CachedContentResultSet
1089 ::getPropertyValue( const OUString
& rPropertyName
)
1090 throw( UnknownPropertyException
,
1091 WrappedTargetException
,
1094 impl_EnsureNotDisposed();
1096 if( !getPropertySetInfo().is() )
1098 OSL_FAIL( "broadcaster was disposed already" );
1099 throw UnknownPropertyException();
1102 Property aProp
= m_pMyPropSetInfo
->getPropertyByName( rPropertyName
);
1103 //throws UnknownPropertyException, if so
1106 if( rPropertyName
== CCRS_PropertySetInfo
1107 ::m_aPropertyNameForCount
)
1109 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1110 aValue
<<= m_nKnownCount
;
1112 else if( rPropertyName
== CCRS_PropertySetInfo
1113 ::m_aPropertyNameForFinalCount
)
1115 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1116 aValue
<<= m_bFinalCount
;
1118 else if( rPropertyName
== CCRS_PropertySetInfo
1119 ::m_aPropertyNameForFetchSize
)
1121 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1122 aValue
<<= m_nFetchSize
;
1124 else if( rPropertyName
== CCRS_PropertySetInfo
1125 ::m_aPropertyNameForFetchDirection
)
1127 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1128 aValue
<<= m_nFetchDirection
;
1132 impl_init_xPropertySetOrigin();
1134 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1135 if( !m_xPropertySetOrigin
.is() )
1137 OSL_FAIL( "broadcaster was disposed already" );
1138 throw UnknownPropertyException();
1141 aValue
= m_xPropertySetOrigin
->getPropertyValue( rPropertyName
);
1146 //--------------------------------------------------------------------------
1147 // own methods. ( inherited )
1148 //--------------------------------------------------------------------------
1151 void SAL_CALL CachedContentResultSet
1152 ::impl_disposing( const EventObject
& rEventObject
)
1153 throw( RuntimeException
)
1156 impl_EnsureNotDisposed();
1157 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1158 //release all references to the broadcaster:
1159 m_xFetchProvider
.clear();
1160 m_xFetchProviderForContentAccess
.clear();
1162 ContentResultSetWrapper::impl_disposing( rEventObject
);
1166 void SAL_CALL CachedContentResultSet
1167 ::impl_propertyChange( const PropertyChangeEvent
& rEvt
)
1168 throw( RuntimeException
)
1170 impl_EnsureNotDisposed();
1172 PropertyChangeEvent
aEvt( rEvt
);
1173 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1174 aEvt
.Further
= sal_False
;
1177 if( CCRS_PropertySetInfo
1178 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1180 //don't notify foreign events on fetchsize and fetchdirection
1181 if( aEvt
.PropertyName
== CCRS_PropertySetInfo
1182 ::m_aPropertyNameForFetchSize
1183 || aEvt
.PropertyName
== CCRS_PropertySetInfo
1184 ::m_aPropertyNameForFetchDirection
)
1187 //adjust my props 'RowCount' and 'IsRowCountFinal'
1188 if( aEvt
.PropertyName
== CCRS_PropertySetInfo
1189 ::m_aPropertyNameForCount
)
1194 if( !( aEvt
.NewValue
>>= nNew
) )
1196 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1200 impl_changeRowCount( m_nKnownCount
, nNew
);
1202 else if( aEvt
.PropertyName
== CCRS_PropertySetInfo
1203 ::m_aPropertyNameForFinalCount
)
1204 {//IsRowCountFinal changed
1207 sal_Bool bNew
= sal_False
;
1208 if( !( aEvt
.NewValue
>>= bNew
) )
1210 OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1213 impl_changeIsRowCountFinal( m_bFinalCount
, bNew
);
1219 impl_notifyPropertyChangeListeners( aEvt
);
1224 void SAL_CALL CachedContentResultSet
1225 ::impl_vetoableChange( const PropertyChangeEvent
& rEvt
)
1226 throw( PropertyVetoException
,
1229 impl_EnsureNotDisposed();
1231 //don't notify events on my properties, cause they are not vetoable
1232 if( CCRS_PropertySetInfo
1233 ::impl_isMyPropertyName( rEvt
.PropertyName
) )
1239 PropertyChangeEvent
aEvt( rEvt
);
1240 aEvt
.Source
= static_cast< XPropertySet
* >( this );
1241 aEvt
.Further
= sal_False
;
1243 impl_notifyVetoableChangeListeners( aEvt
);
1246 //--------------------------------------------------------------------------
1247 // XContentAccess methods. ( inherited ) ( -- position dependent )
1248 //--------------------------------------------------------------------------
1250 #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1251 impl_EnsureNotDisposed(); \
1252 ReacquireableGuard aGuard( m_aMutex ); \
1253 sal_Int32 nRow = m_nRow; \
1254 sal_Int32 nFetchSize = m_nFetchSize; \
1255 sal_Int32 nFetchDirection = m_nFetchDirection; \
1256 if( !m_aCache##XXX.hasRow( nRow ) ) \
1258 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1260 if( !m_xFetchProviderForContentAccess.is() ) \
1262 OSL_FAIL( "broadcaster was disposed already" );\
1263 throw RuntimeException(); \
1266 if( impl_isForwardOnly() ) \
1267 applyPositionToOrigin( nRow ); \
1269 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1271 aGuard.reacquire(); \
1272 if( !m_aCache##XXX.hasRow( nRow ) ) \
1275 applyPositionToOrigin( nRow ); \
1276 TYPE aRet = ContentResultSetWrapper::queryXXX(); \
1277 if( m_xContentIdentifierMapping.is() ) \
1278 return m_xContentIdentifierMapping->map##XXX( aRet );\
1282 return m_aCache##XXX.get##XXX( nRow );
1284 //--------------------------------------------------------------------------
1286 OUString SAL_CALL CachedContentResultSet
1287 ::queryContentIdentifierString()
1288 throw( RuntimeException
)
1290 XCONTENTACCESS_queryXXX( queryContentIdentifierString
, ContentIdentifierString
, OUString
)
1293 //--------------------------------------------------------------------------
1295 Reference
< XContentIdentifier
> SAL_CALL CachedContentResultSet
1296 ::queryContentIdentifier()
1297 throw( RuntimeException
)
1299 XCONTENTACCESS_queryXXX( queryContentIdentifier
, ContentIdentifier
, Reference
< XContentIdentifier
> )
1302 //--------------------------------------------------------------------------
1304 Reference
< XContent
> SAL_CALL CachedContentResultSet
1306 throw( RuntimeException
)
1308 XCONTENTACCESS_queryXXX( queryContent
, Content
, Reference
< XContent
> )
1311 //-----------------------------------------------------------------
1312 // XResultSet methods. ( inherited )
1313 //-----------------------------------------------------------------
1316 sal_Bool SAL_CALL CachedContentResultSet
1318 throw( SQLException
,
1321 impl_EnsureNotDisposed();
1323 ReacquireableGuard
aGuard( m_aMutex
);
1333 m_bAfterLast
= sal_True
;
1337 //known valid position
1338 if( impl_isKnownValidPosition( m_nRow
+ 1 ) )
1345 sal_Int32 nRow
= m_nRow
;
1348 sal_Bool bValid
= applyPositionToOrigin( nRow
+ 1 );
1352 m_bAfterLast
= !bValid
;
1357 sal_Bool SAL_CALL CachedContentResultSet
1359 throw( SQLException
,
1362 impl_EnsureNotDisposed();
1364 if( impl_isForwardOnly() )
1365 throw SQLException();
1367 ReacquireableGuard
aGuard( m_aMutex
);
1369 if( !m_bAfterLast
&& !m_nRow
)
1372 if( !m_bAfterLast
&& m_nKnownCount
&& m_nRow
== 1 )
1375 m_bAfterLast
= sal_False
;
1378 //known valid position ?:
1379 if( impl_isKnownValidPosition( m_nRow
- 1 ) )
1382 m_bAfterLast
= sal_False
;
1386 sal_Int32 nRow
= m_nRow
;
1389 sal_Bool bValid
= applyPositionToOrigin( nRow
- 1 );
1393 m_bAfterLast
= sal_False
;
1398 sal_Bool SAL_CALL CachedContentResultSet
1399 ::absolute( sal_Int32 row
)
1400 throw( SQLException
,
1403 impl_EnsureNotDisposed();
1406 throw SQLException();
1408 if( impl_isForwardOnly() )
1409 throw SQLException();
1411 ReacquireableGuard
aGuard( m_aMutex
);
1413 if( !m_xResultSetOrigin
.is() )
1415 OSL_FAIL( "broadcaster was disposed already" );
1422 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1423 sal_Bool bValid
= sal_True
;
1430 m_bAfterLast
= sal_False
;
1433 //unknown final count:
1436 // Solaris has problems catching or propagating derived exceptions
1437 // when only the base class is known, so make ResultSetException
1438 // (derived from SQLException) known here:
1442 bValid
= m_xResultSetOrigin
->absolute( row
);
1444 catch (const ResultSetException
&)
1452 sal_Int32 nNewRow
= m_nKnownCount
+ 1 + row
;
1455 m_nLastAppliedPos
= nNewRow
;
1457 m_bAfterLastApplied
= m_bAfterLast
= sal_False
;
1462 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1465 m_nLastAppliedPos
= nCurRow
;
1467 m_bAfterLast
= sal_False
;
1468 return nCurRow
!= 0;
1473 if( row
> m_nKnownCount
)
1475 m_nRow
= m_nKnownCount
+ 1;
1476 m_bAfterLast
= sal_True
;
1480 m_bAfterLast
= sal_False
;
1483 //unknown new position:
1486 sal_Bool bValid
= m_xResultSetOrigin
->absolute( row
);
1491 sal_Int32 nNewRow
= row
;
1492 if( nNewRow
> m_nKnownCount
)
1494 nNewRow
= m_nKnownCount
+ 1;
1495 m_bAfterLastApplied
= m_bAfterLast
= sal_True
;
1498 m_bAfterLastApplied
= m_bAfterLast
= sal_False
;
1500 m_nLastAppliedPos
= nNewRow
;
1506 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1507 sal_Bool bIsAfterLast
= m_xResultSetOrigin
->isAfterLast();
1510 m_nLastAppliedPos
= nCurRow
;
1512 m_bAfterLastApplied
= m_bAfterLast
= bIsAfterLast
;
1513 return nCurRow
&& !bIsAfterLast
;
1517 sal_Bool SAL_CALL CachedContentResultSet
1518 ::relative( sal_Int32 rows
)
1519 throw( SQLException
,
1522 impl_EnsureNotDisposed();
1524 if( impl_isForwardOnly() )
1525 throw SQLException();
1527 ReacquireableGuard
aGuard( m_aMutex
);
1528 if( m_bAfterLast
|| impl_isKnownInvalidPosition( m_nRow
) )
1529 throw SQLException();
1534 sal_Int32 nNewRow
= m_nRow
+ rows
;
1538 if( impl_isKnownValidPosition( nNewRow
) )
1541 m_bAfterLast
= sal_False
;
1546 //known invalid new position:
1549 m_bAfterLast
= sal_False
;
1553 if( m_bFinalCount
&& nNewRow
> m_nKnownCount
)
1555 m_bAfterLast
= sal_True
;
1556 m_nRow
= m_nKnownCount
+ 1;
1559 //unknown new position:
1561 sal_Bool bValid
= applyPositionToOrigin( nNewRow
);
1565 m_bAfterLast
= !bValid
&& nNewRow
> 0;
1572 sal_Bool SAL_CALL CachedContentResultSet
1574 throw( SQLException
,
1577 impl_EnsureNotDisposed();
1579 if( impl_isForwardOnly() )
1580 throw SQLException();
1582 ReacquireableGuard
aGuard( m_aMutex
);
1583 if( impl_isKnownValidPosition( 1 ) )
1586 m_bAfterLast
= sal_False
;
1589 if( impl_isKnownInvalidPosition( 1 ) )
1592 m_bAfterLast
= sal_False
;
1598 sal_Bool bValid
= applyPositionToOrigin( 1 );
1602 m_bAfterLast
= sal_False
;
1607 sal_Bool SAL_CALL CachedContentResultSet
1609 throw( SQLException
,
1612 impl_EnsureNotDisposed();
1614 if( impl_isForwardOnly() )
1615 throw SQLException();
1617 ReacquireableGuard
aGuard( m_aMutex
);
1620 m_nRow
= m_nKnownCount
;
1621 m_bAfterLast
= sal_False
;
1622 return m_nKnownCount
!= 0;
1625 if( !m_xResultSetOrigin
.is() )
1627 OSL_FAIL( "broadcaster was disposed already" );
1632 sal_Bool bValid
= m_xResultSetOrigin
->last();
1635 m_bAfterLastApplied
= m_bAfterLast
= sal_False
;
1638 m_nLastAppliedPos
= m_nKnownCount
;
1639 m_nRow
= m_nKnownCount
;
1644 sal_Int32 nCurRow
= m_xResultSetOrigin
->getRow();
1647 m_nLastAppliedPos
= nCurRow
;
1649 OSL_ENSURE( nCurRow
>= m_nKnownCount
, "position of last row < known Count, that could not be" );
1650 m_nKnownCount
= nCurRow
;
1651 m_bFinalCount
= sal_True
;
1652 return nCurRow
!= 0;
1656 void SAL_CALL CachedContentResultSet
1658 throw( SQLException
,
1661 impl_EnsureNotDisposed();
1663 if( impl_isForwardOnly() )
1664 throw SQLException();
1666 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1668 m_bAfterLast
= sal_False
;
1672 void SAL_CALL CachedContentResultSet
1674 throw( SQLException
,
1677 impl_EnsureNotDisposed();
1679 if( impl_isForwardOnly() )
1680 throw SQLException();
1682 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1684 m_bAfterLast
= sal_True
;
1688 sal_Bool SAL_CALL CachedContentResultSet
1690 throw( SQLException
,
1693 impl_EnsureNotDisposed();
1695 ReacquireableGuard
aGuard( m_aMutex
);
1699 return m_bAfterLast
;
1703 if( !m_xResultSetOrigin
.is() )
1705 OSL_FAIL( "broadcaster was disposed already" );
1710 //find out whethter the original resultset contains rows or not
1711 m_xResultSetOrigin
->afterLast();
1714 m_bAfterLastApplied
= sal_True
;
1717 return m_xResultSetOrigin
->isAfterLast();
1721 sal_Bool SAL_CALL CachedContentResultSet
1723 throw( SQLException
,
1726 impl_EnsureNotDisposed();
1728 ReacquireableGuard
aGuard( m_aMutex
);
1738 if( !m_xResultSetOrigin
.is() )
1740 OSL_FAIL( "broadcaster was disposed already" );
1745 //find out whethter the original resultset contains rows or not
1746 m_xResultSetOrigin
->beforeFirst();
1749 m_bAfterLastApplied
= sal_False
;
1750 m_nLastAppliedPos
= 0;
1753 return m_xResultSetOrigin
->isBeforeFirst();
1757 sal_Bool SAL_CALL CachedContentResultSet
1759 throw( SQLException
,
1762 impl_EnsureNotDisposed();
1765 Reference
< XResultSet
> xResultSetOrigin
;
1768 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1779 xResultSetOrigin
= m_xResultSetOrigin
;
1782 //need to ask origin
1784 if( applyPositionToOrigin( nRow
) )
1785 return xResultSetOrigin
->isFirst();
1792 sal_Bool SAL_CALL CachedContentResultSet
1794 throw( SQLException
,
1797 impl_EnsureNotDisposed();
1800 Reference
< XResultSet
> xResultSetOrigin
;
1802 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1805 if( m_nRow
< m_nKnownCount
)
1808 return m_nKnownCount
&& m_nRow
== m_nKnownCount
;
1811 xResultSetOrigin
= m_xResultSetOrigin
;
1814 //need to ask origin
1816 if( applyPositionToOrigin( nRow
) )
1817 return xResultSetOrigin
->isLast();
1825 sal_Int32 SAL_CALL CachedContentResultSet
1827 throw( SQLException
,
1830 impl_EnsureNotDisposed();
1832 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1839 void SAL_CALL CachedContentResultSet
1841 throw( SQLException
,
1844 impl_EnsureNotDisposed();
1846 //the ContentResultSet is static and will not change
1847 //therefore we don't need to reload anything
1851 sal_Bool SAL_CALL CachedContentResultSet
1853 throw( SQLException
,
1856 impl_EnsureNotDisposed();
1858 //the ContentResultSet is static and will not change
1862 sal_Bool SAL_CALL CachedContentResultSet
1864 throw( SQLException
,
1867 impl_EnsureNotDisposed();
1869 //the ContentResultSet is static and will not change
1874 sal_Bool SAL_CALL CachedContentResultSet
1876 throw( SQLException
,
1879 impl_EnsureNotDisposed();
1881 //the ContentResultSet is static and will not change
1886 Reference
< XInterface
> SAL_CALL CachedContentResultSet
1888 throw( SQLException
,
1891 impl_EnsureNotDisposed();
1892 //@todo ?return anything
1893 return Reference
< XInterface
>();
1896 //-----------------------------------------------------------------
1897 // XRow methods. ( inherited )
1898 //-----------------------------------------------------------------
1901 sal_Bool SAL_CALL CachedContentResultSet
1903 throw( SQLException
,
1906 impl_EnsureNotDisposed();
1907 impl_init_xRowOrigin();
1909 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
1910 if( m_bLastReadWasFromCache
)
1911 return m_bLastCachedReadWasNull
;
1912 if( !m_xRowOrigin
.is() )
1914 OSL_FAIL( "broadcaster was disposed already" );
1918 return m_xRowOrigin
->wasNull();
1922 OUString SAL_CALL CachedContentResultSet
1923 ::getString( sal_Int32 columnIndex
)
1924 throw( SQLException
,
1927 XROW_GETXXX( getString
, OUString
);
1931 sal_Bool SAL_CALL CachedContentResultSet
1932 ::getBoolean( sal_Int32 columnIndex
)
1933 throw( SQLException
,
1936 XROW_GETXXX( getBoolean
, sal_Bool
);
1940 sal_Int8 SAL_CALL CachedContentResultSet
1941 ::getByte( sal_Int32 columnIndex
)
1942 throw( SQLException
,
1945 XROW_GETXXX( getByte
, sal_Int8
);
1949 sal_Int16 SAL_CALL CachedContentResultSet
1950 ::getShort( sal_Int32 columnIndex
)
1951 throw( SQLException
,
1954 XROW_GETXXX( getShort
, sal_Int16
);
1958 sal_Int32 SAL_CALL CachedContentResultSet
1959 ::getInt( sal_Int32 columnIndex
)
1960 throw( SQLException
,
1963 XROW_GETXXX( getInt
, sal_Int32
);
1967 sal_Int64 SAL_CALL CachedContentResultSet
1968 ::getLong( sal_Int32 columnIndex
)
1969 throw( SQLException
,
1972 XROW_GETXXX( getLong
, sal_Int64
);
1976 float SAL_CALL CachedContentResultSet
1977 ::getFloat( sal_Int32 columnIndex
)
1978 throw( SQLException
,
1981 XROW_GETXXX( getFloat
, float );
1985 double SAL_CALL CachedContentResultSet
1986 ::getDouble( sal_Int32 columnIndex
)
1987 throw( SQLException
,
1990 XROW_GETXXX( getDouble
, double );
1994 Sequence
< sal_Int8
> SAL_CALL CachedContentResultSet
1995 ::getBytes( sal_Int32 columnIndex
)
1996 throw( SQLException
,
1999 XROW_GETXXX( getBytes
, Sequence
< sal_Int8
> );
2003 Date SAL_CALL CachedContentResultSet
2004 ::getDate( sal_Int32 columnIndex
)
2005 throw( SQLException
,
2008 XROW_GETXXX( getDate
, Date
);
2012 Time SAL_CALL CachedContentResultSet
2013 ::getTime( sal_Int32 columnIndex
)
2014 throw( SQLException
,
2017 XROW_GETXXX( getTime
, Time
);
2021 DateTime SAL_CALL CachedContentResultSet
2022 ::getTimestamp( sal_Int32 columnIndex
)
2023 throw( SQLException
,
2026 XROW_GETXXX( getTimestamp
, DateTime
);
2030 Reference
< com::sun::star::io::XInputStream
>
2031 SAL_CALL CachedContentResultSet
2032 ::getBinaryStream( sal_Int32 columnIndex
)
2033 throw( SQLException
,
2036 XROW_GETXXX( getBinaryStream
, Reference
< com::sun::star::io::XInputStream
> );
2040 Reference
< com::sun::star::io::XInputStream
>
2041 SAL_CALL CachedContentResultSet
2042 ::getCharacterStream( sal_Int32 columnIndex
)
2043 throw( SQLException
,
2046 XROW_GETXXX( getCharacterStream
, Reference
< com::sun::star::io::XInputStream
> );
2050 Any SAL_CALL CachedContentResultSet
2051 ::getObject( sal_Int32 columnIndex
,
2053 com::sun::star::container::XNameAccess
>& typeMap
)
2054 throw( SQLException
,
2057 //if you change this macro please pay attention to
2058 //define XROW_GETXXX, where this is similar implemented
2060 ReacquireableGuard
aGuard( m_aMutex
);
2061 sal_Int32 nRow
= m_nRow
;
2062 sal_Int32 nFetchSize
= m_nFetchSize
;
2063 sal_Int32 nFetchDirection
= m_nFetchDirection
;
2064 if( !m_aCache
.hasRow( nRow
) )
2066 if( !m_aCache
.hasCausedException( nRow
) )
2068 if( !m_xFetchProvider
.is() )
2070 OSL_FAIL( "broadcaster was disposed already" );
2075 impl_fetchData( nRow
, nFetchSize
, nFetchDirection
);
2078 if( !m_aCache
.hasRow( nRow
) )
2080 m_bLastReadWasFromCache
= sal_False
;
2082 applyPositionToOrigin( nRow
);
2083 impl_init_xRowOrigin();
2084 return m_xRowOrigin
->getObject( columnIndex
, typeMap
);
2087 //@todo: pay attention to typeMap
2088 const Any
& rValue
= m_aCache
.getAny( nRow
, columnIndex
);
2090 m_bLastReadWasFromCache
= sal_True
;
2091 m_bLastCachedReadWasNull
= !( rValue
>>= aRet
);
2096 Reference
< XRef
> SAL_CALL CachedContentResultSet
2097 ::getRef( sal_Int32 columnIndex
)
2098 throw( SQLException
,
2101 XROW_GETXXX( getRef
, Reference
< XRef
> );
2105 Reference
< XBlob
> SAL_CALL CachedContentResultSet
2106 ::getBlob( sal_Int32 columnIndex
)
2107 throw( SQLException
,
2110 XROW_GETXXX( getBlob
, Reference
< XBlob
> );
2114 Reference
< XClob
> SAL_CALL CachedContentResultSet
2115 ::getClob( sal_Int32 columnIndex
)
2116 throw( SQLException
,
2119 XROW_GETXXX( getClob
, Reference
< XClob
> );
2123 Reference
< XArray
> SAL_CALL CachedContentResultSet
2124 ::getArray( sal_Int32 columnIndex
)
2125 throw( SQLException
,
2128 XROW_GETXXX( getArray
, Reference
< XArray
> );
2131 //-----------------------------------------------------------------
2132 // Type Converter Support
2133 //-----------------------------------------------------------------
2135 const Reference
< XTypeConverter
>& CachedContentResultSet::getTypeConverter()
2137 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
2139 if ( !m_bTriedToGetTypeConverter
&& !m_xTypeConverter
.is() )
2141 m_bTriedToGetTypeConverter
= sal_True
;
2142 m_xTypeConverter
= Reference
< XTypeConverter
>( Converter::create(m_xContext
) );
2144 OSL_ENSURE( m_xTypeConverter
.is(),
2145 "PropertyValueSet::getTypeConverter() - "
2146 "Service 'com.sun.star.script.Converter' n/a!" );
2148 return m_xTypeConverter
;
2151 //--------------------------------------------------------------------------
2152 //--------------------------------------------------------------------------
2153 // class CachedContentResultSetFactory
2154 //--------------------------------------------------------------------------
2155 //--------------------------------------------------------------------------
2157 CachedContentResultSetFactory::CachedContentResultSetFactory(
2158 const Reference
< XComponentContext
> & rxContext
)
2160 m_xContext
= rxContext
;
2163 CachedContentResultSetFactory::~CachedContentResultSetFactory()
2167 //--------------------------------------------------------------------------
2168 // CachedContentResultSetFactory XInterface methods.
2169 //--------------------------------------------------------------------------
2171 XINTERFACE_IMPL_3( CachedContentResultSetFactory
,
2174 XCachedContentResultSetFactory
);
2176 //--------------------------------------------------------------------------
2177 // CachedContentResultSetFactory XTypeProvider methods.
2178 //--------------------------------------------------------------------------
2180 XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory
,
2183 XCachedContentResultSetFactory
);
2185 //--------------------------------------------------------------------------
2186 // CachedContentResultSetFactory XServiceInfo methods.
2187 //--------------------------------------------------------------------------
2189 XSERVICEINFO_IMPL_1_CTX( CachedContentResultSetFactory
,
2190 OUString( "com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
2191 OUString( CACHED_CONTENT_RESULTSET_FACTORY_NAME
) );
2193 //--------------------------------------------------------------------------
2194 // Service factory implementation.
2195 //--------------------------------------------------------------------------
2197 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory
);
2199 //--------------------------------------------------------------------------
2200 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2201 //--------------------------------------------------------------------------
2204 Reference
< XResultSet
> SAL_CALL CachedContentResultSetFactory
2205 ::createCachedContentResultSet(
2206 const Reference
< XResultSet
> & xSource
,
2207 const Reference
< XContentIdentifierMapping
> & xMapping
)
2208 throw( com::sun::star::uno::RuntimeException
)
2210 Reference
< XResultSet
> xRet
;
2211 xRet
= new CachedContentResultSet( m_xContext
, xSource
, xMapping
);
2215 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */