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 <vector> 32 #include <sortresult.hxx> 33 #include <cppuhelper/interfacecontainer.hxx> 34 #include <com/sun/star/sdbc/DataType.hpp> 35 #include <com/sun/star/sdbc/XResultSetMetaData.hpp> 36 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> 37 #include <com/sun/star/ucb/ListActionType.hpp> 38 #include <com/sun/star/ucb/XAnyCompare.hpp> 39 #include <com/sun/star/ucb/XAnyCompareFactory.hpp> 40 #include <osl/diagnose.h> 41 42 //----------------------------------------------------------------------------- 43 using namespace com::sun::star::beans; 44 using namespace com::sun::star::container; 45 using namespace com::sun::star::io; 46 using namespace com::sun::star::lang; 47 using namespace com::sun::star::sdbc; 48 using namespace com::sun::star::ucb; 49 using namespace com::sun::star::uno; 50 using namespace com::sun::star::util; 51 using namespace cppu; 52 using namespace rtl; 53 54 //========================================================================= 55 56 // The mutex to synchronize access to containers. 57 static osl::Mutex& getContainerMutex() 58 { 59 static osl::Mutex* pMutex = NULL; 60 if( !pMutex ) 61 { 62 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 63 if( !pMutex ) 64 { 65 static osl::Mutex aMutex; 66 pMutex = &aMutex; 67 } 68 } 69 70 return *pMutex; 71 } 72 73 //========================================================================== 74 75 struct SortInfo 76 { 77 sal_Bool mbUseOwnCompare; 78 sal_Bool mbAscending; 79 sal_Bool mbCaseSensitive; 80 sal_Int32 mnColumn; 81 sal_Int32 mnType; 82 SortInfo* mpNext; 83 Reference < XAnyCompare > mxCompareFunction; 84 }; 85 86 //----------------------------------------------------------------------------- 87 88 struct SortListData 89 { 90 sal_Bool mbModified; 91 long mnCurPos; 92 long mnOldPos; 93 94 SortListData( long nPos, sal_Bool bModified = sal_False ); 95 }; 96 97 //============================================================================ 98 // 99 // class SRSPropertySetInfo. 100 // 101 //============================================================================ 102 103 class SRSPropertySetInfo : 104 public OWeakObject, 105 public XTypeProvider, 106 public XPropertySetInfo 107 { 108 Property maProps[2]; 109 110 private: 111 112 public: 113 SRSPropertySetInfo(); 114 virtual ~SRSPropertySetInfo(); 115 116 // XInterface 117 XINTERFACE_DECL() 118 119 // XTypeProvider 120 XTYPEPROVIDER_DECL() 121 122 // XPropertySetInfo 123 virtual Sequence< Property > SAL_CALL getProperties() 124 throw( RuntimeException ); 125 virtual Property SAL_CALL getPropertyByName( const OUString& aName ) 126 throw( UnknownPropertyException, RuntimeException ); 127 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) 128 throw( RuntimeException ); 129 }; 130 131 //========================================================================= 132 // 133 // PropertyChangeListenerContainer_Impl. 134 // 135 //========================================================================= 136 137 struct equalStr_Impl 138 { 139 bool operator()( const OUString& s1, const OUString& s2 ) const 140 { 141 return !!( s1 == s2 ); 142 } 143 }; 144 145 struct hashStr_Impl 146 { 147 size_t operator()( const OUString& rName ) const 148 { 149 return rName.hashCode(); 150 } 151 }; 152 153 typedef OMultiTypeInterfaceContainerHelperVar 154 < 155 OUString, 156 hashStr_Impl, 157 equalStr_Impl 158 > PropertyChangeListenerContainer_Impl; 159 160 //========================================================================= 161 // 162 // class PropertyChangeListeners_Impl 163 // 164 //========================================================================= 165 166 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl 167 { 168 public: 169 PropertyChangeListeners_Impl() 170 : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {} 171 }; 172 173 //========================================================================== 174 SortedResultSet::SortedResultSet( Reference< XResultSet > aResult ) 175 { 176 mpDisposeEventListeners = NULL; 177 mpPropChangeListeners = NULL; 178 mpVetoChangeListeners = NULL; 179 mpPropSetInfo = NULL; 180 181 mxOriginal = aResult; 182 mpSortInfo = NULL; 183 mnLastSort = 0; 184 mnCurEntry = 0; 185 mnCount = 0; 186 mbIsCopy = sal_False; 187 } 188 189 //-------------------------------------------------------------------------- 190 SortedResultSet::~SortedResultSet() 191 { 192 mxOriginal.clear(); 193 mxOther.clear(); 194 195 if ( !mbIsCopy ) 196 { 197 SortInfo *pInfo = mpSortInfo; 198 while ( pInfo ) 199 { 200 mpSortInfo = pInfo->mpNext; 201 delete pInfo; 202 pInfo = mpSortInfo; 203 } 204 } 205 206 mpSortInfo = NULL; 207 208 if ( mpPropSetInfo ) 209 mpPropSetInfo->release(); 210 211 delete mpPropChangeListeners; 212 delete mpVetoChangeListeners; 213 } 214 215 //-------------------------------------------------------------------------- 216 // XInterface methods. 217 //-------------------------------------------------------------------------- 218 219 XINTERFACE_IMPL_9( SortedResultSet, 220 XTypeProvider, 221 XServiceInfo, 222 XComponent, 223 XContentAccess, 224 XResultSet, 225 XRow, 226 XCloseable, 227 XResultSetMetaDataSupplier, 228 XPropertySet ); 229 230 //-------------------------------------------------------------------------- 231 // XTypeProvider methods. 232 //-------------------------------------------------------------------------- 233 234 XTYPEPROVIDER_IMPL_9( SortedResultSet, 235 XTypeProvider, 236 XServiceInfo, 237 XComponent, 238 XContentAccess, 239 XResultSet, 240 XRow, 241 XCloseable, 242 XResultSetMetaDataSupplier, 243 XPropertySet ); 244 245 //-------------------------------------------------------------------------- 246 // XServiceInfo methods. 247 //-------------------------------------------------------------------------- 248 249 XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet, 250 OUString::createFromAscii( 251 "com.sun.star.comp.ucb.SortedResultSet" ), 252 OUString::createFromAscii( 253 RESULTSET_SERVICE_NAME ) ); 254 255 //-------------------------------------------------------------------------- 256 // XComponent methods. 257 //-------------------------------------------------------------------------- 258 void SAL_CALL SortedResultSet::dispose() 259 throw( RuntimeException ) 260 { 261 osl::Guard< osl::Mutex > aGuard( maMutex ); 262 263 if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() ) 264 { 265 EventObject aEvt; 266 aEvt.Source = static_cast< XComponent * >( this ); 267 mpDisposeEventListeners->disposeAndClear( aEvt ); 268 } 269 270 if ( mpPropChangeListeners ) 271 { 272 EventObject aEvt; 273 aEvt.Source = static_cast< XPropertySet * >( this ); 274 mpPropChangeListeners->disposeAndClear( aEvt ); 275 } 276 277 if ( mpVetoChangeListeners ) 278 { 279 EventObject aEvt; 280 aEvt.Source = static_cast< XPropertySet * >( this ); 281 mpVetoChangeListeners->disposeAndClear( aEvt ); 282 } 283 284 mxOriginal.clear(); 285 mxOther.clear(); 286 } 287 288 //-------------------------------------------------------------------------- 289 void SAL_CALL SortedResultSet::addEventListener( 290 const Reference< XEventListener >& Listener ) 291 throw( RuntimeException ) 292 { 293 osl::Guard< osl::Mutex > aGuard( maMutex ); 294 295 if ( !mpDisposeEventListeners ) 296 mpDisposeEventListeners = 297 new OInterfaceContainerHelper( getContainerMutex() ); 298 299 mpDisposeEventListeners->addInterface( Listener ); 300 } 301 302 //-------------------------------------------------------------------------- 303 void SAL_CALL SortedResultSet::removeEventListener( 304 const Reference< XEventListener >& Listener ) 305 throw( RuntimeException ) 306 { 307 osl::Guard< osl::Mutex > aGuard( maMutex ); 308 309 if ( mpDisposeEventListeners ) 310 mpDisposeEventListeners->removeInterface( Listener ); 311 } 312 313 //-------------------------------------------------------------------------- 314 // XContentAccess methods. 315 //-------------------------------------------------------------------------- 316 317 OUString SAL_CALL 318 SortedResultSet::queryContentIdentifierString() 319 throw( RuntimeException ) 320 { 321 osl::Guard< osl::Mutex > aGuard( maMutex ); 322 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString(); 323 } 324 325 //-------------------------------------------------------------------------- 326 Reference< XContentIdentifier > SAL_CALL 327 SortedResultSet::queryContentIdentifier() 328 throw( RuntimeException ) 329 { 330 osl::Guard< osl::Mutex > aGuard( maMutex ); 331 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier(); 332 } 333 334 //-------------------------------------------------------------------------- 335 Reference< XContent > SAL_CALL 336 SortedResultSet::queryContent() 337 throw( RuntimeException ) 338 { 339 osl::Guard< osl::Mutex > aGuard( maMutex ); 340 return Reference< XContentAccess >::query(mxOriginal)->queryContent(); 341 } 342 343 344 //-------------------------------------------------------------------------- 345 // XResultSet methods. 346 //-------------------------------------------------------------------------- 347 sal_Bool SAL_CALL SortedResultSet::next() 348 throw ( SQLException, RuntimeException ) 349 { 350 osl::Guard< osl::Mutex > aGuard( maMutex ); 351 352 mnCurEntry++; 353 354 if ( mnCurEntry > 0 ) 355 { 356 if ( mnCurEntry <= mnCount ) 357 { 358 sal_Int32 nIndex = maS2O[ mnCurEntry ]; 359 return mxOriginal->absolute( nIndex ); 360 } 361 else 362 { 363 mnCurEntry = mnCount + 1; 364 } 365 } 366 return sal_False; 367 } 368 369 //------------------------------------------------------------------------- 370 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst() 371 throw ( SQLException, RuntimeException ) 372 { 373 if ( mnCurEntry ) 374 return sal_False; 375 else 376 return sal_True; 377 } 378 379 //------------------------------------------------------------------------- 380 sal_Bool SAL_CALL SortedResultSet::isAfterLast() 381 throw ( SQLException, RuntimeException ) 382 { 383 if ( mnCurEntry > mnCount ) 384 return sal_True; 385 else 386 return sal_False; 387 } 388 389 //------------------------------------------------------------------------- 390 sal_Bool SAL_CALL SortedResultSet::isFirst() 391 throw ( SQLException, RuntimeException ) 392 { 393 if ( mnCurEntry == 1 ) 394 return sal_True; 395 else 396 return sal_False; 397 } 398 399 //------------------------------------------------------------------------- 400 sal_Bool SAL_CALL SortedResultSet::isLast() 401 throw ( SQLException, RuntimeException ) 402 { 403 if ( mnCurEntry == mnCount ) 404 return sal_True; 405 else 406 return sal_False; 407 } 408 409 //------------------------------------------------------------------------- 410 void SAL_CALL SortedResultSet::beforeFirst() 411 throw ( SQLException, RuntimeException ) 412 { 413 osl::Guard< osl::Mutex > aGuard( maMutex ); 414 mnCurEntry = 0; 415 mxOriginal->beforeFirst(); 416 } 417 418 //------------------------------------------------------------------------- 419 void SAL_CALL SortedResultSet::afterLast() 420 throw ( SQLException, RuntimeException ) 421 { 422 osl::Guard< osl::Mutex > aGuard( maMutex ); 423 mnCurEntry = mnCount+1; 424 mxOriginal->afterLast(); 425 } 426 427 //------------------------------------------------------------------------- 428 sal_Bool SAL_CALL SortedResultSet::first() 429 throw ( SQLException, RuntimeException ) 430 { 431 osl::Guard< osl::Mutex > aGuard( maMutex ); 432 433 if ( mnCount ) 434 { 435 mnCurEntry = 1; 436 sal_Int32 nIndex = maS2O[ mnCurEntry ]; 437 return mxOriginal->absolute( nIndex ); 438 } 439 else 440 { 441 mnCurEntry = 0; 442 return sal_False; 443 } 444 } 445 446 //------------------------------------------------------------------------- 447 sal_Bool SAL_CALL SortedResultSet::last() 448 throw ( SQLException, RuntimeException ) 449 { 450 osl::Guard< osl::Mutex > aGuard( maMutex ); 451 452 if ( mnCount ) 453 { 454 mnCurEntry = mnCount; 455 sal_Int32 nIndex = maS2O[ mnCurEntry ]; 456 return mxOriginal->absolute( nIndex ); 457 } 458 else 459 { 460 mnCurEntry = 0; 461 return sal_False; 462 } 463 } 464 465 //------------------------------------------------------------------------- 466 sal_Int32 SAL_CALL SortedResultSet::getRow() 467 throw ( SQLException, RuntimeException ) 468 { 469 return mnCurEntry; 470 } 471 472 //------------------------------------------------------------------------- 473 /** 474 moves the cursor to the given row number in the result set. 475 <p>If the row number is positive, the cursor moves to the given row 476 number with respect to the beginning of the result set. The first 477 row is row 1, the second is row 2, and so on. 478 <p>If the given row number is negative, the cursor moves to an 479 absolute row position with respect to the end of the result set. 480 For example, calling <code>moveToPosition(-1)</code> positions the 481 cursor on the last row, <code>moveToPosition(-2)</code> indicates the 482 next-to-last row, and so on. 483 <p>An attempt to position the cursor beyond the first/last row in the 484 result set leaves the cursor before/after the first/last row, 485 respectively. 486 <p>Note: Calling <code>moveToPosition(1)</code> is the same 487 as calling <code>moveToFirst()</code>. Calling 488 <code>moveToPosition(-1)</code> is the same as calling 489 <code>moveToLast()</code>. 490 @param row 491 is the number of rows to move. Could be negative. 492 @returns 493 <TRUE/> if the cursor is on a row; <FALSE/> otherwise 494 @throws SQLException 495 if a database access error occurs or if row is 0, or the result set 496 type is FORWARD_ONLY. 497 */ 498 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row ) 499 throw ( SQLException, RuntimeException ) 500 { 501 osl::Guard< osl::Mutex > aGuard( maMutex ); 502 503 sal_Int32 nIndex; 504 505 if ( row > 0 ) 506 { 507 if ( row <= mnCount ) 508 { 509 mnCurEntry = row; 510 nIndex = maS2O[ mnCurEntry ]; 511 return mxOriginal->absolute( nIndex ); 512 } 513 else 514 { 515 mnCurEntry = mnCount + 1; 516 return sal_False; 517 } 518 } 519 else if ( row == 0 ) 520 { 521 throw SQLException(); 522 } 523 else 524 { 525 if ( mnCount + row + 1 > 0 ) 526 { 527 mnCurEntry = mnCount + row + 1; 528 nIndex = maS2O[ mnCurEntry ]; 529 return mxOriginal->absolute( nIndex ); 530 } 531 else 532 { 533 mnCurEntry = 0; 534 return sal_False; 535 } 536 } 537 } 538 539 //------------------------------------------------------------------------- 540 /** 541 moves the cursor a relative number of rows, either positive or negative. 542 <p> 543 Attempting to move beyond the first/last row in the result set positions 544 the cursor before/after the first/last row. Calling 545 <code>moveRelative(0)</code> is valid, but does not change the cursor 546 position. 547 <p>Note: Calling <code>moveRelative(1)</code> is different from calling 548 <code>moveNext()</code> because is makes sense to call 549 <code>moveNext()</code> when there is no current row, for example, 550 when the cursor is positioned before the first row or after the last 551 row of the result set. 552 @param rows 553 is the number of rows to move. Could be negative. 554 @returns 555 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off 556 the result set. 557 @throws SQLException 558 if a database access error occurs or if there is no 559 current row, or the result set type is FORWARD_ONLY. 560 */ 561 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows ) 562 throw ( SQLException, RuntimeException ) 563 { 564 osl::Guard< osl::Mutex > aGuard( maMutex ); 565 566 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) 567 { 568 throw SQLException(); 569 } 570 571 if ( rows == 0 ) 572 return sal_True; 573 574 sal_Int32 nTmp = mnCurEntry + rows; 575 576 if ( nTmp <= 0 ) 577 { 578 mnCurEntry = 0; 579 return sal_False; 580 } 581 else if ( nTmp > mnCount ) 582 { 583 mnCurEntry = mnCount + 1; 584 return sal_False; 585 } 586 else 587 { 588 mnCurEntry = nTmp; 589 nTmp = maS2O[ mnCurEntry ]; 590 return mxOriginal->absolute( nTmp ); 591 } 592 } 593 594 //------------------------------------------------------------------------- 595 /** 596 moves the cursor to the previous row in the result set. 597 <p>Note: <code>previous()</code> is not the same as 598 <code>relative(-1)</code> because it makes sense to call 599 <code>previous()</code> when there is no current row. 600 @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off 601 the result set. 602 @throws SQLException 603 if a database access error occurs or the result set type 604 is FORWARD_ONLY. 605 */ 606 sal_Bool SAL_CALL SortedResultSet::previous() 607 throw ( SQLException, RuntimeException ) 608 { 609 osl::Guard< osl::Mutex > aGuard( maMutex ); 610 611 mnCurEntry -= 1; 612 613 if ( mnCurEntry > 0 ) 614 { 615 if ( mnCurEntry <= mnCount ) 616 { 617 sal_Int32 nIndex = maS2O[ mnCurEntry ]; 618 return mxOriginal->absolute( nIndex ); 619 } 620 } 621 else 622 mnCurEntry = 0; 623 624 return sal_False; 625 } 626 627 //------------------------------------------------------------------------- 628 void SAL_CALL SortedResultSet::refreshRow() 629 throw ( SQLException, RuntimeException ) 630 { 631 osl::Guard< osl::Mutex > aGuard( maMutex ); 632 633 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) 634 { 635 throw SQLException(); 636 } 637 638 mxOriginal->refreshRow(); 639 } 640 641 //------------------------------------------------------------------------- 642 sal_Bool SAL_CALL SortedResultSet::rowUpdated() 643 throw ( SQLException, RuntimeException ) 644 { 645 osl::Guard< osl::Mutex > aGuard( maMutex ); 646 647 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) 648 { 649 throw SQLException(); 650 } 651 652 return mxOriginal->rowUpdated(); 653 } 654 655 //------------------------------------------------------------------------- 656 sal_Bool SAL_CALL SortedResultSet::rowInserted() 657 throw ( SQLException, RuntimeException ) 658 { 659 osl::Guard< osl::Mutex > aGuard( maMutex ); 660 661 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) 662 { 663 throw SQLException(); 664 } 665 666 return mxOriginal->rowInserted(); 667 } 668 669 //------------------------------------------------------------------------- 670 sal_Bool SAL_CALL SortedResultSet::rowDeleted() 671 throw ( SQLException, RuntimeException ) 672 { 673 osl::Guard< osl::Mutex > aGuard( maMutex ); 674 675 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) 676 { 677 throw SQLException(); 678 } 679 680 return mxOriginal->rowDeleted(); 681 } 682 683 //------------------------------------------------------------------------- 684 Reference< XInterface > SAL_CALL SortedResultSet::getStatement() 685 throw ( SQLException, RuntimeException ) 686 { 687 osl::Guard< osl::Mutex > aGuard( maMutex ); 688 689 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) ) 690 { 691 throw SQLException(); 692 } 693 694 return mxOriginal->getStatement(); 695 } 696 697 //-------------------------------------------------------------------------- 698 // XRow methods. 699 //-------------------------------------------------------------------------- 700 701 sal_Bool SAL_CALL SortedResultSet::wasNull() 702 throw( SQLException, RuntimeException ) 703 { 704 osl::Guard< osl::Mutex > aGuard( maMutex ); 705 return Reference< XRow >::query(mxOriginal)->wasNull(); 706 } 707 708 //------------------------------------------------------------------------- 709 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex ) 710 throw( SQLException, RuntimeException ) 711 { 712 osl::Guard< osl::Mutex > aGuard( maMutex ); 713 return Reference< XRow >::query(mxOriginal)->getString( columnIndex ); 714 } 715 716 //------------------------------------------------------------------------- 717 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex ) 718 throw( SQLException, RuntimeException ) 719 { 720 osl::Guard< osl::Mutex > aGuard( maMutex ); 721 return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex ); 722 } 723 724 //------------------------------------------------------------------------- 725 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex ) 726 throw( SQLException, RuntimeException ) 727 { 728 osl::Guard< osl::Mutex > aGuard( maMutex ); 729 return Reference< XRow >::query(mxOriginal)->getByte( columnIndex ); 730 } 731 732 //------------------------------------------------------------------------- 733 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex ) 734 throw( SQLException, RuntimeException ) 735 { 736 osl::Guard< osl::Mutex > aGuard( maMutex ); 737 return Reference< XRow >::query(mxOriginal)->getShort( columnIndex ); 738 } 739 740 //------------------------------------------------------------------------- 741 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex ) 742 throw( SQLException, RuntimeException ) 743 { 744 osl::Guard< osl::Mutex > aGuard( maMutex ); 745 return Reference< XRow >::query(mxOriginal)->getInt( columnIndex ); 746 } 747 //------------------------------------------------------------------------- 748 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex ) 749 throw( SQLException, RuntimeException ) 750 { 751 osl::Guard< osl::Mutex > aGuard( maMutex ); 752 return Reference< XRow >::query(mxOriginal)->getLong( columnIndex ); 753 } 754 755 //------------------------------------------------------------------------- 756 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex ) 757 throw( SQLException, RuntimeException ) 758 { 759 osl::Guard< osl::Mutex > aGuard( maMutex ); 760 return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex ); 761 } 762 763 //------------------------------------------------------------------------- 764 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex ) 765 throw( SQLException, RuntimeException ) 766 { 767 osl::Guard< osl::Mutex > aGuard( maMutex ); 768 return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex ); 769 } 770 771 //------------------------------------------------------------------------- 772 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex ) 773 throw( SQLException, RuntimeException ) 774 { 775 osl::Guard< osl::Mutex > aGuard( maMutex ); 776 return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex ); 777 } 778 779 //------------------------------------------------------------------------- 780 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex ) 781 throw( SQLException, RuntimeException ) 782 { 783 osl::Guard< osl::Mutex > aGuard( maMutex ); 784 return Reference< XRow >::query(mxOriginal)->getDate( columnIndex ); 785 } 786 787 //------------------------------------------------------------------------- 788 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex ) 789 throw( SQLException, RuntimeException ) 790 { 791 osl::Guard< osl::Mutex > aGuard( maMutex ); 792 return Reference< XRow >::query(mxOriginal)->getTime( columnIndex ); 793 } 794 795 //------------------------------------------------------------------------- 796 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex ) 797 throw( SQLException, RuntimeException ) 798 { 799 osl::Guard< osl::Mutex > aGuard( maMutex ); 800 return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex ); 801 } 802 803 //------------------------------------------------------------------------- 804 Reference< XInputStream > SAL_CALL 805 SortedResultSet::getBinaryStream( sal_Int32 columnIndex ) 806 throw( SQLException, RuntimeException ) 807 { 808 osl::Guard< osl::Mutex > aGuard( maMutex ); 809 return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex ); 810 } 811 812 //------------------------------------------------------------------------- 813 Reference< XInputStream > SAL_CALL 814 SortedResultSet::getCharacterStream( sal_Int32 columnIndex ) 815 throw( SQLException, RuntimeException ) 816 { 817 osl::Guard< osl::Mutex > aGuard( maMutex ); 818 return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex ); 819 } 820 821 //------------------------------------------------------------------------- 822 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex, 823 const Reference< XNameAccess >& typeMap ) 824 throw( SQLException, RuntimeException ) 825 { 826 osl::Guard< osl::Mutex > aGuard( maMutex ); 827 return Reference< XRow >::query(mxOriginal)->getObject( columnIndex, 828 typeMap); 829 } 830 831 //------------------------------------------------------------------------- 832 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex ) 833 throw( SQLException, RuntimeException ) 834 { 835 osl::Guard< osl::Mutex > aGuard( maMutex ); 836 return Reference< XRow >::query(mxOriginal)->getRef( columnIndex ); 837 } 838 839 //------------------------------------------------------------------------- 840 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex ) 841 throw( SQLException, RuntimeException ) 842 { 843 osl::Guard< osl::Mutex > aGuard( maMutex ); 844 return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex ); 845 } 846 847 //------------------------------------------------------------------------- 848 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex ) 849 throw( SQLException, RuntimeException ) 850 { 851 osl::Guard< osl::Mutex > aGuard( maMutex ); 852 return Reference< XRow >::query(mxOriginal)->getClob( columnIndex ); 853 } 854 855 //------------------------------------------------------------------------- 856 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex ) 857 throw( SQLException, RuntimeException ) 858 { 859 osl::Guard< osl::Mutex > aGuard( maMutex ); 860 return Reference< XRow >::query(mxOriginal)->getArray( columnIndex ); 861 } 862 863 864 //-------------------------------------------------------------------------- 865 // XCloseable methods. 866 //-------------------------------------------------------------------------- 867 868 void SAL_CALL SortedResultSet::close() 869 throw( SQLException, RuntimeException ) 870 { 871 osl::Guard< osl::Mutex > aGuard( maMutex ); 872 Reference< XCloseable >::query(mxOriginal)->close(); 873 } 874 875 //-------------------------------------------------------------------------- 876 // XResultSetMetaDataSupplier methods. 877 //-------------------------------------------------------------------------- 878 879 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData() 880 throw( SQLException, RuntimeException ) 881 { 882 osl::Guard< osl::Mutex > aGuard( maMutex ); 883 return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData(); 884 } 885 886 887 //-------------------------------------------------------------------------- 888 // XPropertySet methods. 889 //-------------------------------------------------------------------------- 890 891 Reference< XPropertySetInfo > SAL_CALL 892 SortedResultSet::getPropertySetInfo() throw( RuntimeException ) 893 { 894 osl::Guard< osl::Mutex > aGuard( maMutex ); 895 896 if ( !mpPropSetInfo ) 897 { 898 mpPropSetInfo = new SRSPropertySetInfo(); 899 mpPropSetInfo->acquire(); 900 } 901 902 return Reference< XPropertySetInfo >( mpPropSetInfo ); 903 } 904 905 //-------------------------------------------------------------------------- 906 void SAL_CALL SortedResultSet::setPropertyValue( 907 const OUString& PropertyName, 908 const Any& ) 909 throw( UnknownPropertyException, 910 PropertyVetoException, 911 IllegalArgumentException, 912 WrappedTargetException, 913 RuntimeException ) 914 { 915 osl::Guard< osl::Mutex > aGuard( maMutex ); 916 917 if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) || 918 ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) ) 919 throw IllegalArgumentException(); 920 else 921 throw UnknownPropertyException(); 922 } 923 924 //-------------------------------------------------------------------------- 925 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName ) 926 throw( UnknownPropertyException, 927 WrappedTargetException, 928 RuntimeException ) 929 { 930 osl::Guard< osl::Mutex > aGuard( maMutex ); 931 932 Any aRet; 933 934 if ( PropertyName.compareToAscii( "RowCount" ) == 0 ) 935 { 936 aRet <<= maS2O.Count(); 937 } 938 else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) 939 { 940 sal_uInt32 nOrgCount = 0; 941 sal_Bool bOrgFinal = false; 942 Any aOrgRet; 943 944 aRet <<= (sal_Bool) sal_False; 945 946 aOrgRet = Reference< XPropertySet >::query(mxOriginal)-> 947 getPropertyValue( PropertyName ); 948 aOrgRet >>= bOrgFinal; 949 950 if ( bOrgFinal ) 951 { 952 aOrgRet = Reference< XPropertySet >::query(mxOriginal)-> 953 getPropertyValue( OUString::createFromAscii( "RowCount" ) ); 954 aOrgRet >>= nOrgCount; 955 if ( nOrgCount == maS2O.Count() ) 956 aRet <<= (sal_Bool) sal_True; 957 } 958 } 959 else 960 throw UnknownPropertyException(); 961 962 return aRet; 963 } 964 965 //-------------------------------------------------------------------------- 966 void SAL_CALL SortedResultSet::addPropertyChangeListener( 967 const OUString& PropertyName, 968 const Reference< XPropertyChangeListener >& Listener ) 969 throw( UnknownPropertyException, 970 WrappedTargetException, 971 RuntimeException ) 972 { 973 osl::Guard< osl::Mutex > aGuard( maMutex ); 974 975 if ( !mpPropChangeListeners ) 976 mpPropChangeListeners = 977 new PropertyChangeListeners_Impl(); 978 979 mpPropChangeListeners->addInterface( PropertyName, Listener ); 980 } 981 982 //-------------------------------------------------------------------------- 983 void SAL_CALL SortedResultSet::removePropertyChangeListener( 984 const OUString& PropertyName, 985 const Reference< XPropertyChangeListener >& Listener ) 986 throw( UnknownPropertyException, 987 WrappedTargetException, 988 RuntimeException ) 989 { 990 osl::Guard< osl::Mutex > aGuard( maMutex ); 991 992 if ( mpPropChangeListeners ) 993 mpPropChangeListeners->removeInterface( PropertyName, Listener ); 994 } 995 996 //-------------------------------------------------------------------------- 997 void SAL_CALL SortedResultSet::addVetoableChangeListener( 998 const OUString& PropertyName, 999 const Reference< XVetoableChangeListener >& Listener ) 1000 throw( UnknownPropertyException, 1001 WrappedTargetException, 1002 RuntimeException ) 1003 { 1004 osl::Guard< osl::Mutex > aGuard( maMutex ); 1005 1006 if ( !mpVetoChangeListeners ) 1007 mpVetoChangeListeners = 1008 new PropertyChangeListeners_Impl(); 1009 1010 mpVetoChangeListeners->addInterface( PropertyName, Listener ); 1011 } 1012 1013 //-------------------------------------------------------------------------- 1014 void SAL_CALL SortedResultSet::removeVetoableChangeListener( 1015 const OUString& PropertyName, 1016 const Reference< XVetoableChangeListener >& Listener ) 1017 throw( UnknownPropertyException, 1018 WrappedTargetException, 1019 RuntimeException ) 1020 { 1021 osl::Guard< osl::Mutex > aGuard( maMutex ); 1022 1023 if ( mpVetoChangeListeners ) 1024 mpVetoChangeListeners->removeInterface( PropertyName, Listener ); 1025 } 1026 1027 //-------------------------------------------------------------------------- 1028 // private methods 1029 //-------------------------------------------------------------------------- 1030 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne, 1031 Reference < XResultSet > xResultTwo, 1032 long nIndexOne, long nIndexTwo, 1033 SortInfo* pSortInfo ) 1034 1035 throw( SQLException, RuntimeException ) 1036 { 1037 Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne ); 1038 Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo ); 1039 1040 long nCompare = 0; 1041 long nColumn = pSortInfo->mnColumn; 1042 1043 switch ( pSortInfo->mnType ) 1044 { 1045 case DataType::BIT : 1046 case DataType::TINYINT : 1047 case DataType::SMALLINT : 1048 case DataType::INTEGER : 1049 { 1050 sal_Int32 aOne = 0; 1051 sal_Int32 aTwo = 0; 1052 1053 if ( xResultOne->absolute( nIndexOne ) ) 1054 aOne = xRowOne->getInt( nColumn ); 1055 if ( xResultTwo->absolute( nIndexTwo ) ) 1056 aTwo = xRowTwo->getInt( nColumn ); 1057 1058 if ( aOne < aTwo ) 1059 nCompare = -1; 1060 else if ( aOne == aTwo ) 1061 nCompare = 0; 1062 else 1063 nCompare = 1; 1064 1065 break; 1066 } 1067 case DataType::BIGINT : 1068 { 1069 sal_Int64 aOne = 0; 1070 sal_Int64 aTwo = 0; 1071 1072 if ( xResultOne->absolute( nIndexOne ) ) 1073 aOne = xRowOne->getLong( nColumn ); 1074 if ( xResultTwo->absolute( nIndexTwo ) ) 1075 aTwo = xRowTwo->getLong( nColumn ); 1076 1077 if ( aOne < aTwo ) 1078 nCompare = -1; 1079 else if ( aOne == aTwo ) 1080 nCompare = 0; 1081 else 1082 nCompare = 1; 1083 1084 break; 1085 } 1086 case DataType::CHAR : 1087 case DataType::VARCHAR : 1088 case DataType::LONGVARCHAR : 1089 { 1090 OUString aOne, aTwo; 1091 1092 if ( xResultOne->absolute( nIndexOne ) ) 1093 aOne = xRowOne->getString( nColumn ); 1094 if ( xResultTwo->absolute( nIndexTwo ) ) 1095 aTwo = xRowTwo->getString( nColumn ); 1096 1097 if ( ! pSortInfo->mbCaseSensitive ) 1098 { 1099 aOne = aOne.toAsciiLowerCase(); 1100 aTwo = aTwo.toAsciiLowerCase(); 1101 } 1102 1103 nCompare = aOne.compareTo( aTwo ); 1104 break; 1105 } 1106 case DataType::DATE : 1107 { 1108 Date aOne, aTwo; 1109 sal_Int32 nTmp; 1110 1111 if ( xResultOne->absolute( nIndexOne ) ) 1112 aOne = xRowOne->getDate( nColumn ); 1113 if ( xResultTwo->absolute( nIndexTwo ) ) 1114 aTwo = xRowTwo->getDate( nColumn ); 1115 1116 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year; 1117 if ( !nTmp ) { 1118 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month; 1119 if ( !nTmp ) 1120 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day; 1121 } 1122 1123 if ( nTmp < 0 ) 1124 nCompare = -1; 1125 else if ( nTmp == 0 ) 1126 nCompare = 0; 1127 else 1128 nCompare = 1; 1129 1130 break; 1131 } 1132 case DataType::TIME : 1133 { 1134 Time aOne, aTwo; 1135 sal_Int32 nTmp; 1136 1137 if ( xResultOne->absolute( nIndexOne ) ) 1138 aOne = xRowOne->getTime( nColumn ); 1139 if ( xResultTwo->absolute( nIndexTwo ) ) 1140 aTwo = xRowTwo->getTime( nColumn ); 1141 1142 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours; 1143 if ( !nTmp ) { 1144 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes; 1145 if ( !nTmp ) { 1146 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds; 1147 if ( !nTmp ) 1148 nTmp = (sal_Int32) aTwo.HundredthSeconds 1149 - (sal_Int32) aOne.HundredthSeconds; 1150 }} 1151 1152 if ( nTmp < 0 ) 1153 nCompare = -1; 1154 else if ( nTmp == 0 ) 1155 nCompare = 0; 1156 else 1157 nCompare = 1; 1158 1159 break; 1160 } 1161 case DataType::TIMESTAMP : 1162 { 1163 DateTime aOne, aTwo; 1164 sal_Int32 nTmp; 1165 1166 if ( xResultOne->absolute( nIndexOne ) ) 1167 aOne = xRowOne->getTimestamp( nColumn ); 1168 if ( xResultTwo->absolute( nIndexTwo ) ) 1169 aTwo = xRowTwo->getTimestamp( nColumn ); 1170 1171 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year; 1172 if ( !nTmp ) { 1173 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month; 1174 if ( !nTmp ) { 1175 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day; 1176 if ( !nTmp ) { 1177 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours; 1178 if ( !nTmp ) { 1179 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes; 1180 if ( !nTmp ) { 1181 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds; 1182 if ( !nTmp ) 1183 nTmp = (sal_Int32) aTwo.HundredthSeconds 1184 - (sal_Int32) aOne.HundredthSeconds; 1185 }}}}} 1186 1187 if ( nTmp < 0 ) 1188 nCompare = -1; 1189 else if ( nTmp == 0 ) 1190 nCompare = 0; 1191 else 1192 nCompare = 1; 1193 1194 break; 1195 } 1196 case DataType::REAL : 1197 { 1198 float aOne = 0; 1199 float aTwo = 0; 1200 1201 if ( xResultOne->absolute( nIndexOne ) ) 1202 aOne = xRowOne->getFloat( nColumn ); 1203 if ( xResultTwo->absolute( nIndexTwo ) ) 1204 aTwo = xRowTwo->getFloat( nColumn ); 1205 1206 if ( aOne < aTwo ) 1207 nCompare = -1; 1208 else if ( aOne == aTwo ) 1209 nCompare = 0; 1210 else 1211 nCompare = 1; 1212 1213 break; 1214 } 1215 case DataType::FLOAT : 1216 case DataType::DOUBLE : 1217 { 1218 double aOne = 0; 1219 double aTwo = 0; 1220 1221 if ( xResultOne->absolute( nIndexOne ) ) 1222 aOne = xRowOne->getDouble( nColumn ); 1223 if ( xResultTwo->absolute( nIndexTwo ) ) 1224 aTwo = xRowTwo->getDouble( nColumn ); 1225 1226 if ( aOne < aTwo ) 1227 nCompare = -1; 1228 else if ( aOne == aTwo ) 1229 nCompare = 0; 1230 else 1231 nCompare = 1; 1232 1233 break; 1234 } 1235 default: 1236 { 1237 OSL_ENSURE( sal_False, "DataType not supported for compare!" ); 1238 } 1239 } 1240 1241 return nCompare; 1242 } 1243 1244 //-------------------------------------------------------------------------- 1245 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne, 1246 Reference < XResultSet > xResultTwo, 1247 long nIndexOne, long nIndexTwo ) 1248 throw( SQLException, RuntimeException ) 1249 { 1250 long nCompare = 0; 1251 SortInfo* pInfo = mpSortInfo; 1252 1253 while ( !nCompare && pInfo ) 1254 { 1255 if ( pInfo->mbUseOwnCompare ) 1256 { 1257 nCompare = CompareImpl( xResultOne, xResultTwo, 1258 nIndexOne, nIndexTwo, pInfo ); 1259 } 1260 else 1261 { 1262 Any aOne, aTwo; 1263 1264 Reference < XRow > xRowOne = 1265 Reference< XRow >::query( xResultOne ); 1266 Reference < XRow > xRowTwo = 1267 Reference< XRow >::query( xResultTwo ); 1268 1269 if ( xResultOne->absolute( nIndexOne ) ) 1270 aOne = xRowOne->getObject( pInfo->mnColumn, NULL ); 1271 if ( xResultTwo->absolute( nIndexTwo ) ) 1272 aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL ); 1273 1274 nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo ); 1275 } 1276 1277 if ( ! pInfo->mbAscending ) 1278 nCompare = - nCompare; 1279 1280 pInfo = pInfo->mpNext; 1281 } 1282 1283 return nCompare; 1284 } 1285 1286 //-------------------------------------------------------------------------- 1287 long SortedResultSet::Compare( SortListData *pOne, 1288 SortListData *pTwo ) 1289 throw( SQLException, RuntimeException ) 1290 { 1291 long nIndexOne; 1292 long nIndexTwo; 1293 1294 Reference < XResultSet > xResultOne; 1295 Reference < XResultSet > xResultTwo; 1296 1297 if ( pOne->mbModified ) 1298 { 1299 xResultOne = mxOther; 1300 nIndexOne = pOne->mnOldPos; 1301 } 1302 else 1303 { 1304 xResultOne = mxOriginal; 1305 nIndexOne = pOne->mnCurPos; 1306 } 1307 1308 if ( pTwo->mbModified ) 1309 { 1310 xResultTwo = mxOther; 1311 nIndexTwo = pTwo->mnOldPos; 1312 } 1313 else 1314 { 1315 xResultTwo = mxOriginal; 1316 nIndexTwo = pTwo->mnCurPos; 1317 } 1318 1319 long nCompare; 1320 nCompare = CompareImpl( xResultOne, xResultTwo, 1321 nIndexOne, nIndexTwo ); 1322 return nCompare; 1323 } 1324 1325 //-------------------------------------------------------------------------- 1326 long SortedResultSet::FindPos( SortListData *pEntry, 1327 long _nStart, long _nEnd ) 1328 throw( SQLException, RuntimeException ) 1329 { 1330 if ( _nStart > _nEnd ) 1331 return _nStart + 1; 1332 1333 long nStart = _nStart; 1334 long nEnd = _nEnd; 1335 long nMid = 0, nCompare = 0; 1336 1337 SortListData *pMid; 1338 1339 while ( nStart <= nEnd ) 1340 { 1341 nMid = ( nEnd - nStart ) / 2 + nStart; 1342 pMid = maS2O.GetData( nMid ); 1343 nCompare = Compare( pEntry, pMid ); 1344 1345 if ( !nCompare ) 1346 nCompare = ((long) pEntry ) - ( (long) pMid ); 1347 1348 if ( nCompare < 0 ) // pEntry < pMid 1349 nEnd = nMid - 1; 1350 else 1351 nStart = nMid + 1; 1352 } 1353 1354 if ( nCompare < 0 ) // pEntry < pMid 1355 return nMid; 1356 else 1357 return nMid+1; 1358 } 1359 1360 //-------------------------------------------------------------------------- 1361 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt ) 1362 { 1363 osl::Guard< osl::Mutex > aGuard( maMutex ); 1364 1365 if ( !mpPropChangeListeners ) 1366 return; 1367 1368 // Notify listeners interested especially in the changed property. 1369 OInterfaceContainerHelper* pPropsContainer = 1370 mpPropChangeListeners->getContainer( rEvt.PropertyName ); 1371 if ( pPropsContainer ) 1372 { 1373 OInterfaceIteratorHelper aIter( *pPropsContainer ); 1374 while ( aIter.hasMoreElements() ) 1375 { 1376 Reference< XPropertyChangeListener > xListener( 1377 aIter.next(), UNO_QUERY ); 1378 if ( xListener.is() ) 1379 xListener->propertyChange( rEvt ); 1380 } 1381 } 1382 1383 // Notify listeners interested in all properties. 1384 pPropsContainer = mpPropChangeListeners->getContainer( OUString() ); 1385 if ( pPropsContainer ) 1386 { 1387 OInterfaceIteratorHelper aIter( *pPropsContainer ); 1388 while ( aIter.hasMoreElements() ) 1389 { 1390 Reference< XPropertyChangeListener > xListener( 1391 aIter.next(), UNO_QUERY ); 1392 if ( xListener.is() ) 1393 xListener->propertyChange( rEvt ); 1394 } 1395 } 1396 } 1397 1398 //------------------------------------------------------------------------- 1399 1400 //-------------------------------------------------------------------------- 1401 // public methods 1402 //-------------------------------------------------------------------------- 1403 1404 void SortedResultSet::CopyData( SortedResultSet *pSource ) 1405 { 1406 const SortedEntryList *pSrcS2O = pSource->GetS2OList(); 1407 const SimpleList *pSrcO2S = pSource->GetO2SList(); 1408 1409 long i, nCount; 1410 1411 maS2O.Clear(); 1412 maO2S.Clear(); 1413 maModList.Clear(); 1414 1415 maS2O.Insert( NULL, 0 ); 1416 maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos 1417 1418 nCount = pSrcS2O->Count(); 1419 1420 for ( i=1; i<nCount; i++ ) 1421 { 1422 maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i ); 1423 maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i ); 1424 } 1425 1426 mnLastSort = maS2O.Count(); 1427 mxOther = pSource->GetResultSet(); 1428 1429 if ( !mpSortInfo ) 1430 { 1431 mpSortInfo = pSource->GetSortInfo(); 1432 mbIsCopy = sal_True; 1433 } 1434 } 1435 1436 //-------------------------------------------------------------------------- 1437 void SortedResultSet::Initialize( 1438 const Sequence < NumberedSortingInfo > &xSortInfo, 1439 const Reference< XAnyCompareFactory > &xCompFactory ) 1440 { 1441 BuildSortInfo( mxOriginal, xSortInfo, xCompFactory ); 1442 // Insert dummy at pos 0 1443 SortListData *pData = new SortListData( 0 ); 1444 maS2O.Insert( pData, 0 ); 1445 1446 long nIndex = 1; 1447 1448 // now fetch all the elements from the original result set, 1449 // get there new position in the sorted result set and insert 1450 // an entry in the sorted to original mapping list 1451 try { 1452 while ( mxOriginal->absolute( nIndex ) ) 1453 { 1454 pData = new SortListData( nIndex ); 1455 long nPos = FindPos( pData, 1, nIndex-1 ); 1456 1457 maS2O.Insert( pData, nPos ); 1458 1459 nIndex++; 1460 } 1461 } 1462 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::Initialize() : Got unexpected SQLException" ); } 1463 1464 // when we have fetched all the elements, we can create the 1465 // original to sorted mapping list from the s2o list 1466 maO2S.Clear(); 1467 maO2S.Insert( NULL, (sal_uInt32) 0 ); 1468 1469 // insert some dummy entries first and replace then 1470 // the entries with the right ones 1471 sal_uInt32 i; 1472 1473 for ( i=1; i<maS2O.Count(); i++ ) 1474 maO2S.Insert( (void*) 0, i ); // Insert( data, pos ) 1475 for ( i=1; i<maS2O.Count(); i++ ) 1476 maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos ) 1477 1478 mnCount = maS2O.Count() - 1; 1479 } 1480 1481 //-------------------------------------------------------------------------- 1482 void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal ) 1483 { 1484 osl::Guard< osl::Mutex > aGuard( maMutex ); 1485 1486 if ( !mpPropChangeListeners ) 1487 return; 1488 1489 try { 1490 // check for propertyChangeEvents 1491 if ( nOldCount != GetCount() ) 1492 { 1493 sal_Bool bIsFinal = sal_False; 1494 PropertyChangeEvent aEvt; 1495 1496 aEvt.PropertyName = OUString::createFromAscii( "RowCount" ); 1497 aEvt.Further = sal_False; 1498 aEvt.PropertyHandle = -1; 1499 aEvt.OldValue <<= nOldCount; 1500 aEvt.NewValue <<= GetCount(); 1501 1502 PropertyChanged( aEvt ); 1503 1504 OUString aName = OUString::createFromAscii( "IsRowCountFinal" ); 1505 Any aRet = getPropertyValue( aName ); 1506 if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal ) 1507 { 1508 aEvt.PropertyName = aName; 1509 aEvt.Further = sal_False; 1510 aEvt.PropertyHandle = -1; 1511 aEvt.OldValue <<= (sal_Bool) bWasFinal; 1512 aEvt.NewValue <<= (sal_Bool) bIsFinal; 1513 PropertyChanged( aEvt ); 1514 } 1515 } 1516 } 1517 catch ( UnknownPropertyException ) {} 1518 catch ( WrappedTargetException ) {} 1519 } 1520 1521 //------------------------------------------------------------------------- 1522 void SortedResultSet::InsertNew( long nPos, long nCount ) 1523 { 1524 // in der maS2O Liste alle Eintr�ge, die >= nPos sind, um nCount 1525 // erh�hen 1526 SortListData *pData; 1527 long i, nEnd; 1528 1529 nEnd = maS2O.Count(); 1530 for ( i=1; i<=nEnd; i++ ) 1531 { 1532 pData = maS2O.GetData( i ); 1533 if ( pData->mnCurPos >= nPos ) 1534 { 1535 pData->mnCurPos += nCount; 1536 } 1537 } 1538 1539 // und die neuen eintr�ge hinten an die maS2O Liste anh�ngen bzw 1540 // an der Position nPos in der maO2S Liste einf�gen 1541 for ( i=0; i<nCount; i++ ) 1542 { 1543 nEnd += 1; 1544 pData = new SortListData( nEnd ); 1545 1546 maS2O.Insert( pData, nEnd ); // Insert( Wert, Position ) 1547 maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Wert, Position ) 1548 } 1549 1550 mnCount += nCount; 1551 } 1552 1553 //------------------------------------------------------------------------- 1554 void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents ) 1555 { 1556 sal_uInt32 i, j; 1557 long nOldLastSort; 1558 1559 // correct mnLastSort first 1560 nOldLastSort = mnLastSort; 1561 if ( nPos <= mnLastSort ) 1562 { 1563 if ( nPos + nCount - 1 <= mnLastSort ) 1564 mnLastSort -= nCount; 1565 else 1566 mnLastSort = nPos - 1; 1567 } 1568 1569 // remove the entries from the lists and correct the positions 1570 // in the original2sorted list 1571 for ( i=0; i < (sal_uInt32) nCount; i++ ) 1572 { 1573 long nSortPos = (long) maO2S.GetObject( nPos ); 1574 maO2S.Remove( (sal_uInt32) nPos ); 1575 1576 for ( j=1; j<=maO2S.Count(); j++ ) 1577 { 1578 long nVal = (long) maO2S.GetObject( j ); 1579 if ( nVal > nSortPos ) 1580 { 1581 --nVal; 1582 maO2S.Replace( (void*) nVal, j ); 1583 } 1584 } 1585 1586 SortListData *pData = maS2O.Remove( nSortPos ); 1587 if ( pData->mbModified ) 1588 maModList.Remove( (void*) pData ); 1589 delete pData; 1590 1591 // generate remove Event, but not for new entries 1592 if ( nSortPos <= nOldLastSort ) 1593 pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 ); 1594 } 1595 1596 // correct the positions in the sorted list 1597 for ( i=1; i<= maS2O.Count(); i++ ) 1598 { 1599 SortListData *pData = maS2O.GetData( i ); 1600 if ( pData->mnCurPos > nPos ) 1601 pData->mnCurPos -= nCount; 1602 } 1603 1604 mnCount -= nCount; 1605 } 1606 1607 //------------------------------------------------------------------------- 1608 void SortedResultSet::Move( long nPos, long nCount, long nOffset ) 1609 { 1610 if ( !nOffset ) 1611 return; 1612 1613 long i, nSortPos, nTo; 1614 SortListData *pData; 1615 1616 for ( i=0; i<nCount; i++ ) 1617 { 1618 nSortPos = (long) maO2S.GetObject( nPos+i ); 1619 pData = maS2O.GetData( nSortPos ); 1620 pData->mnCurPos += nOffset; 1621 } 1622 1623 if ( nOffset < 0 ) 1624 { 1625 for ( i=nPos+nOffset; i<nPos; i++ ) 1626 { 1627 nSortPos = (long) maO2S.GetObject( i ); 1628 pData = maS2O.GetData( nSortPos ); 1629 pData->mnCurPos += nCount; 1630 } 1631 } 1632 else 1633 { 1634 long nStart = nPos + nCount; 1635 long nEnd = nStart + nOffset; 1636 for ( i=nStart; i<nEnd; i++ ) 1637 { 1638 nSortPos = (long) maO2S.GetObject( i ); 1639 pData = maS2O.GetData( nSortPos ); 1640 pData->mnCurPos -= nCount; 1641 } 1642 } 1643 1644 // remember the to be moved entries 1645 long *pTmpArr = new long[ nCount ]; 1646 for ( i=0; i<nCount; i++ ) 1647 pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) ); 1648 1649 // now move the entries, which are in the way 1650 if ( nOffset < 0 ) 1651 { 1652 // be carefully here, because nOffset is negative here, so an 1653 // addition is a subtraction 1654 long nFrom = nPos - 1; 1655 nTo = nPos + nCount - 1; 1656 1657 // same for i here 1658 for ( i=0; i>nOffset; i-- ) 1659 { 1660 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) ); 1661 maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) ); 1662 } 1663 1664 } 1665 else 1666 { 1667 long nStart = nPos + nCount; 1668 for ( i=0; i<nOffset; i++ ) 1669 { 1670 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) ); 1671 maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) ); 1672 } 1673 } 1674 1675 // finally put the remembered entries at there new location 1676 nTo = nPos + nOffset; 1677 for ( i=0; i<nCount; i++ ) 1678 { 1679 maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) ); 1680 } 1681 1682 delete [] pTmpArr; 1683 } 1684 1685 //-------------------------------------------------------------------------- 1686 void SortedResultSet::BuildSortInfo( 1687 Reference< XResultSet > aResult, 1688 const Sequence < NumberedSortingInfo > &xSortInfo, 1689 const Reference< XAnyCompareFactory > &xCompFactory ) 1690 { 1691 Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY ); 1692 1693 if ( ! xMeta.is() ) 1694 { 1695 OSL_ENSURE( sal_False, "No MetaData, No Sorting!" ); 1696 return; 1697 } 1698 1699 Reference < XResultSetMetaData > xData = xMeta->getMetaData(); 1700 const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray(); 1701 1702 sal_Int32 nColumn; 1703 OUString aPropName; 1704 SortInfo *pInfo; 1705 1706 for ( long i=xSortInfo.getLength(); i > 0; ) 1707 { 1708 --i; 1709 nColumn = pSortInfo[ i ].ColumnIndex; 1710 aPropName = xData->getColumnName( nColumn ); 1711 pInfo = new SortInfo; 1712 1713 if ( xCompFactory.is() ) 1714 pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName( 1715 aPropName ); 1716 1717 if ( pInfo->mxCompareFunction.is() ) 1718 { 1719 pInfo->mbUseOwnCompare = sal_False; 1720 pInfo->mnType = 0; 1721 } 1722 else 1723 { 1724 pInfo->mbUseOwnCompare = sal_True; 1725 pInfo->mnType = xData->getColumnType( nColumn ); 1726 } 1727 1728 pInfo->mnColumn = nColumn; 1729 pInfo->mbAscending = pSortInfo[ i ].Ascending; 1730 pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn ); 1731 pInfo->mpNext = mpSortInfo; 1732 mpSortInfo = pInfo; 1733 } 1734 } 1735 1736 //------------------------------------------------------------------------- 1737 void SortedResultSet::SetChanged( long nPos, long nCount ) 1738 { 1739 for ( long i=0; i<nCount; i++ ) 1740 { 1741 long nSortPos = (long) maO2S.GetObject( nPos ); 1742 if ( nSortPos < mnLastSort ) 1743 { 1744 SortListData *pData = maS2O.GetData( nSortPos ); 1745 if ( ! pData->mbModified ) 1746 { 1747 pData->mbModified = sal_True; 1748 maModList.Append( pData ); 1749 } 1750 } 1751 nPos += 1; 1752 } 1753 } 1754 1755 //------------------------------------------------------------------------- 1756 void SortedResultSet::ResortModified( EventList* pList ) 1757 { 1758 sal_uInt32 i, j; 1759 long nCompare, nCurPos, nNewPos; 1760 long nStart, nEnd, nOffset, nVal; 1761 SortListData *pData; 1762 ListAction *pAction; 1763 1764 try { 1765 for ( i=0; i<maModList.Count(); i++ ) 1766 { 1767 pData = (SortListData*) maModList.GetObject( i ); 1768 nCompare = CompareImpl( mxOther, mxOriginal, 1769 pData->mnOldPos, pData->mnCurPos ); 1770 pData->mbModified = sal_False; 1771 if ( nCompare != 0 ) 1772 { 1773 nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos ); 1774 if ( nCompare < 0 ) 1775 { 1776 nNewPos = FindPos( pData, 1, nCurPos-1 ); 1777 nStart = nNewPos; 1778 nEnd = nCurPos; 1779 nOffset = 1; 1780 } 1781 else 1782 { 1783 nNewPos = FindPos( pData, nCurPos+1, mnLastSort ); 1784 nStart = nCurPos; 1785 nEnd = mnLastSort; 1786 nOffset = -1; 1787 } 1788 1789 if ( nNewPos != nCurPos ) 1790 { 1791 // correct the lists! 1792 maS2O.Remove( (sal_uInt32) nCurPos ); 1793 maS2O.Insert( pData, nNewPos ); 1794 for ( j=1; j<maO2S.Count(); j++ ) 1795 { 1796 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) ); 1797 if ( ( nStart <= nVal ) && ( nVal <= nEnd ) ) 1798 { 1799 nVal += nOffset; 1800 maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) ); 1801 } 1802 } 1803 1804 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos ); 1805 1806 pAction = new ListAction; 1807 pAction->Position = nCurPos; 1808 pAction->Count = 1; 1809 pAction->ListActionType = ListActionType::MOVED; 1810 pAction->ActionInfo <<= nNewPos-nCurPos; 1811 pList->Insert( pAction ); 1812 } 1813 pList->AddEvent( ListActionType::PROPERTIES_CHANGED, 1814 nNewPos, 1 ); 1815 } 1816 } 1817 } 1818 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortModified() : Got unexpected SQLException" ); } 1819 1820 maModList.Clear(); 1821 } 1822 1823 //------------------------------------------------------------------------- 1824 void SortedResultSet::ResortNew( EventList* pList ) 1825 { 1826 long i, j, nNewPos, nVal; 1827 SortListData *pData; 1828 1829 try { 1830 for ( i = mnLastSort; i<(long)maS2O.Count(); i++ ) 1831 { 1832 pData = (SortListData*) maModList.GetObject( i ); 1833 nNewPos = FindPos( pData, 1, mnLastSort ); 1834 if ( nNewPos != i ) 1835 { 1836 maS2O.Remove( (sal_uInt32) i ); 1837 maS2O.Insert( pData, nNewPos ); 1838 // maO2S liste korigieren 1839 for ( j=1; j<(long)maO2S.Count(); j++ ) 1840 { 1841 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) ); 1842 if ( nVal >= nNewPos ) 1843 maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) ); 1844 } 1845 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos ); 1846 } 1847 mnLastSort++; 1848 pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 ); 1849 } 1850 } 1851 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortNew() : Got unexpected SQLException" ); } 1852 } 1853 1854 //------------------------------------------------------------------------- 1855 // 1856 // SortListData 1857 // 1858 //------------------------------------------------------------------------- 1859 SortListData::SortListData( long nPos, sal_Bool bModified ) 1860 { 1861 mbModified = bModified; 1862 mnCurPos = nPos; 1863 mnOldPos = nPos; 1864 }; 1865 1866 1867 //========================================================================= 1868 void SortedEntryList::Clear() 1869 { 1870 for ( std::deque< LISTACTION* >::size_type i = 0; 1871 i < maData.size(); ++i ) 1872 { 1873 delete maData[i]; 1874 } 1875 1876 maData.clear(); 1877 } 1878 1879 //------------------------------------------------------------------------- 1880 void SortedEntryList::Insert( SortListData *pEntry, long nPos ) 1881 { 1882 if ( nPos < (long) maData.size() ) 1883 maData.insert( maData.begin() + nPos, pEntry ); 1884 else 1885 maData.push_back( pEntry ); 1886 } 1887 1888 //------------------------------------------------------------------------- 1889 SortListData* SortedEntryList::Remove( long nPos ) 1890 { 1891 SortListData *pData; 1892 1893 if ( nPos < (long) maData.size() ) 1894 { 1895 pData = maData[ nPos ]; 1896 maData.erase( maData.begin() + nPos ); 1897 } 1898 else 1899 pData = NULL; 1900 1901 return pData; 1902 } 1903 1904 //------------------------------------------------------------------------- 1905 SortListData* SortedEntryList::GetData( long nPos ) 1906 { 1907 SortListData *pData; 1908 1909 if ( nPos < (long) maData.size() ) 1910 pData = maData[ nPos ]; 1911 else 1912 pData = NULL; 1913 1914 return pData; 1915 } 1916 1917 //------------------------------------------------------------------------- 1918 long SortedEntryList::operator [] ( long nPos ) const 1919 { 1920 SortListData *pData; 1921 1922 if ( nPos < (long) maData.size() ) 1923 pData = maData[ nPos ]; 1924 else 1925 pData = NULL; 1926 1927 if ( pData ) 1928 if ( ! pData->mbModified ) 1929 return pData->mnCurPos; 1930 else 1931 { 1932 OSL_ENSURE( sal_False, "SortedEntryList: Can't get value for modified entry!"); 1933 return 0; 1934 } 1935 else 1936 { 1937 OSL_ENSURE( sal_False, "SortedEntryList: invalid pos!"); 1938 return 0; 1939 } 1940 } 1941 1942 //------------------------------------------------------------------------- 1943 //------------------------------------------------------------------------- 1944 //------------------------------------------------------------------------- 1945 void SimpleList::Remove( sal_uInt32 nPos ) 1946 { 1947 if ( nPos < (sal_uInt32) maData.size() ) 1948 { 1949 maData.erase( maData.begin() + nPos ); 1950 } 1951 } 1952 1953 //------------------------------------------------------------------------- 1954 void SimpleList::Remove( void* pData ) 1955 { 1956 sal_Bool bFound = sal_False; 1957 sal_uInt32 i; 1958 1959 for ( i = 0; i < (sal_uInt32) maData.size(); i++ ) 1960 { 1961 if ( maData[ i ] == pData ) 1962 { 1963 bFound = sal_True; 1964 break; 1965 } 1966 } 1967 1968 if ( bFound ) 1969 maData.erase( maData.begin() + i ); 1970 } 1971 1972 //------------------------------------------------------------------------- 1973 void SimpleList::Insert( void* pData, sal_uInt32 nPos ) 1974 { 1975 if ( nPos < (sal_uInt32) maData.size() ) 1976 maData.insert( maData.begin() + nPos, pData ); 1977 else 1978 maData.push_back( pData ); 1979 } 1980 1981 //------------------------------------------------------------------------- 1982 void* SimpleList::GetObject( sal_uInt32 nPos ) const 1983 { 1984 if ( nPos < (sal_uInt32) maData.size() ) 1985 return maData[ nPos ]; 1986 else 1987 return NULL; 1988 } 1989 1990 //------------------------------------------------------------------------- 1991 void SimpleList::Replace( void* pData, sal_uInt32 nPos ) 1992 { 1993 if ( nPos < (sal_uInt32) maData.size() ) 1994 maData[ nPos ] = pData; 1995 } 1996 1997 //------------------------------------------------------------------------- 1998 // 1999 // class SRSPropertySetInfo. 2000 // 2001 //------------------------------------------------------------------------- 2002 2003 SRSPropertySetInfo::SRSPropertySetInfo() 2004 { 2005 maProps[0].Name = OUString::createFromAscii( "RowCount" ); 2006 maProps[0].Handle = -1; 2007 maProps[0].Type = ::getCppuType( (const OUString*) NULL ); 2008 maProps[0].Attributes = -1; 2009 2010 maProps[1].Name = OUString::createFromAscii( "IsRowCountFinal" ); 2011 maProps[1].Handle = -1; 2012 maProps[1].Type = ::getBooleanCppuType(); 2013 maProps[1].Attributes = -1; 2014 } 2015 2016 //------------------------------------------------------------------------- 2017 SRSPropertySetInfo::~SRSPropertySetInfo() 2018 {} 2019 2020 //------------------------------------------------------------------------- 2021 // XInterface methods. 2022 //------------------------------------------------------------------------- 2023 2024 XINTERFACE_IMPL_2( SRSPropertySetInfo, 2025 XTypeProvider, 2026 XPropertySetInfo ); 2027 2028 //------------------------------------------------------------------------- 2029 // XTypeProvider methods. 2030 //------------------------------------------------------------------------- 2031 2032 XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo, 2033 XTypeProvider, 2034 XPropertySetInfo ); 2035 2036 //------------------------------------------------------------------------- 2037 // XPropertySetInfo methods. 2038 //------------------------------------------------------------------------- 2039 Sequence< Property > SAL_CALL 2040 SRSPropertySetInfo::getProperties() throw( RuntimeException ) 2041 { 2042 return Sequence < Property > ( maProps, 2 ); 2043 } 2044 2045 //------------------------------------------------------------------------- 2046 Property SAL_CALL 2047 SRSPropertySetInfo::getPropertyByName( const OUString& Name ) 2048 throw( UnknownPropertyException, RuntimeException ) 2049 { 2050 if ( Name.compareToAscii( "RowCount" ) == 0 ) 2051 return maProps[0]; 2052 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 ) 2053 return maProps[1]; 2054 else 2055 throw UnknownPropertyException(); 2056 } 2057 2058 //------------------------------------------------------------------------- 2059 sal_Bool SAL_CALL 2060 SRSPropertySetInfo::hasPropertyByName( const OUString& Name ) 2061 throw( RuntimeException ) 2062 { 2063 if ( Name.compareToAscii( "RowCount" ) == 0 ) 2064 return sal_True; 2065 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 ) 2066 return sal_True; 2067 else 2068 return sal_False; 2069 } 2070 2071