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