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