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