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