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