xref: /trunk/main/ucb/source/sorter/sortresult.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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