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