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