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