1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cacher.hxx"
26
27 #include <cachedcontentresultset.hxx>
28 #include <com/sun/star/sdbc/FetchDirection.hpp>
29 #include <com/sun/star/ucb/FetchError.hpp>
30 #include <com/sun/star/ucb/ResultSetException.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/script/XTypeConverter.hpp>
33 #include <com/sun/star/sdbc/ResultSetType.hpp>
34 #include <rtl/ustring.hxx>
35 #include <osl/diagnose.h>
36
37 using namespace com::sun::star::beans;
38 using namespace com::sun::star::lang;
39 using namespace com::sun::star::script;
40 using namespace com::sun::star::sdbc;
41 using namespace com::sun::star::ucb;
42 using namespace com::sun::star::uno;
43 using namespace com::sun::star::util;
44 using namespace cppu;
45 using namespace rtl;
46
47 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
48 #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
49
50 //--------------------------------------------------------------------------
51 //--------------------------------------------------------------------------
52 //define for getXXX methods of interface XRow
53 //--------------------------------------------------------------------------
54 //--------------------------------------------------------------------------
55
56 //if you change this macro please pay attention to
57 //function ::getObject, where this is similar implemented
58
59 #define XROW_GETXXX( getXXX, Type ) \
60 impl_EnsureNotDisposed(); \
61 ReacquireableGuard aGuard( m_aMutex ); \
62 sal_Int32 nRow = m_nRow; \
63 sal_Int32 nFetchSize = m_nFetchSize; \
64 sal_Int32 nFetchDirection = m_nFetchDirection; \
65 if( !m_aCache.hasRow( nRow ) ) \
66 { \
67 if( !m_aCache.hasCausedException( nRow ) ) \
68 { \
69 if( !m_xFetchProvider.is() ) \
70 { \
71 OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \
72 throw SQLException(); \
73 } \
74 aGuard.clear(); \
75 if( impl_isForwardOnly() ) \
76 applyPositionToOrigin( nRow ); \
77 \
78 impl_fetchData( nRow, nFetchSize, nFetchDirection ); \
79 } \
80 aGuard.reacquire(); \
81 if( !m_aCache.hasRow( nRow ) ) \
82 { \
83 m_bLastReadWasFromCache = sal_False; \
84 aGuard.clear(); \
85 applyPositionToOrigin( nRow ); \
86 impl_init_xRowOrigin(); \
87 return m_xRowOrigin->getXXX( columnIndex ); \
88 } \
89 } \
90 const Any& rValue = m_aCache.getAny( nRow, columnIndex );\
91 Type aRet = Type(); \
92 m_bLastReadWasFromCache = sal_True; \
93 m_bLastCachedReadWasNull = !( rValue >>= aRet ); \
94 /* Last chance. Try type converter service... */ \
95 if ( m_bLastCachedReadWasNull && rValue.hasValue() ) \
96 { \
97 Reference< XTypeConverter > xConverter \
98 = getTypeConverter(); \
99 if ( xConverter.is() ) \
100 { \
101 try \
102 { \
103 Any aConvAny = xConverter->convertTo( \
104 rValue, \
105 getCppuType( static_cast< \
106 const Type * >( 0 ) ) ); \
107 m_bLastCachedReadWasNull = !( aConvAny >>= aRet ); \
108 } \
109 catch ( IllegalArgumentException ) \
110 { \
111 } \
112 catch ( CannotConvertException ) \
113 { \
114 } \
115 } \
116 } \
117 return aRet;
118
119 //--------------------------------------------------------------------------
120 //--------------------------------------------------------------------------
121 // CCRS_Cache methoeds.
122 //--------------------------------------------------------------------------
123 //--------------------------------------------------------------------------
124
CCRS_Cache(const Reference<XContentIdentifierMapping> & xMapping)125 CachedContentResultSet::CCRS_Cache::CCRS_Cache(
126 const Reference< XContentIdentifierMapping > & xMapping )
127 : m_pResult( NULL )
128 , m_xContentIdentifierMapping( xMapping )
129 , m_pMappedReminder( NULL )
130 {
131 }
132
~CCRS_Cache()133 CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
134 {
135 delete m_pResult;
136 }
137
138 void SAL_CALL CachedContentResultSet::CCRS_Cache
clear()139 ::clear()
140 {
141 if( m_pResult )
142 {
143 delete m_pResult;
144 m_pResult = NULL;
145 }
146 clearMappedReminder();
147 }
148
149 void SAL_CALL CachedContentResultSet::CCRS_Cache
loadData(const FetchResult & rResult)150 ::loadData( const FetchResult& rResult )
151 {
152 clear();
153 m_pResult = new FetchResult( rResult );
154 }
155
156 sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
hasRow(sal_Int32 row)157 ::hasRow( sal_Int32 row )
158 {
159 if( !m_pResult )
160 return sal_False;
161 long nStart = m_pResult->StartIndex;
162 long nEnd = nStart;
163 if( m_pResult->Orientation )
164 nEnd += m_pResult->Rows.getLength() - 1;
165 else
166 nStart -= m_pResult->Rows.getLength() + 1;
167
168 return nStart <= row && row <= nEnd;
169 }
170
171 sal_Int32 SAL_CALL CachedContentResultSet::CCRS_Cache
getMaxRow()172 ::getMaxRow()
173 {
174 if( !m_pResult )
175 return 0;
176 long nEnd = m_pResult->StartIndex;
177 if( m_pResult->Orientation )
178 return nEnd += m_pResult->Rows.getLength() - 1;
179 else
180 return nEnd;
181 }
182
183 sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
hasKnownLast()184 ::hasKnownLast()
185 {
186 if( !m_pResult )
187 return sal_False;
188
189 if( ( m_pResult->FetchError & FetchError::ENDOFDATA )
190 && m_pResult->Orientation
191 && m_pResult->Rows.getLength() )
192 return sal_True;
193
194 return sal_False;
195 }
196
197 sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
hasCausedException(sal_Int32 nRow)198 ::hasCausedException( sal_Int32 nRow )
199 {
200 if( !m_pResult )
201 return sal_False;
202 if( !( m_pResult->FetchError & FetchError::EXCEPTION ) )
203 return sal_False;
204
205 long nEnd = m_pResult->StartIndex;
206 if( m_pResult->Orientation )
207 nEnd += m_pResult->Rows.getLength();
208
209 return nRow == nEnd+1;
210 }
211
212 Any& SAL_CALL CachedContentResultSet::CCRS_Cache
getRowAny(sal_Int32 nRow)213 ::getRowAny( sal_Int32 nRow )
214 {
215 if( !nRow )
216 throw SQLException();
217 if( !m_pResult )
218 throw SQLException();
219 if( !hasRow( nRow ) )
220 throw SQLException();
221
222 long nDiff = nRow - m_pResult->StartIndex;
223 if( nDiff < 0 )
224 nDiff *= -1;
225
226 return (m_pResult->Rows)[nDiff];
227 }
228
229 void SAL_CALL CachedContentResultSet::CCRS_Cache
remindMapped(sal_Int32 nRow)230 ::remindMapped( sal_Int32 nRow )
231 {
232 //remind that this row was mapped
233 if( !m_pResult )
234 return;
235 long nDiff = nRow - m_pResult->StartIndex;
236 if( nDiff < 0 )
237 nDiff *= -1;
238 Sequence< sal_Bool >* pMappedReminder = getMappedReminder();
239 if( nDiff < pMappedReminder->getLength() )
240 (*pMappedReminder)[nDiff] = sal_True;
241 }
242
243 sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
isRowMapped(sal_Int32 nRow)244 ::isRowMapped( sal_Int32 nRow )
245 {
246 if( !m_pMappedReminder || !m_pResult )
247 return sal_False;
248 long nDiff = nRow - m_pResult->StartIndex;
249 if( nDiff < 0 )
250 nDiff *= -1;
251 if( nDiff < m_pMappedReminder->getLength() )
252 return (*m_pMappedReminder)[nDiff];
253 return sal_False;
254 }
255
256 void SAL_CALL CachedContentResultSet::CCRS_Cache
clearMappedReminder()257 ::clearMappedReminder()
258 {
259 delete m_pMappedReminder;
260 m_pMappedReminder = NULL;
261 }
262
263 Sequence< sal_Bool >* SAL_CALL CachedContentResultSet::CCRS_Cache
getMappedReminder()264 ::getMappedReminder()
265 {
266 if( !m_pMappedReminder )
267 {
268 sal_Int32 nCount = m_pResult->Rows.getLength();
269 m_pMappedReminder = new Sequence< sal_Bool >( nCount );
270 for( ;nCount; nCount-- )
271 (*m_pMappedReminder)[nCount] = sal_False;
272 }
273 return m_pMappedReminder;
274 }
275
276 const Any& SAL_CALL CachedContentResultSet::CCRS_Cache
getAny(sal_Int32 nRow,sal_Int32 nColumnIndex)277 ::getAny( sal_Int32 nRow, sal_Int32 nColumnIndex )
278 {
279 if( !nColumnIndex )
280 throw SQLException();
281 if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
282 {
283 Any& rRow = getRowAny( nRow );
284 Sequence< Any > aValue;
285 rRow >>= aValue;
286 if( m_xContentIdentifierMapping->mapRow( aValue ) )
287 {
288 rRow <<= aValue;
289 remindMapped( nRow );
290 }
291 else
292 m_xContentIdentifierMapping.clear();
293 }
294 const Sequence< Any >& rRow =
295 (* reinterpret_cast< const Sequence< Any > * >
296 (getRowAny( nRow ).getValue() ));
297
298 if( nColumnIndex > rRow.getLength() )
299 throw SQLException();
300 return rRow[nColumnIndex-1];
301 }
302
303 const rtl::OUString& SAL_CALL CachedContentResultSet::CCRS_Cache
getContentIdentifierString(sal_Int32 nRow)304 ::getContentIdentifierString( sal_Int32 nRow )
305 {
306 try
307 {
308 if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
309 {
310 Any& rRow = getRowAny( nRow );
311 rtl::OUString aValue;
312 rRow >>= aValue;
313 rRow <<= m_xContentIdentifierMapping->mapContentIdentifierString( aValue );
314 remindMapped( nRow );
315 }
316 return (* reinterpret_cast< const rtl::OUString * >
317 (getRowAny( nRow ).getValue() ));
318 }
319 catch( SQLException )
320 {
321 throw RuntimeException();
322 }
323 }
324
325 const Reference< XContentIdentifier >& SAL_CALL CachedContentResultSet::CCRS_Cache
getContentIdentifier(sal_Int32 nRow)326 ::getContentIdentifier( sal_Int32 nRow )
327 {
328 try
329 {
330 if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
331 {
332 Any& rRow = getRowAny( nRow );
333 Reference< XContentIdentifier > aValue;
334 rRow >>= aValue;
335 rRow <<= m_xContentIdentifierMapping->mapContentIdentifier( aValue );
336 remindMapped( nRow );
337 }
338 return (* reinterpret_cast< const Reference< XContentIdentifier > * >
339 (getRowAny( nRow ).getValue() ));
340 }
341 catch( SQLException )
342 {
343 throw RuntimeException();
344 }
345 }
346
347 const Reference< XContent >& SAL_CALL CachedContentResultSet::CCRS_Cache
getContent(sal_Int32 nRow)348 ::getContent( sal_Int32 nRow )
349 {
350 try
351 {
352 if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
353 {
354 Any& rRow = getRowAny( nRow );
355 Reference< XContent > aValue;
356 rRow >>= aValue;
357 rRow <<= m_xContentIdentifierMapping->mapContent( aValue );
358 remindMapped( nRow );
359 }
360 return (* reinterpret_cast< const Reference< XContent > * >
361 (getRowAny( nRow ).getValue() ));
362 }
363 catch( SQLException )
364 {
365 throw RuntimeException();
366 }
367 }
368
369 //--------------------------------------------------------------------------
370 //--------------------------------------------------------------------------
371 // class CCRS_PropertySetInfo
372 //--------------------------------------------------------------------------
373 //--------------------------------------------------------------------------
374
375 class CCRS_PropertySetInfo :
376 public cppu::OWeakObject,
377 public com::sun::star::lang::XTypeProvider,
378 public com::sun::star::beans::XPropertySetInfo
379 {
380 friend class CachedContentResultSet;
381
382 //my Properties
383 Sequence< com::sun::star::beans::Property >*
384 m_pProperties;
385
386 //some helping variables ( names for my special properties )
387 static rtl::OUString m_aPropertyNameForCount;
388 static rtl::OUString m_aPropertyNameForFinalCount;
389 static rtl::OUString m_aPropertyNameForFetchSize;
390 static rtl::OUString m_aPropertyNameForFetchDirection;
391
392 long m_nFetchSizePropertyHandle;
393 long m_nFetchDirectionPropertyHandle;
394
395 private:
396 sal_Int32 SAL_CALL
397 impl_getRemainedHandle() const;
398
399 sal_Bool SAL_CALL
400 impl_queryProperty(
401 const rtl::OUString& rName
402 , com::sun::star::beans::Property& rProp ) const;
403 sal_Int32 SAL_CALL
404 impl_getPos( const rtl::OUString& rName ) const;
405
406 static sal_Bool SAL_CALL
407 impl_isMyPropertyName( const rtl::OUString& rName );
408
409 public:
410 CCRS_PropertySetInfo( Reference<
411 XPropertySetInfo > xPropertySetInfoOrigin );
412
413 virtual ~CCRS_PropertySetInfo();
414
415 // XInterface
416 XINTERFACE_DECL()
417
418 // XTypeProvider
419 XTYPEPROVIDER_DECL()
420
421 // XPropertySetInfo
422 virtual Sequence< com::sun::star::beans::Property > SAL_CALL
423 getProperties();
424
425 virtual com::sun::star::beans::Property SAL_CALL
426 getPropertyByName( const rtl::OUString& aName );
427
428 virtual sal_Bool SAL_CALL
429 hasPropertyByName( const rtl::OUString& Name );
430 };
431
432 OUString CCRS_PropertySetInfo::m_aPropertyNameForCount( OUString::createFromAscii( "RowCount" ) );
433 OUString CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( OUString::createFromAscii( "IsRowCountFinal" ) );
434 OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) );
435 OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) );
436
CCRS_PropertySetInfo(Reference<XPropertySetInfo> xInfo)437 CCRS_PropertySetInfo::CCRS_PropertySetInfo(
438 Reference< XPropertySetInfo > xInfo )
439 : m_pProperties( NULL )
440 , m_nFetchSizePropertyHandle( -1 )
441 , m_nFetchDirectionPropertyHandle( -1 )
442 {
443 //initialize list of properties:
444
445 // it is required, that the received xInfo contains the two
446 // properties with names 'm_aPropertyNameForCount' and
447 // 'm_aPropertyNameForFinalCount'
448
449 if( xInfo.is() )
450 {
451 Sequence<Property> aProps = xInfo->getProperties();
452 m_pProperties = new Sequence<Property> ( aProps );
453 }
454 else
455 {
456 OSL_ENSURE( sal_False, "The received XPropertySetInfo doesn't contain required properties" );
457 m_pProperties = new Sequence<Property>;
458 }
459
460 //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
461 sal_Int32 nFetchSize = impl_getPos( m_aPropertyNameForFetchSize );
462 sal_Int32 nFetchDirection = impl_getPos( m_aPropertyNameForFetchDirection );
463 sal_Int32 nDeleted = 0;
464 if( nFetchSize != -1 )
465 nDeleted++;
466 if( nFetchDirection != -1 )
467 nDeleted++;
468
469 Sequence< Property >* pOrigProps = new Sequence<Property> ( *m_pProperties );
470 sal_Int32 nOrigProps = pOrigProps->getLength();
471
472 m_pProperties->realloc( nOrigProps + 2 - nDeleted );//note that nDeleted is <= 2
473 for( sal_Int32 n = 0, m = 0; n < nOrigProps; n++, m++ )
474 {
475 if( n == nFetchSize || n == nFetchDirection )
476 m--;
477 else
478 (*m_pProperties)[ m ] = (*pOrigProps)[ n ];
479 }
480 {
481 Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted ];
482 rMyProp.Name = m_aPropertyNameForFetchSize;
483 rMyProp.Type = getCppuType( static_cast< const sal_Int32 * >( 0 ) );
484 rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;
485
486 if( nFetchSize != -1 )
487 m_nFetchSizePropertyHandle = (*pOrigProps)[nFetchSize].Handle;
488 else
489 m_nFetchSizePropertyHandle = impl_getRemainedHandle();
490
491 rMyProp.Handle = m_nFetchSizePropertyHandle;
492
493 }
494 {
495 Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted + 1 ];
496 rMyProp.Name = m_aPropertyNameForFetchDirection;
497 rMyProp.Type = getCppuType( static_cast< const sal_Bool * >( 0 ) );
498 rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;
499
500 if( nFetchSize != -1 )
501 m_nFetchDirectionPropertyHandle = (*pOrigProps)[nFetchDirection].Handle;
502 else
503 m_nFetchDirectionPropertyHandle = impl_getRemainedHandle();
504
505 m_nFetchDirectionPropertyHandle = rMyProp.Handle;
506 }
507 delete pOrigProps;
508 }
509
~CCRS_PropertySetInfo()510 CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
511 {
512 delete m_pProperties;
513 }
514
515 //--------------------------------------------------------------------------
516 // XInterface methods.
517 //--------------------------------------------------------------------------
518 //list all interfaces inclusive baseclasses of interfaces
519 XINTERFACE_IMPL_2( CCRS_PropertySetInfo
520 , XTypeProvider
521 , XPropertySetInfo
522 );
523
524 //--------------------------------------------------------------------------
525 // XTypeProvider methods.
526 //--------------------------------------------------------------------------
527 //list all interfaces exclusive baseclasses
528 XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
529 , XTypeProvider
530 , XPropertySetInfo
531 );
532 //--------------------------------------------------------------------------
533 // XPropertySetInfo methods.
534 //--------------------------------------------------------------------------
535 //virtual
536 Sequence< Property > SAL_CALL CCRS_PropertySetInfo
getProperties()537 ::getProperties()
538 {
539 return *m_pProperties;
540 }
541
542 //virtual
543 Property SAL_CALL CCRS_PropertySetInfo
getPropertyByName(const rtl::OUString & aName)544 ::getPropertyByName( const rtl::OUString& aName )
545 {
546 if ( !aName.getLength() )
547 throw UnknownPropertyException();
548
549 Property aProp;
550 if ( impl_queryProperty( aName, aProp ) )
551 return aProp;
552
553 throw UnknownPropertyException();
554 }
555
556 //virtual
557 sal_Bool SAL_CALL CCRS_PropertySetInfo
hasPropertyByName(const rtl::OUString & Name)558 ::hasPropertyByName( const rtl::OUString& Name )
559 {
560 return ( impl_getPos( Name ) != -1 );
561 }
562
563 //--------------------------------------------------------------------------
564 // impl_ methods.
565 //--------------------------------------------------------------------------
566
567 sal_Int32 SAL_CALL CCRS_PropertySetInfo
impl_getPos(const OUString & rName) const568 ::impl_getPos( const OUString& rName ) const
569 {
570 for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
571 {
572 const Property& rMyProp = (*m_pProperties)[nN];
573 if( rMyProp.Name == rName )
574 return nN;
575 }
576 return -1;
577 }
578
579 sal_Bool SAL_CALL CCRS_PropertySetInfo
impl_queryProperty(const OUString & rName,Property & rProp) const580 ::impl_queryProperty( const OUString& rName, Property& rProp ) const
581 {
582 for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
583 {
584 const Property& rMyProp = (*m_pProperties)[nN];
585 if( rMyProp.Name == rName )
586 {
587 rProp.Name = rMyProp.Name;
588 rProp.Handle = rMyProp.Handle;
589 rProp.Type = rMyProp.Type;
590 rProp.Attributes = rMyProp.Attributes;
591
592 return sal_True;
593 }
594 }
595 return sal_False;
596 }
597
598 //static
599 sal_Bool SAL_CALL CCRS_PropertySetInfo
impl_isMyPropertyName(const OUString & rPropertyName)600 ::impl_isMyPropertyName( const OUString& rPropertyName )
601 {
602 return ( rPropertyName == m_aPropertyNameForCount
603 || rPropertyName == m_aPropertyNameForFinalCount
604 || rPropertyName == m_aPropertyNameForFetchSize
605 || rPropertyName == m_aPropertyNameForFetchDirection );
606 }
607
608 sal_Int32 SAL_CALL CCRS_PropertySetInfo
impl_getRemainedHandle() const609 ::impl_getRemainedHandle( ) const
610 {
611 sal_Int32 nHandle = 1;
612
613 if( !m_pProperties )
614 {
615 OSL_ENSURE( sal_False, "Properties not initialized yet" );
616 return nHandle;
617 }
618 sal_Bool bFound = sal_True;
619 while( bFound )
620 {
621 bFound = sal_False;
622 for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
623 {
624 if( nHandle == (*m_pProperties)[nN].Handle )
625 {
626 bFound = sal_True;
627 nHandle++;
628 break;
629 }
630 }
631 }
632 return nHandle;
633 }
634
635 //--------------------------------------------------------------------------
636 //--------------------------------------------------------------------------
637 // class CachedContentResultSet
638 //--------------------------------------------------------------------------
639 //--------------------------------------------------------------------------
640
CachedContentResultSet(const Reference<XMultiServiceFactory> & xSMgr,const Reference<XResultSet> & xOrigin,const Reference<XContentIdentifierMapping> & xContentIdentifierMapping)641 CachedContentResultSet::CachedContentResultSet(
642 const Reference< XMultiServiceFactory > & xSMgr
643 , const Reference< XResultSet > & xOrigin
644 , const Reference< XContentIdentifierMapping > &
645 xContentIdentifierMapping )
646 : ContentResultSetWrapper( xOrigin )
647
648 , m_xSMgr( xSMgr )
649 , m_xFetchProvider( NULL )
650 , m_xFetchProviderForContentAccess( NULL )
651
652 , m_xMyPropertySetInfo( NULL )
653 , m_pMyPropSetInfo( NULL )
654
655 , m_xContentIdentifierMapping( xContentIdentifierMapping )
656 , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
657 , m_bAfterLast( sal_False )
658 , m_nLastAppliedPos( 0 )
659 , m_bAfterLastApplied( sal_False )
660 , m_nKnownCount( 0 )
661 , m_bFinalCount( sal_False )
662 , m_nFetchSize(
663 COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE )
664 , m_nFetchDirection(
665 COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION )
666
667 , m_bLastReadWasFromCache( sal_False )
668 , m_bLastCachedReadWasNull( sal_True )
669 , m_aCache( m_xContentIdentifierMapping )
670 , m_aCacheContentIdentifierString( m_xContentIdentifierMapping )
671 , m_aCacheContentIdentifier( m_xContentIdentifierMapping )
672 , m_aCacheContent( m_xContentIdentifierMapping )
673 , m_bTriedToGetTypeConverter( sal_False )
674 , m_xTypeConverter( NULL )
675 {
676 m_xFetchProvider = Reference< XFetchProvider >( m_xResultSetOrigin, UNO_QUERY );
677 OSL_ENSURE( m_xFetchProvider.is(), "interface XFetchProvider is required" );
678
679 m_xFetchProviderForContentAccess = Reference< XFetchProviderForContentAccess >( m_xResultSetOrigin, UNO_QUERY );
680 OSL_ENSURE( m_xFetchProviderForContentAccess.is(), "interface XFetchProviderForContentAccess is required" );
681
682 impl_init();
683 };
684
~CachedContentResultSet()685 CachedContentResultSet::~CachedContentResultSet()
686 {
687 impl_deinit();
688 //do not delete m_pMyPropSetInfo, cause it is hold via reference
689 };
690
691 //--------------------------------------------------------------------------
692 // impl_ methods.
693 //--------------------------------------------------------------------------
694
695 sal_Bool SAL_CALL CachedContentResultSet
applyPositionToOrigin(sal_Int32 nRow)696 ::applyPositionToOrigin( sal_Int32 nRow )
697 {
698 impl_EnsureNotDisposed();
699 //-------------------------------------------------------------------------
700 /**
701 @returns
702 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
703 the result set.
704 */
705
706 ReacquireableGuard aGuard( m_aMutex );
707 OSL_ENSURE( nRow >= 0, "only positive values supported" );
708 if( !m_xResultSetOrigin.is() )
709 {
710 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
711 return sal_False;
712 }
713 // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
714
715 sal_Int32 nLastAppliedPos = m_nLastAppliedPos;
716 sal_Bool bAfterLastApplied = m_bAfterLastApplied;
717 sal_Bool bAfterLast = m_bAfterLast;
718 sal_Int32 nForwardOnly = m_nForwardOnly;
719
720 aGuard.clear();
721
722 if( bAfterLastApplied || nLastAppliedPos != nRow )
723 {
724 if( nForwardOnly == 1 )
725 {
726 if( bAfterLastApplied || bAfterLast || !nRow || nRow < nLastAppliedPos )
727 throw SQLException();
728
729 sal_Int32 nN = nRow - nLastAppliedPos;
730 sal_Int32 nM;
731 for( nM = 0; nN--; nM++ )
732 {
733 if( !m_xResultSetOrigin->next() )
734 break;
735 }
736
737 aGuard.reacquire();
738 m_nLastAppliedPos += nM;
739 m_bAfterLastApplied = nRow != m_nLastAppliedPos;
740 return nRow == m_nLastAppliedPos;
741 }
742
743 if( !nRow ) //absolute( 0 ) will throw exception
744 {
745 m_xResultSetOrigin->beforeFirst();
746
747 aGuard.reacquire();
748 m_nLastAppliedPos = 0;
749 m_bAfterLastApplied = sal_False;
750 return sal_False;
751 }
752 try
753 {
754 //move absolute, if !nLastAppliedPos
755 //because move relative would throw exception
756 if( !nLastAppliedPos || bAfterLast || bAfterLastApplied )
757 {
758 sal_Bool bValid = m_xResultSetOrigin->absolute( nRow );
759
760 aGuard.reacquire();
761 m_nLastAppliedPos = nRow;
762 m_bAfterLastApplied = !bValid;
763 return bValid;
764 }
765 else
766 {
767 sal_Bool bValid = m_xResultSetOrigin->relative( nRow - nLastAppliedPos );
768
769 aGuard.reacquire();
770 m_nLastAppliedPos += ( nRow - nLastAppliedPos );
771 m_bAfterLastApplied = !bValid;
772 return bValid;
773 }
774 }
775 catch( SQLException& rEx )
776 {
777 if( !bAfterLastApplied && !bAfterLast && nRow > nLastAppliedPos && impl_isForwardOnly() )
778 {
779 sal_Int32 nN = nRow - nLastAppliedPos;
780 sal_Int32 nM;
781 for( nM = 0; nN--; nM++ )
782 {
783 if( !m_xResultSetOrigin->next() )
784 break;
785 }
786
787 aGuard.reacquire();
788 m_nLastAppliedPos += nM;
789 m_bAfterLastApplied = nRow != m_nLastAppliedPos;
790 }
791 else
792 throw rEx;
793 }
794
795 return nRow == m_nLastAppliedPos;
796 }
797 return sal_True;
798 };
799
800 //--------------------------------------------------------------------------
801 //--------------------------------------------------------------------------
802 //define for fetching data
803 //--------------------------------------------------------------------------
804 //--------------------------------------------------------------------------
805
806 #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
807 sal_Bool bDirection = !!( \
808 nFetchDirection != FetchDirection::REVERSE ); \
809 FetchResult aResult = \
810 fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
811 osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
812 aCache.loadData( aResult ); \
813 sal_Int32 nMax = aCache.getMaxRow(); \
814 sal_Int32 nCurCount = m_nKnownCount; \
815 sal_Bool bIsFinalCount = aCache.hasKnownLast(); \
816 sal_Bool bCurIsFinalCount = m_bFinalCount; \
817 aGuard2.clear(); \
818 if( nMax > nCurCount ) \
819 impl_changeRowCount( nCurCount, nMax ); \
820 if( bIsFinalCount && !bCurIsFinalCount ) \
821 impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
822
823 void SAL_CALL CachedContentResultSet
impl_fetchData(sal_Int32 nRow,sal_Int32 nFetchSize,sal_Int32 nFetchDirection)824 ::impl_fetchData( sal_Int32 nRow
825 , sal_Int32 nFetchSize, sal_Int32 nFetchDirection )
826 {
827 FETCH_XXX( m_aCache, m_xFetchProvider, fetch );
828 }
829
830 void SAL_CALL CachedContentResultSet
impl_changeRowCount(sal_Int32 nOld,sal_Int32 nNew)831 ::impl_changeRowCount( sal_Int32 nOld, sal_Int32 nNew )
832 {
833 OSL_ENSURE( nNew > nOld, "RowCount only can grow" );
834 if( nNew <= nOld )
835 return;
836
837 //create PropertyChangeEvent and set value
838 PropertyChangeEvent aEvt;
839 {
840 osl::Guard< osl::Mutex > aGuard( m_aMutex );
841 aEvt.Source = static_cast< XPropertySet * >( this );
842 aEvt.Further = sal_False;
843 aEvt.OldValue <<= nOld;
844 aEvt.NewValue <<= nNew;
845
846 m_nKnownCount = nNew;
847 }
848
849 //send PropertyChangeEvent to listeners
850 impl_notifyPropertyChangeListeners( aEvt );
851 }
852
853 void SAL_CALL CachedContentResultSet
impl_changeIsRowCountFinal(sal_Bool bOld,sal_Bool bNew)854 ::impl_changeIsRowCountFinal( sal_Bool bOld, sal_Bool bNew )
855 {
856 OSL_ENSURE( !bOld && bNew, "This change is not allowed for IsRowCountFinal" );
857 if( ! (!bOld && bNew ) )
858 return;
859
860 //create PropertyChangeEvent and set value
861 PropertyChangeEvent aEvt;
862 {
863 osl::Guard< osl::Mutex > aGuard( m_aMutex );
864 aEvt.Source = static_cast< XPropertySet * >( this );
865 aEvt.Further = sal_False;
866 aEvt.OldValue <<= bOld;
867 aEvt.NewValue <<= bNew;
868
869 m_bFinalCount = bNew;
870 }
871
872 //send PropertyChangeEvent to listeners
873 impl_notifyPropertyChangeListeners( aEvt );
874 }
875
876 sal_Bool SAL_CALL CachedContentResultSet
impl_isKnownValidPosition(sal_Int32 nRow)877 ::impl_isKnownValidPosition( sal_Int32 nRow )
878 {
879 return m_nKnownCount && nRow
880 && nRow <= m_nKnownCount;
881 }
882
883 sal_Bool SAL_CALL CachedContentResultSet
impl_isKnownInvalidPosition(sal_Int32 nRow)884 ::impl_isKnownInvalidPosition( sal_Int32 nRow )
885 {
886 if( !nRow )
887 return sal_True;
888 if( !m_bFinalCount )
889 return sal_False;
890 return nRow > m_nKnownCount;
891 }
892
893
894 //virtual
895 void SAL_CALL CachedContentResultSet
impl_initPropertySetInfo()896 ::impl_initPropertySetInfo()
897 {
898 ContentResultSetWrapper::impl_initPropertySetInfo();
899
900 osl::Guard< osl::Mutex > aGuard( m_aMutex );
901 if( m_pMyPropSetInfo )
902 return;
903 m_pMyPropSetInfo = new CCRS_PropertySetInfo( m_xPropertySetInfo );
904 m_xMyPropertySetInfo = m_pMyPropSetInfo;
905 m_xPropertySetInfo = m_xMyPropertySetInfo;
906 }
907
908 //--------------------------------------------------------------------------
909 // XInterface methods. ( inherited )
910 //--------------------------------------------------------------------------
XINTERFACE_COMMON_IMPL(CachedContentResultSet)911 XINTERFACE_COMMON_IMPL( CachedContentResultSet )
912
913 Any SAL_CALL CachedContentResultSet
914 ::queryInterface( const Type& rType )
915 {
916 //list all interfaces inclusive baseclasses of interfaces
917
918 Any aRet = ContentResultSetWrapper::queryInterface( rType );
919 if( aRet.hasValue() )
920 return aRet;
921
922 aRet = cppu::queryInterface( rType,
923 static_cast< XTypeProvider* >( this ),
924 static_cast< XServiceInfo* >( this ) );
925
926 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
927 }
928
929 //--------------------------------------------------------------------------
930 // XTypeProvider methods.
931 //--------------------------------------------------------------------------
932 //list all interfaces exclusive baseclasses
933 XTYPEPROVIDER_IMPL_11( CachedContentResultSet
934 , XTypeProvider
935 , XServiceInfo
936 , XComponent
937 , XCloseable
938 , XResultSetMetaDataSupplier
939 , XPropertySet
940
941 , XPropertyChangeListener
942 , XVetoableChangeListener
943
944 , XContentAccess
945
946 , XResultSet
947 , XRow );
948
949 //--------------------------------------------------------------------------
950 // XServiceInfo methods.
951 //--------------------------------------------------------------------------
952
953 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet,
954 OUString::createFromAscii(
955 "com.sun.star.comp.ucb.CachedContentResultSet" ),
956 OUString::createFromAscii(
957 CACHED_CONTENT_RESULTSET_SERVICE_NAME ) );
958
959 //--------------------------------------------------------------------------
960 // XPropertySet methods. ( inherited )
961 //--------------------------------------------------------------------------
962
963 // virtual
964 void SAL_CALL CachedContentResultSet
setPropertyValue(const OUString & aPropertyName,const Any & aValue)965 ::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
966 {
967 impl_EnsureNotDisposed();
968
969 if( !getPropertySetInfo().is() )
970 {
971 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
972 throw UnknownPropertyException();
973 }
974
975 Property aProp = m_pMyPropSetInfo->getPropertyByName( aPropertyName );
976 //throws UnknownPropertyException, if so
977
978 if( aProp.Attributes & PropertyAttribute::READONLY )
979 {
980 //It is assumed, that the properties
981 //'RowCount' and 'IsRowCountFinal' are readonly!
982 throw IllegalArgumentException();
983 }
984 if( aProp.Name == CCRS_PropertySetInfo
985 ::m_aPropertyNameForFetchDirection )
986 {
987 //check value
988 sal_Int32 nNew;
989 if( !( aValue >>= nNew ) )
990 {
991 throw IllegalArgumentException();
992 }
993
994 if( nNew == FetchDirection::UNKNOWN )
995 {
996 nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION;
997 }
998 else if( !( nNew == FetchDirection::FORWARD
999 || nNew == FetchDirection::REVERSE ) )
1000 {
1001 throw IllegalArgumentException();
1002 }
1003
1004 //create PropertyChangeEvent and set value
1005 PropertyChangeEvent aEvt;
1006 {
1007 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1008 aEvt.Source = static_cast< XPropertySet * >( this );
1009 aEvt.PropertyName = aPropertyName;
1010 aEvt.Further = sal_False;
1011 aEvt.PropertyHandle = m_pMyPropSetInfo->
1012 m_nFetchDirectionPropertyHandle;
1013 aEvt.OldValue <<= m_nFetchDirection;
1014 aEvt.NewValue <<= nNew;
1015
1016 m_nFetchDirection = nNew;
1017 }
1018
1019 //send PropertyChangeEvent to listeners
1020 impl_notifyPropertyChangeListeners( aEvt );
1021 }
1022 else if( aProp.Name == CCRS_PropertySetInfo
1023 ::m_aPropertyNameForFetchSize )
1024 {
1025 //check value
1026 sal_Int32 nNew;
1027 if( !( aValue >>= nNew ) )
1028 {
1029 throw IllegalArgumentException();
1030 }
1031
1032 if( nNew < 0 )
1033 {
1034 nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE;
1035 }
1036
1037 //create PropertyChangeEvent and set value
1038 PropertyChangeEvent aEvt;
1039 {
1040 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1041 aEvt.Source = static_cast< XPropertySet * >( this );
1042 aEvt.PropertyName = aPropertyName;
1043 aEvt.Further = sal_False;
1044 aEvt.PropertyHandle = m_pMyPropSetInfo->
1045 m_nFetchSizePropertyHandle;
1046 aEvt.OldValue <<= m_nFetchSize;
1047 aEvt.NewValue <<= nNew;
1048
1049 m_nFetchSize = nNew;
1050 }
1051
1052 //send PropertyChangeEvent to listeners
1053 impl_notifyPropertyChangeListeners( aEvt );
1054 }
1055 else
1056 {
1057 impl_init_xPropertySetOrigin();
1058 {
1059 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1060 if( !m_xPropertySetOrigin.is() )
1061 {
1062 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1063 return;
1064 }
1065 }
1066 m_xPropertySetOrigin->setPropertyValue( aPropertyName, aValue );
1067 }
1068 }
1069
1070 //--------------------------------------------------------------------------
1071 // virtual
1072 Any SAL_CALL CachedContentResultSet
getPropertyValue(const OUString & rPropertyName)1073 ::getPropertyValue( const OUString& rPropertyName )
1074 {
1075 impl_EnsureNotDisposed();
1076
1077 if( !getPropertySetInfo().is() )
1078 {
1079 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1080 throw UnknownPropertyException();
1081 }
1082
1083 Property aProp = m_pMyPropSetInfo->getPropertyByName( rPropertyName );
1084 //throws UnknownPropertyException, if so
1085
1086 Any aValue;
1087 if( rPropertyName == CCRS_PropertySetInfo
1088 ::m_aPropertyNameForCount )
1089 {
1090 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1091 aValue <<= m_nKnownCount;
1092 }
1093 else if( rPropertyName == CCRS_PropertySetInfo
1094 ::m_aPropertyNameForFinalCount )
1095 {
1096 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1097 aValue <<= m_bFinalCount;
1098 }
1099 else if( rPropertyName == CCRS_PropertySetInfo
1100 ::m_aPropertyNameForFetchSize )
1101 {
1102 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1103 aValue <<= m_nFetchSize;
1104 }
1105 else if( rPropertyName == CCRS_PropertySetInfo
1106 ::m_aPropertyNameForFetchDirection )
1107 {
1108 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1109 aValue <<= m_nFetchDirection;
1110 }
1111 else
1112 {
1113 impl_init_xPropertySetOrigin();
1114 {
1115 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1116 if( !m_xPropertySetOrigin.is() )
1117 {
1118 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1119 throw UnknownPropertyException();
1120 }
1121 }
1122 aValue = m_xPropertySetOrigin->getPropertyValue( rPropertyName );
1123 }
1124 return aValue;
1125 }
1126
1127 //--------------------------------------------------------------------------
1128 // own methods. ( inherited )
1129 //--------------------------------------------------------------------------
1130
1131 //virtual
1132 void SAL_CALL CachedContentResultSet
impl_disposing(const EventObject & rEventObject)1133 ::impl_disposing( const EventObject& rEventObject )
1134 {
1135 {
1136 impl_EnsureNotDisposed();
1137 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1138 //release all references to the broadcaster:
1139 m_xFetchProvider.clear();
1140 m_xFetchProviderForContentAccess.clear();
1141 }
1142 ContentResultSetWrapper::impl_disposing( rEventObject );
1143 }
1144
1145 //virtual
1146 void SAL_CALL CachedContentResultSet
impl_propertyChange(const PropertyChangeEvent & rEvt)1147 ::impl_propertyChange( const PropertyChangeEvent& rEvt )
1148 {
1149 impl_EnsureNotDisposed();
1150
1151 PropertyChangeEvent aEvt( rEvt );
1152 aEvt.Source = static_cast< XPropertySet * >( this );
1153 aEvt.Further = sal_False;
1154 //---------
1155
1156 if( CCRS_PropertySetInfo
1157 ::impl_isMyPropertyName( rEvt.PropertyName ) )
1158 {
1159 //don't notify foreign events on fetchsize and fetchdirection
1160 if( aEvt.PropertyName == CCRS_PropertySetInfo
1161 ::m_aPropertyNameForFetchSize
1162 || aEvt.PropertyName == CCRS_PropertySetInfo
1163 ::m_aPropertyNameForFetchDirection )
1164 return;
1165
1166 //adjust my props 'RowCount' and 'IsRowCountFinal'
1167 if( aEvt.PropertyName == CCRS_PropertySetInfo
1168 ::m_aPropertyNameForCount )
1169 {//RowCount changed
1170
1171 //check value
1172 sal_Int32 nNew = 0;
1173 if( !( aEvt.NewValue >>= nNew ) )
1174 {
1175 OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" );
1176 return;
1177 }
1178
1179 impl_changeRowCount( m_nKnownCount, nNew );
1180 }
1181 else if( aEvt.PropertyName == CCRS_PropertySetInfo
1182 ::m_aPropertyNameForFinalCount )
1183 {//IsRowCountFinal changed
1184
1185 //check value
1186 sal_Bool bNew = sal_False;
1187 if( !( aEvt.NewValue >>= bNew ) )
1188 {
1189 OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" );
1190 return;
1191 }
1192 impl_changeIsRowCountFinal( m_bFinalCount, bNew );
1193 }
1194 return;
1195 }
1196
1197 //-----------
1198 impl_notifyPropertyChangeListeners( aEvt );
1199 }
1200
1201
1202 //virtual
1203 void SAL_CALL CachedContentResultSet
impl_vetoableChange(const PropertyChangeEvent & rEvt)1204 ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
1205 {
1206 impl_EnsureNotDisposed();
1207
1208 //don't notify events on my properties, cause they are not vetoable
1209 if( CCRS_PropertySetInfo
1210 ::impl_isMyPropertyName( rEvt.PropertyName ) )
1211 {
1212 return;
1213 }
1214
1215
1216 PropertyChangeEvent aEvt( rEvt );
1217 aEvt.Source = static_cast< XPropertySet * >( this );
1218 aEvt.Further = sal_False;
1219
1220 impl_notifyVetoableChangeListeners( aEvt );
1221 }
1222
1223 //--------------------------------------------------------------------------
1224 // XContentAccess methods. ( inherited ) ( -- position dependent )
1225 //--------------------------------------------------------------------------
1226
1227 #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1228 impl_EnsureNotDisposed(); \
1229 ReacquireableGuard aGuard( m_aMutex ); \
1230 sal_Int32 nRow = m_nRow; \
1231 sal_Int32 nFetchSize = m_nFetchSize; \
1232 sal_Int32 nFetchDirection = m_nFetchDirection; \
1233 if( !m_aCache##XXX.hasRow( nRow ) ) \
1234 { \
1235 if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1236 { \
1237 if( !m_xFetchProviderForContentAccess.is() ) \
1238 { \
1239 OSL_ENSURE( sal_False, "broadcaster was disposed already" );\
1240 throw RuntimeException(); \
1241 } \
1242 aGuard.clear(); \
1243 if( impl_isForwardOnly() ) \
1244 applyPositionToOrigin( nRow ); \
1245 \
1246 FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1247 } \
1248 aGuard.reacquire(); \
1249 if( !m_aCache##XXX.hasRow( nRow ) ) \
1250 { \
1251 aGuard.clear(); \
1252 applyPositionToOrigin( nRow ); \
1253 TYPE aRet = ContentResultSetWrapper::queryXXX(); \
1254 if( m_xContentIdentifierMapping.is() ) \
1255 return m_xContentIdentifierMapping->map##XXX( aRet );\
1256 return aRet; \
1257 } \
1258 } \
1259 return m_aCache##XXX.get##XXX( nRow );
1260
1261 //--------------------------------------------------------------------------
1262 // virtual
1263 OUString SAL_CALL CachedContentResultSet
queryContentIdentifierString()1264 ::queryContentIdentifierString()
1265 {
1266 XCONTENTACCESS_queryXXX( queryContentIdentifierString, ContentIdentifierString, OUString )
1267 }
1268
1269 //--------------------------------------------------------------------------
1270 // virtual
1271 Reference< XContentIdentifier > SAL_CALL CachedContentResultSet
queryContentIdentifier()1272 ::queryContentIdentifier()
1273 {
1274 XCONTENTACCESS_queryXXX( queryContentIdentifier, ContentIdentifier, Reference< XContentIdentifier > )
1275 }
1276
1277 //--------------------------------------------------------------------------
1278 // virtual
1279 Reference< XContent > SAL_CALL CachedContentResultSet
queryContent()1280 ::queryContent()
1281 {
1282 XCONTENTACCESS_queryXXX( queryContent, Content, Reference< XContent > )
1283 }
1284
1285 //-----------------------------------------------------------------
1286 // XResultSet methods. ( inherited )
1287 //-----------------------------------------------------------------
1288 //virtual
1289
1290 sal_Bool SAL_CALL CachedContentResultSet
next()1291 ::next()
1292 {
1293 impl_EnsureNotDisposed();
1294
1295 ReacquireableGuard aGuard( m_aMutex );
1296 //after last
1297 if( m_bAfterLast )
1298 return sal_False;
1299 //last
1300 aGuard.clear();
1301 if( isLast() )
1302 {
1303 aGuard.reacquire();
1304 m_nRow++;
1305 m_bAfterLast = sal_True;
1306 return sal_False;
1307 }
1308 aGuard.reacquire();
1309 //known valid position
1310 if( impl_isKnownValidPosition( m_nRow + 1 ) )
1311 {
1312 m_nRow++;
1313 return sal_True;
1314 }
1315
1316 //unknown position
1317 sal_Int32 nRow = m_nRow;
1318 aGuard.clear();
1319
1320 sal_Bool bValid = applyPositionToOrigin( nRow + 1 );
1321
1322 aGuard.reacquire();
1323 m_nRow = nRow + 1;
1324 m_bAfterLast = !bValid;
1325 return bValid;
1326 }
1327
1328 //virtual
1329 sal_Bool SAL_CALL CachedContentResultSet
previous()1330 ::previous()
1331 {
1332 impl_EnsureNotDisposed();
1333
1334 if( impl_isForwardOnly() )
1335 throw SQLException();
1336
1337 ReacquireableGuard aGuard( m_aMutex );
1338 //before first ?:
1339 if( !m_bAfterLast && !m_nRow )
1340 return sal_False;
1341 //first ?:
1342 if( !m_bAfterLast && m_nKnownCount && m_nRow == 1 )
1343 {
1344 m_nRow--;
1345 m_bAfterLast = sal_False;
1346 return sal_False;
1347 }
1348 //known valid position ?:
1349 if( impl_isKnownValidPosition( m_nRow - 1 ) )
1350 {
1351 m_nRow--;
1352 m_bAfterLast = sal_False;
1353 return sal_True;
1354 }
1355 //unknown position:
1356 sal_Int32 nRow = m_nRow;
1357 aGuard.clear();
1358
1359 sal_Bool bValid = applyPositionToOrigin( nRow - 1 );
1360
1361 aGuard.reacquire();
1362 m_nRow = nRow - 1;
1363 m_bAfterLast = sal_False;
1364 return bValid;
1365 }
1366
1367 //virtual
1368 sal_Bool SAL_CALL CachedContentResultSet
absolute(sal_Int32 row)1369 ::absolute( sal_Int32 row )
1370 {
1371 impl_EnsureNotDisposed();
1372
1373 if( !row )
1374 throw SQLException();
1375
1376 if( impl_isForwardOnly() )
1377 throw SQLException();
1378
1379 ReacquireableGuard aGuard( m_aMutex );
1380
1381 if( !m_xResultSetOrigin.is() )
1382 {
1383 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1384 return sal_False;
1385 }
1386 if( row < 0 )
1387 {
1388 if( m_bFinalCount )
1389 {
1390 sal_Int32 nNewRow = m_nKnownCount + 1 + row;
1391 sal_Bool bValid = sal_True;
1392 if( nNewRow <= 0 )
1393 {
1394 nNewRow = 0;
1395 bValid = sal_False;
1396 }
1397 m_nRow = nNewRow;
1398 m_bAfterLast = sal_False;
1399 return bValid;
1400 }
1401 //unknown final count:
1402 aGuard.clear();
1403
1404 // Solaris has problems catching or propagating derived exceptions
1405 // when only the base class is known, so make ResultSetException
1406 // (derived from SQLException) known here:
1407 sal_Bool bValid;
1408 try
1409 {
1410 bValid = m_xResultSetOrigin->absolute( row );
1411 }
1412 catch (ResultSetException &)
1413 {
1414 throw;
1415 }
1416
1417 aGuard.reacquire();
1418 if( m_bFinalCount )
1419 {
1420 sal_Int32 nNewRow = m_nKnownCount + 1 + row;
1421 if( nNewRow < 0 )
1422 nNewRow = 0;
1423 m_nLastAppliedPos = nNewRow;
1424 m_nRow = nNewRow;
1425 m_bAfterLastApplied = m_bAfterLast = sal_False;
1426 return bValid;
1427 }
1428 aGuard.clear();
1429
1430 sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
1431
1432 aGuard.reacquire();
1433 m_nLastAppliedPos = nCurRow;
1434 m_nRow = nCurRow;
1435 m_bAfterLast = sal_False;
1436 return nCurRow != 0;
1437 }
1438 //row > 0:
1439 if( m_bFinalCount )
1440 {
1441 if( row > m_nKnownCount )
1442 {
1443 m_nRow = m_nKnownCount + 1;
1444 m_bAfterLast = sal_True;
1445 return sal_False;
1446 }
1447 m_nRow = row;
1448 m_bAfterLast = sal_False;
1449 return sal_True;
1450 }
1451 //unknown new position:
1452 aGuard.clear();
1453
1454 sal_Bool bValid = m_xResultSetOrigin->absolute( row );
1455
1456 aGuard.reacquire();
1457 if( m_bFinalCount )
1458 {
1459 sal_Int32 nNewRow = row;
1460 if( nNewRow > m_nKnownCount )
1461 {
1462 nNewRow = m_nKnownCount + 1;
1463 m_bAfterLastApplied = m_bAfterLast = sal_True;
1464 }
1465 else
1466 m_bAfterLastApplied = m_bAfterLast = sal_False;
1467
1468 m_nLastAppliedPos = nNewRow;
1469 m_nRow = nNewRow;
1470 return bValid;
1471 }
1472 aGuard.clear();
1473
1474 sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
1475 sal_Bool bIsAfterLast = m_xResultSetOrigin->isAfterLast();
1476
1477 aGuard.reacquire();
1478 m_nLastAppliedPos = nCurRow;
1479 m_nRow = nCurRow;
1480 m_bAfterLastApplied = m_bAfterLast = bIsAfterLast;
1481 return nCurRow && !bIsAfterLast;
1482 }
1483
1484 //virtual
1485 sal_Bool SAL_CALL CachedContentResultSet
relative(sal_Int32 rows)1486 ::relative( sal_Int32 rows )
1487 {
1488 impl_EnsureNotDisposed();
1489
1490 if( impl_isForwardOnly() )
1491 throw SQLException();
1492
1493 ReacquireableGuard aGuard( m_aMutex );
1494 if( m_bAfterLast || impl_isKnownInvalidPosition( m_nRow ) )
1495 throw SQLException();
1496
1497 if( !rows )
1498 return sal_True;
1499
1500 sal_Int32 nNewRow = m_nRow + rows;
1501 if( nNewRow < 0 )
1502 nNewRow = 0;
1503
1504 if( impl_isKnownValidPosition( nNewRow ) )
1505 {
1506 m_nRow = nNewRow;
1507 m_bAfterLast = sal_False;
1508 return sal_True;
1509 }
1510 else
1511 {
1512 //known invalid new position:
1513 if( nNewRow == 0 )
1514 {
1515 m_bAfterLast = sal_False;
1516 m_nRow = 0;
1517 return sal_False;
1518 }
1519 if( m_bFinalCount && nNewRow > m_nKnownCount )
1520 {
1521 m_bAfterLast = sal_True;
1522 m_nRow = m_nKnownCount + 1;
1523 return sal_False;
1524 }
1525 //unknown new position:
1526 aGuard.clear();
1527 sal_Bool bValid = applyPositionToOrigin( nNewRow );
1528
1529 aGuard.reacquire();
1530 m_nRow = nNewRow;
1531 m_bAfterLast = !bValid && nNewRow > 0;
1532 return bValid;
1533 }
1534 }
1535
1536
1537 //virtual
1538 sal_Bool SAL_CALL CachedContentResultSet
first()1539 ::first()
1540 {
1541 impl_EnsureNotDisposed();
1542
1543 if( impl_isForwardOnly() )
1544 throw SQLException();
1545
1546 ReacquireableGuard aGuard( m_aMutex );
1547 if( impl_isKnownValidPosition( 1 ) )
1548 {
1549 m_nRow = 1;
1550 m_bAfterLast = sal_False;
1551 return sal_True;
1552 }
1553 if( impl_isKnownInvalidPosition( 1 ) )
1554 {
1555 m_nRow = 1;
1556 m_bAfterLast = sal_False;
1557 return sal_False;
1558 }
1559 //unknown position
1560 aGuard.clear();
1561
1562 sal_Bool bValid = applyPositionToOrigin( 1 );
1563
1564 aGuard.reacquire();
1565 m_nRow = 1;
1566 m_bAfterLast = sal_False;
1567 return bValid;
1568 }
1569
1570 //virtual
1571 sal_Bool SAL_CALL CachedContentResultSet
last()1572 ::last()
1573 {
1574 impl_EnsureNotDisposed();
1575
1576 if( impl_isForwardOnly() )
1577 throw SQLException();
1578
1579 ReacquireableGuard aGuard( m_aMutex );
1580 if( m_bFinalCount )
1581 {
1582 m_nRow = m_nKnownCount;
1583 m_bAfterLast = sal_False;
1584 return m_nKnownCount != 0;
1585 }
1586 //unknown position
1587 if( !m_xResultSetOrigin.is() )
1588 {
1589 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1590 return sal_False;
1591 }
1592 aGuard.clear();
1593
1594 sal_Bool bValid = m_xResultSetOrigin->last();
1595
1596 aGuard.reacquire();
1597 m_bAfterLastApplied = m_bAfterLast = sal_False;
1598 if( m_bFinalCount )
1599 {
1600 m_nLastAppliedPos = m_nKnownCount;
1601 m_nRow = m_nKnownCount;
1602 return bValid;
1603 }
1604 aGuard.clear();
1605
1606 sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
1607
1608 aGuard.reacquire();
1609 m_nLastAppliedPos = nCurRow;
1610 m_nRow = nCurRow;
1611 OSL_ENSURE( nCurRow >= m_nKnownCount, "position of last row < known Count, that could not be" );
1612 m_nKnownCount = nCurRow;
1613 m_bFinalCount = sal_True;
1614 return nCurRow != 0;
1615 }
1616
1617 //virtual
1618 void SAL_CALL CachedContentResultSet
beforeFirst()1619 ::beforeFirst()
1620 {
1621 impl_EnsureNotDisposed();
1622
1623 if( impl_isForwardOnly() )
1624 throw SQLException();
1625
1626 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1627 m_nRow = 0;
1628 m_bAfterLast = sal_False;
1629 }
1630
1631 //virtual
1632 void SAL_CALL CachedContentResultSet
afterLast()1633 ::afterLast()
1634 {
1635 impl_EnsureNotDisposed();
1636
1637 if( impl_isForwardOnly() )
1638 throw SQLException();
1639
1640 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1641 m_nRow = 1;
1642 m_bAfterLast = sal_True;
1643 }
1644
1645 //virtual
1646 sal_Bool SAL_CALL CachedContentResultSet
isAfterLast()1647 ::isAfterLast()
1648 {
1649 impl_EnsureNotDisposed();
1650
1651 ReacquireableGuard aGuard( m_aMutex );
1652 if( !m_bAfterLast )
1653 return sal_False;
1654 if( m_nKnownCount )
1655 return m_bAfterLast;
1656 if( m_bFinalCount )
1657 return sal_False;
1658
1659 if( !m_xResultSetOrigin.is() )
1660 {
1661 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1662 return sal_False;
1663 }
1664 aGuard.clear();
1665
1666 //find out whether the original resultset contains rows or not
1667 m_xResultSetOrigin->afterLast();
1668
1669 aGuard.reacquire();
1670 m_bAfterLastApplied = sal_True;
1671 aGuard.clear();
1672
1673 return m_xResultSetOrigin->isAfterLast();
1674 }
1675
1676 //virtual
1677 sal_Bool SAL_CALL CachedContentResultSet
isBeforeFirst()1678 ::isBeforeFirst()
1679 {
1680 impl_EnsureNotDisposed();
1681
1682 ReacquireableGuard aGuard( m_aMutex );
1683 if( m_bAfterLast )
1684 return sal_False;
1685 if( m_nRow )
1686 return sal_False;
1687 if( m_nKnownCount )
1688 return !m_nRow;
1689 if( m_bFinalCount )
1690 return sal_False;
1691
1692 if( !m_xResultSetOrigin.is() )
1693 {
1694 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1695 return sal_False;
1696 }
1697 aGuard.clear();
1698
1699 //find out whether the original resultset contains rows or not
1700 m_xResultSetOrigin->beforeFirst();
1701
1702 aGuard.reacquire();
1703 m_bAfterLastApplied = sal_False;
1704 m_nLastAppliedPos = 0;
1705 aGuard.clear();
1706
1707 return m_xResultSetOrigin->isBeforeFirst();
1708 }
1709
1710 //virtual
1711 sal_Bool SAL_CALL CachedContentResultSet
isFirst()1712 ::isFirst()
1713 {
1714 impl_EnsureNotDisposed();
1715
1716 sal_Int32 nRow = 0;
1717 Reference< XResultSet > xResultSetOrigin;
1718
1719 {
1720 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1721 if( m_bAfterLast )
1722 return sal_False;
1723 if( m_nRow != 1 )
1724 return sal_False;
1725 if( m_nKnownCount )
1726 return m_nRow == 1;
1727 if( m_bFinalCount )
1728 return sal_False;
1729
1730 nRow = m_nRow;
1731 xResultSetOrigin = m_xResultSetOrigin;
1732 }
1733
1734 //need to ask origin
1735 {
1736 if( applyPositionToOrigin( nRow ) )
1737 return xResultSetOrigin->isFirst();
1738 else
1739 return sal_False;
1740 }
1741 }
1742
1743 //virtual
1744 sal_Bool SAL_CALL CachedContentResultSet
isLast()1745 ::isLast()
1746 {
1747 impl_EnsureNotDisposed();
1748
1749 sal_Int32 nRow = 0;
1750 Reference< XResultSet > xResultSetOrigin;
1751 {
1752 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1753 if( m_bAfterLast )
1754 return sal_False;
1755 if( m_nRow < m_nKnownCount )
1756 return sal_False;
1757 if( m_bFinalCount )
1758 return m_nKnownCount && m_nRow == m_nKnownCount;
1759
1760 nRow = m_nRow;
1761 xResultSetOrigin = m_xResultSetOrigin;
1762 }
1763
1764 //need to ask origin
1765 {
1766 if( applyPositionToOrigin( nRow ) )
1767 return xResultSetOrigin->isLast();
1768 else
1769 return sal_False;
1770 }
1771 }
1772
1773
1774 //virtual
1775 sal_Int32 SAL_CALL CachedContentResultSet
getRow()1776 ::getRow()
1777 {
1778 impl_EnsureNotDisposed();
1779
1780 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1781 if( m_bAfterLast )
1782 return 0;
1783 return m_nRow;
1784 }
1785
1786 //virtual
1787 void SAL_CALL CachedContentResultSet
refreshRow()1788 ::refreshRow()
1789 {
1790 impl_EnsureNotDisposed();
1791
1792 //the ContentResultSet is static and will not change
1793 //therefore we don't need to reload anything
1794 }
1795
1796 //virtual
1797 sal_Bool SAL_CALL CachedContentResultSet
rowUpdated()1798 ::rowUpdated()
1799 {
1800 impl_EnsureNotDisposed();
1801
1802 //the ContentResultSet is static and will not change
1803 return sal_False;
1804 }
1805 //virtual
1806 sal_Bool SAL_CALL CachedContentResultSet
rowInserted()1807 ::rowInserted()
1808 {
1809 impl_EnsureNotDisposed();
1810
1811 //the ContentResultSet is static and will not change
1812 return sal_False;
1813 }
1814
1815 //virtual
1816 sal_Bool SAL_CALL CachedContentResultSet
rowDeleted()1817 ::rowDeleted()
1818 {
1819 impl_EnsureNotDisposed();
1820
1821 //the ContentResultSet is static and will not change
1822 return sal_False;
1823 }
1824
1825 //virtual
1826 Reference< XInterface > SAL_CALL CachedContentResultSet
getStatement()1827 ::getStatement()
1828 {
1829 impl_EnsureNotDisposed();
1830 //@todo ?return anything
1831 return Reference< XInterface >();
1832 }
1833
1834 //-----------------------------------------------------------------
1835 // XRow methods. ( inherited )
1836 //-----------------------------------------------------------------
1837
1838 //virtual
1839 sal_Bool SAL_CALL CachedContentResultSet
wasNull()1840 ::wasNull()
1841 {
1842 impl_EnsureNotDisposed();
1843 impl_init_xRowOrigin();
1844 {
1845 osl::Guard< osl::Mutex > aGuard( m_aMutex );
1846 if( m_bLastReadWasFromCache )
1847 return m_bLastCachedReadWasNull;
1848 if( !m_xRowOrigin.is() )
1849 {
1850 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1851 return sal_False;
1852 }
1853 }
1854 return m_xRowOrigin->wasNull();
1855 }
1856
1857 //virtual
1858 rtl::OUString SAL_CALL CachedContentResultSet
getString(sal_Int32 columnIndex)1859 ::getString( sal_Int32 columnIndex )
1860 {
1861 XROW_GETXXX( getString, OUString );
1862 }
1863
1864 //virtual
1865 sal_Bool SAL_CALL CachedContentResultSet
getBoolean(sal_Int32 columnIndex)1866 ::getBoolean( sal_Int32 columnIndex )
1867 {
1868 XROW_GETXXX( getBoolean, sal_Bool );
1869 }
1870
1871 //virtual
1872 sal_Int8 SAL_CALL CachedContentResultSet
getByte(sal_Int32 columnIndex)1873 ::getByte( sal_Int32 columnIndex )
1874 {
1875 XROW_GETXXX( getByte, sal_Int8 );
1876 }
1877
1878 //virtual
1879 sal_Int16 SAL_CALL CachedContentResultSet
getShort(sal_Int32 columnIndex)1880 ::getShort( sal_Int32 columnIndex )
1881 {
1882 XROW_GETXXX( getShort, sal_Int16 );
1883 }
1884
1885 //virtual
1886 sal_Int32 SAL_CALL CachedContentResultSet
getInt(sal_Int32 columnIndex)1887 ::getInt( sal_Int32 columnIndex )
1888 {
1889 XROW_GETXXX( getInt, sal_Int32 );
1890 }
1891
1892 //virtual
1893 sal_Int64 SAL_CALL CachedContentResultSet
getLong(sal_Int32 columnIndex)1894 ::getLong( sal_Int32 columnIndex )
1895 {
1896 XROW_GETXXX( getLong, sal_Int64 );
1897 }
1898
1899 //virtual
1900 float SAL_CALL CachedContentResultSet
getFloat(sal_Int32 columnIndex)1901 ::getFloat( sal_Int32 columnIndex )
1902 {
1903 XROW_GETXXX( getFloat, float );
1904 }
1905
1906 //virtual
1907 double SAL_CALL CachedContentResultSet
getDouble(sal_Int32 columnIndex)1908 ::getDouble( sal_Int32 columnIndex )
1909 {
1910 XROW_GETXXX( getDouble, double );
1911 }
1912
1913 //virtual
1914 Sequence< sal_Int8 > SAL_CALL CachedContentResultSet
getBytes(sal_Int32 columnIndex)1915 ::getBytes( sal_Int32 columnIndex )
1916 {
1917 XROW_GETXXX( getBytes, Sequence< sal_Int8 > );
1918 }
1919
1920 //virtual
1921 Date SAL_CALL CachedContentResultSet
getDate(sal_Int32 columnIndex)1922 ::getDate( sal_Int32 columnIndex )
1923 {
1924 XROW_GETXXX( getDate, Date );
1925 }
1926
1927 //virtual
1928 Time SAL_CALL CachedContentResultSet
getTime(sal_Int32 columnIndex)1929 ::getTime( sal_Int32 columnIndex )
1930 {
1931 XROW_GETXXX( getTime, Time );
1932 }
1933
1934 //virtual
1935 DateTime SAL_CALL CachedContentResultSet
getTimestamp(sal_Int32 columnIndex)1936 ::getTimestamp( sal_Int32 columnIndex )
1937 {
1938 XROW_GETXXX( getTimestamp, DateTime );
1939 }
1940
1941 //virtual
1942 Reference< com::sun::star::io::XInputStream >
1943 SAL_CALL CachedContentResultSet
getBinaryStream(sal_Int32 columnIndex)1944 ::getBinaryStream( sal_Int32 columnIndex )
1945 {
1946 XROW_GETXXX( getBinaryStream, Reference< com::sun::star::io::XInputStream > );
1947 }
1948
1949 //virtual
1950 Reference< com::sun::star::io::XInputStream >
1951 SAL_CALL CachedContentResultSet
getCharacterStream(sal_Int32 columnIndex)1952 ::getCharacterStream( sal_Int32 columnIndex )
1953 {
1954 XROW_GETXXX( getCharacterStream, Reference< com::sun::star::io::XInputStream > );
1955 }
1956
1957 //virtual
1958 Any SAL_CALL CachedContentResultSet
getObject(sal_Int32 columnIndex,const Reference<com::sun::star::container::XNameAccess> & typeMap)1959 ::getObject( sal_Int32 columnIndex,
1960 const Reference<
1961 com::sun::star::container::XNameAccess >& typeMap )
1962 {
1963 //if you change this macro please pay attention to
1964 //define XROW_GETXXX, where this is similar implemented
1965
1966 ReacquireableGuard aGuard( m_aMutex );
1967 sal_Int32 nRow = m_nRow;
1968 sal_Int32 nFetchSize = m_nFetchSize;
1969 sal_Int32 nFetchDirection = m_nFetchDirection;
1970 if( !m_aCache.hasRow( nRow ) )
1971 {
1972 if( !m_aCache.hasCausedException( nRow ) )
1973 {
1974 if( !m_xFetchProvider.is() )
1975 {
1976 OSL_ENSURE( sal_False, "broadcaster was disposed already" );
1977 return Any();
1978 }
1979 aGuard.clear();
1980
1981 impl_fetchData( nRow, nFetchSize, nFetchDirection );
1982 }
1983 aGuard.reacquire();
1984 if( !m_aCache.hasRow( nRow ) )
1985 {
1986 m_bLastReadWasFromCache = sal_False;
1987 aGuard.clear();
1988 applyPositionToOrigin( nRow );
1989 impl_init_xRowOrigin();
1990 return m_xRowOrigin->getObject( columnIndex, typeMap );
1991 }
1992 }
1993 //@todo: pay attention to typeMap
1994 const Any& rValue = m_aCache.getAny( nRow, columnIndex );
1995 Any aRet;
1996 m_bLastReadWasFromCache = sal_True;
1997 m_bLastCachedReadWasNull = !( rValue >>= aRet );
1998 return aRet;
1999 }
2000
2001 //virtual
2002 Reference< XRef > SAL_CALL CachedContentResultSet
getRef(sal_Int32 columnIndex)2003 ::getRef( sal_Int32 columnIndex )
2004 {
2005 XROW_GETXXX( getRef, Reference< XRef > );
2006 }
2007
2008 //virtual
2009 Reference< XBlob > SAL_CALL CachedContentResultSet
getBlob(sal_Int32 columnIndex)2010 ::getBlob( sal_Int32 columnIndex )
2011 {
2012 XROW_GETXXX( getBlob, Reference< XBlob > );
2013 }
2014
2015 //virtual
2016 Reference< XClob > SAL_CALL CachedContentResultSet
getClob(sal_Int32 columnIndex)2017 ::getClob( sal_Int32 columnIndex )
2018 {
2019 XROW_GETXXX( getClob, Reference< XClob > );
2020 }
2021
2022 //virtual
2023 Reference< XArray > SAL_CALL CachedContentResultSet
getArray(sal_Int32 columnIndex)2024 ::getArray( sal_Int32 columnIndex )
2025 {
2026 XROW_GETXXX( getArray, Reference< XArray > );
2027 }
2028
2029 //-----------------------------------------------------------------
2030 // Type Converter Support
2031 //-----------------------------------------------------------------
2032
getTypeConverter()2033 const Reference< XTypeConverter >& CachedContentResultSet::getTypeConverter()
2034 {
2035 osl::Guard< osl::Mutex > aGuard( m_aMutex );
2036
2037 if ( !m_bTriedToGetTypeConverter && !m_xTypeConverter.is() )
2038 {
2039 m_bTriedToGetTypeConverter = sal_True;
2040 m_xTypeConverter = Reference< XTypeConverter >(
2041 m_xSMgr->createInstance(
2042 OUString::createFromAscii(
2043 "com.sun.star.script.Converter" ) ),
2044 UNO_QUERY );
2045
2046 OSL_ENSURE( m_xTypeConverter.is(),
2047 "PropertyValueSet::getTypeConverter() - "
2048 "Service 'com.sun.star.script.Converter' n/a!" );
2049 }
2050 return m_xTypeConverter;
2051 }
2052
2053 //--------------------------------------------------------------------------
2054 //--------------------------------------------------------------------------
2055 // class CachedContentResultSetFactory
2056 //--------------------------------------------------------------------------
2057 //--------------------------------------------------------------------------
2058
CachedContentResultSetFactory(const Reference<XMultiServiceFactory> & rSMgr)2059 CachedContentResultSetFactory::CachedContentResultSetFactory(
2060 const Reference< XMultiServiceFactory > & rSMgr )
2061 {
2062 m_xSMgr = rSMgr;
2063 }
2064
~CachedContentResultSetFactory()2065 CachedContentResultSetFactory::~CachedContentResultSetFactory()
2066 {
2067 }
2068
2069 //--------------------------------------------------------------------------
2070 // CachedContentResultSetFactory XInterface methods.
2071 //--------------------------------------------------------------------------
2072
2073 XINTERFACE_IMPL_3( CachedContentResultSetFactory,
2074 XTypeProvider,
2075 XServiceInfo,
2076 XCachedContentResultSetFactory );
2077
2078 //--------------------------------------------------------------------------
2079 // CachedContentResultSetFactory XTypeProvider methods.
2080 //--------------------------------------------------------------------------
2081
2082 XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory,
2083 XTypeProvider,
2084 XServiceInfo,
2085 XCachedContentResultSetFactory );
2086
2087 //--------------------------------------------------------------------------
2088 // CachedContentResultSetFactory XServiceInfo methods.
2089 //--------------------------------------------------------------------------
2090
2091 XSERVICEINFO_IMPL_1( CachedContentResultSetFactory,
2092 OUString::createFromAscii(
2093 "com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
2094 OUString::createFromAscii(
2095 CACHED_CONTENT_RESULTSET_FACTORY_NAME ) );
2096
2097 //--------------------------------------------------------------------------
2098 // Service factory implementation.
2099 //--------------------------------------------------------------------------
2100
2101 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory );
2102
2103 //--------------------------------------------------------------------------
2104 // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2105 //--------------------------------------------------------------------------
2106
2107 //virtual
2108 Reference< XResultSet > SAL_CALL CachedContentResultSetFactory
createCachedContentResultSet(const Reference<XResultSet> & xSource,const Reference<XContentIdentifierMapping> & xMapping)2109 ::createCachedContentResultSet(
2110 const Reference< XResultSet > & xSource,
2111 const Reference< XContentIdentifierMapping > & xMapping )
2112 {
2113 Reference< XResultSet > xRet;
2114 xRet = new CachedContentResultSet( m_xSMgr, xSource, xMapping );
2115 return xRet;
2116 }
2117