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