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