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