merge the formfield patch from ooo-build
[ooovba.git] / ucb / source / sorter / sortresult.cxx
blob9fc3ffe764ac4feaf9c18e7ea754a8a043bc3bd4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sortresult.cxx,v $
10 * $Revision: 1.18.22.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 #include <vector>
35 #include <sortresult.hxx>
36 #include <cppuhelper/interfacecontainer.hxx>
37 #include <com/sun/star/sdbc/DataType.hpp>
38 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
39 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
40 #include <com/sun/star/ucb/ListActionType.hpp>
41 #include <com/sun/star/ucb/XAnyCompare.hpp>
42 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
43 #include <osl/diagnose.h>
45 //-----------------------------------------------------------------------------
46 using namespace com::sun::star::beans;
47 using namespace com::sun::star::container;
48 using namespace com::sun::star::io;
49 using namespace com::sun::star::lang;
50 using namespace com::sun::star::sdbc;
51 using namespace com::sun::star::ucb;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::util;
54 using namespace cppu;
55 using namespace rtl;
57 //=========================================================================
59 // The mutex to synchronize access to containers.
60 static osl::Mutex& getContainerMutex()
62 static osl::Mutex* pMutex = NULL;
63 if( !pMutex )
65 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
66 if( !pMutex )
68 static osl::Mutex aMutex;
69 pMutex = &aMutex;
73 return *pMutex;
76 //==========================================================================
78 struct SortInfo
80 sal_Bool mbUseOwnCompare;
81 sal_Bool mbAscending;
82 sal_Bool mbCaseSensitive;
83 sal_Int32 mnColumn;
84 sal_Int32 mnType;
85 SortInfo* mpNext;
86 Reference < XAnyCompare > mxCompareFunction;
89 //-----------------------------------------------------------------------------
91 struct SortListData
93 sal_Bool mbModified;
94 long mnCurPos;
95 long mnOldPos;
97 SortListData( long nPos, sal_Bool bModified = sal_False );
100 //============================================================================
102 // class SRSPropertySetInfo.
104 //============================================================================
106 class SRSPropertySetInfo :
107 public OWeakObject,
108 public XTypeProvider,
109 public XPropertySetInfo
111 Property maProps[2];
113 private:
115 public:
116 SRSPropertySetInfo();
117 virtual ~SRSPropertySetInfo();
119 // XInterface
120 XINTERFACE_DECL()
122 // XTypeProvider
123 XTYPEPROVIDER_DECL()
125 // XPropertySetInfo
126 virtual Sequence< Property > SAL_CALL getProperties()
127 throw( RuntimeException );
128 virtual Property SAL_CALL getPropertyByName( const OUString& aName )
129 throw( UnknownPropertyException, RuntimeException );
130 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
131 throw( RuntimeException );
134 //=========================================================================
136 // PropertyChangeListenerContainer_Impl.
138 //=========================================================================
140 struct equalStr_Impl
142 bool operator()( const OUString& s1, const OUString& s2 ) const
144 return !!( s1 == s2 );
148 struct hashStr_Impl
150 size_t operator()( const OUString& rName ) const
152 return rName.hashCode();
156 typedef OMultiTypeInterfaceContainerHelperVar
158 OUString,
159 hashStr_Impl,
160 equalStr_Impl
161 > PropertyChangeListenerContainer_Impl;
163 //=========================================================================
165 // class PropertyChangeListeners_Impl
167 //=========================================================================
169 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
171 public:
172 PropertyChangeListeners_Impl()
173 : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
176 //==========================================================================
177 SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
179 mpDisposeEventListeners = NULL;
180 mpPropChangeListeners = NULL;
181 mpVetoChangeListeners = NULL;
182 mpPropSetInfo = NULL;
184 mxOriginal = aResult;
185 mpSortInfo = NULL;
186 mnLastSort = 0;
187 mnCurEntry = 0;
188 mnCount = 0;
189 mbIsCopy = sal_False;
192 //--------------------------------------------------------------------------
193 SortedResultSet::~SortedResultSet()
195 mxOriginal.clear();
196 mxOther.clear();
198 if ( !mbIsCopy )
200 SortInfo *pInfo = mpSortInfo;
201 while ( pInfo )
203 mpSortInfo = pInfo->mpNext;
204 delete pInfo;
205 pInfo = mpSortInfo;
209 mpSortInfo = NULL;
211 if ( mpPropSetInfo )
212 mpPropSetInfo->release();
214 delete mpPropChangeListeners;
215 delete mpVetoChangeListeners;
218 //--------------------------------------------------------------------------
219 // XInterface methods.
220 //--------------------------------------------------------------------------
222 XINTERFACE_IMPL_9( SortedResultSet,
223 XTypeProvider,
224 XServiceInfo,
225 XComponent,
226 XContentAccess,
227 XResultSet,
228 XRow,
229 XCloseable,
230 XResultSetMetaDataSupplier,
231 XPropertySet );
233 //--------------------------------------------------------------------------
234 // XTypeProvider methods.
235 //--------------------------------------------------------------------------
237 XTYPEPROVIDER_IMPL_9( SortedResultSet,
238 XTypeProvider,
239 XServiceInfo,
240 XComponent,
241 XContentAccess,
242 XResultSet,
243 XRow,
244 XCloseable,
245 XResultSetMetaDataSupplier,
246 XPropertySet );
248 //--------------------------------------------------------------------------
249 // XServiceInfo methods.
250 //--------------------------------------------------------------------------
252 XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet,
253 OUString::createFromAscii(
254 "com.sun.star.comp.ucb.SortedResultSet" ),
255 OUString::createFromAscii(
256 RESULTSET_SERVICE_NAME ) );
258 //--------------------------------------------------------------------------
259 // XComponent methods.
260 //--------------------------------------------------------------------------
261 void SAL_CALL SortedResultSet::dispose()
262 throw( RuntimeException )
264 osl::Guard< osl::Mutex > aGuard( maMutex );
266 if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
268 EventObject aEvt;
269 aEvt.Source = static_cast< XComponent * >( this );
270 mpDisposeEventListeners->disposeAndClear( aEvt );
273 if ( mpPropChangeListeners )
275 EventObject aEvt;
276 aEvt.Source = static_cast< XPropertySet * >( this );
277 mpPropChangeListeners->disposeAndClear( aEvt );
280 if ( mpVetoChangeListeners )
282 EventObject aEvt;
283 aEvt.Source = static_cast< XPropertySet * >( this );
284 mpVetoChangeListeners->disposeAndClear( aEvt );
287 mxOriginal.clear();
288 mxOther.clear();
291 //--------------------------------------------------------------------------
292 void SAL_CALL SortedResultSet::addEventListener(
293 const Reference< XEventListener >& Listener )
294 throw( RuntimeException )
296 osl::Guard< osl::Mutex > aGuard( maMutex );
298 if ( !mpDisposeEventListeners )
299 mpDisposeEventListeners =
300 new OInterfaceContainerHelper( getContainerMutex() );
302 mpDisposeEventListeners->addInterface( Listener );
305 //--------------------------------------------------------------------------
306 void SAL_CALL SortedResultSet::removeEventListener(
307 const Reference< XEventListener >& Listener )
308 throw( RuntimeException )
310 osl::Guard< osl::Mutex > aGuard( maMutex );
312 if ( mpDisposeEventListeners )
313 mpDisposeEventListeners->removeInterface( Listener );
316 //--------------------------------------------------------------------------
317 // XContentAccess methods.
318 //--------------------------------------------------------------------------
320 OUString SAL_CALL
321 SortedResultSet::queryContentIdentifierString()
322 throw( RuntimeException )
324 osl::Guard< osl::Mutex > aGuard( maMutex );
325 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
328 //--------------------------------------------------------------------------
329 Reference< XContentIdentifier > SAL_CALL
330 SortedResultSet::queryContentIdentifier()
331 throw( RuntimeException )
333 osl::Guard< osl::Mutex > aGuard( maMutex );
334 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
337 //--------------------------------------------------------------------------
338 Reference< XContent > SAL_CALL
339 SortedResultSet::queryContent()
340 throw( RuntimeException )
342 osl::Guard< osl::Mutex > aGuard( maMutex );
343 return Reference< XContentAccess >::query(mxOriginal)->queryContent();
347 //--------------------------------------------------------------------------
348 // XResultSet methods.
349 //--------------------------------------------------------------------------
350 sal_Bool SAL_CALL SortedResultSet::next()
351 throw ( SQLException, RuntimeException )
353 osl::Guard< osl::Mutex > aGuard( maMutex );
355 mnCurEntry++;
357 if ( mnCurEntry > 0 )
359 if ( mnCurEntry <= mnCount )
361 sal_Int32 nIndex = maS2O[ mnCurEntry ];
362 return mxOriginal->absolute( nIndex );
364 else
366 mnCurEntry = mnCount + 1;
369 return sal_False;
372 //-------------------------------------------------------------------------
373 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
374 throw ( SQLException, RuntimeException )
376 if ( mnCurEntry )
377 return sal_False;
378 else
379 return sal_True;
382 //-------------------------------------------------------------------------
383 sal_Bool SAL_CALL SortedResultSet::isAfterLast()
384 throw ( SQLException, RuntimeException )
386 if ( mnCurEntry > mnCount )
387 return sal_True;
388 else
389 return sal_False;
392 //-------------------------------------------------------------------------
393 sal_Bool SAL_CALL SortedResultSet::isFirst()
394 throw ( SQLException, RuntimeException )
396 if ( mnCurEntry == 1 )
397 return sal_True;
398 else
399 return sal_False;
402 //-------------------------------------------------------------------------
403 sal_Bool SAL_CALL SortedResultSet::isLast()
404 throw ( SQLException, RuntimeException )
406 if ( mnCurEntry == mnCount )
407 return sal_True;
408 else
409 return sal_False;
412 //-------------------------------------------------------------------------
413 void SAL_CALL SortedResultSet::beforeFirst()
414 throw ( SQLException, RuntimeException )
416 osl::Guard< osl::Mutex > aGuard( maMutex );
417 mnCurEntry = 0;
418 mxOriginal->beforeFirst();
421 //-------------------------------------------------------------------------
422 void SAL_CALL SortedResultSet::afterLast()
423 throw ( SQLException, RuntimeException )
425 osl::Guard< osl::Mutex > aGuard( maMutex );
426 mnCurEntry = mnCount+1;
427 mxOriginal->afterLast();
430 //-------------------------------------------------------------------------
431 sal_Bool SAL_CALL SortedResultSet::first()
432 throw ( SQLException, RuntimeException )
434 osl::Guard< osl::Mutex > aGuard( maMutex );
436 if ( mnCount )
438 mnCurEntry = 1;
439 sal_Int32 nIndex = maS2O[ mnCurEntry ];
440 return mxOriginal->absolute( nIndex );
442 else
444 mnCurEntry = 0;
445 return sal_False;
449 //-------------------------------------------------------------------------
450 sal_Bool SAL_CALL SortedResultSet::last()
451 throw ( SQLException, RuntimeException )
453 osl::Guard< osl::Mutex > aGuard( maMutex );
455 if ( mnCount )
457 mnCurEntry = mnCount;
458 sal_Int32 nIndex = maS2O[ mnCurEntry ];
459 return mxOriginal->absolute( nIndex );
461 else
463 mnCurEntry = 0;
464 return sal_False;
468 //-------------------------------------------------------------------------
469 sal_Int32 SAL_CALL SortedResultSet::getRow()
470 throw ( SQLException, RuntimeException )
472 return mnCurEntry;
475 //-------------------------------------------------------------------------
477 moves the cursor to the given row number in the result set.
478 <p>If the row number is positive, the cursor moves to the given row
479 number with respect to the beginning of the result set. The first
480 row is row 1, the second is row 2, and so on.
481 <p>If the given row number is negative, the cursor moves to an
482 absolute row position with respect to the end of the result set.
483 For example, calling <code>moveToPosition(-1)</code> positions the
484 cursor on the last row, <code>moveToPosition(-2)</code> indicates the
485 next-to-last row, and so on.
486 <p>An attempt to position the cursor beyond the first/last row in the
487 result set leaves the cursor before/after the first/last row,
488 respectively.
489 <p>Note: Calling <code>moveToPosition(1)</code> is the same
490 as calling <code>moveToFirst()</code>. Calling
491 <code>moveToPosition(-1)</code> is the same as calling
492 <code>moveToLast()</code>.
493 @param row
494 is the number of rows to move. Could be negative.
495 @returns
496 <sal_True/> if the cursor is on a row; <sal_False/> otherwise
497 @throws SQLException
498 if a database access error occurs or if row is 0, or the result set
499 type is FORWARD_ONLY.
501 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
502 throw ( SQLException, RuntimeException )
504 osl::Guard< osl::Mutex > aGuard( maMutex );
506 sal_Int32 nIndex;
508 if ( row > 0 )
510 if ( row <= mnCount )
512 mnCurEntry = row;
513 nIndex = maS2O[ mnCurEntry ];
514 return mxOriginal->absolute( nIndex );
516 else
518 mnCurEntry = mnCount + 1;
519 return sal_False;
522 else if ( row == 0 )
524 throw SQLException();
526 else
528 if ( mnCount + row + 1 > 0 )
530 mnCurEntry = mnCount + row + 1;
531 nIndex = maS2O[ mnCurEntry ];
532 return mxOriginal->absolute( nIndex );
534 else
536 mnCurEntry = 0;
537 return sal_False;
542 //-------------------------------------------------------------------------
544 moves the cursor a relative number of rows, either positive or negative.
546 Attempting to move beyond the first/last row in the result set positions
547 the cursor before/after the first/last row. Calling
548 <code>moveRelative(0)</code> is valid, but does not change the cursor
549 position.
550 <p>Note: Calling <code>moveRelative(1)</code> is different from calling
551 <code>moveNext()</code> because is makes sense to call
552 <code>moveNext()</code> when there is no current row, for example,
553 when the cursor is positioned before the first row or after the last
554 row of the result set.
555 @param rows
556 is the number of rows to move. Could be negative.
557 @returns
558 <sal_True/> if the cursor is on a valid row; <sal_False/> if it is off
559 the result set.
560 @throws SQLException
561 if a database access error occurs or if there is no
562 current row, or the result set type is FORWARD_ONLY.
564 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
565 throw ( SQLException, RuntimeException )
567 osl::Guard< osl::Mutex > aGuard( maMutex );
569 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
571 throw SQLException();
574 if ( rows == 0 )
575 return sal_True;
577 sal_Int32 nTmp = mnCurEntry + rows;
579 if ( nTmp <= 0 )
581 mnCurEntry = 0;
582 return sal_False;
584 else if ( nTmp > mnCount )
586 mnCurEntry = mnCount + 1;
587 return sal_False;
589 else
591 mnCurEntry = nTmp;
592 nTmp = maS2O[ mnCurEntry ];
593 return mxOriginal->absolute( nTmp );
597 //-------------------------------------------------------------------------
599 moves the cursor to the previous row in the result set.
600 <p>Note: <code>previous()</code> is not the same as
601 <code>relative(-1)</code> because it makes sense to call
602 <code>previous()</code> when there is no current row.
603 @returns <sal_True/> if the cursor is on a valid row; <sal_False/> if it is off
604 the result set.
605 @throws SQLException
606 if a database access error occurs or the result set type
607 is FORWARD_ONLY.
609 sal_Bool SAL_CALL SortedResultSet::previous()
610 throw ( SQLException, RuntimeException )
612 osl::Guard< osl::Mutex > aGuard( maMutex );
614 mnCurEntry -= 1;
616 if ( mnCurEntry > 0 )
618 if ( mnCurEntry <= mnCount )
620 sal_Int32 nIndex = maS2O[ mnCurEntry ];
621 return mxOriginal->absolute( nIndex );
624 else
625 mnCurEntry = 0;
627 return sal_False;
630 //-------------------------------------------------------------------------
631 void SAL_CALL SortedResultSet::refreshRow()
632 throw ( SQLException, RuntimeException )
634 osl::Guard< osl::Mutex > aGuard( maMutex );
636 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
638 throw SQLException();
641 mxOriginal->refreshRow();
644 //-------------------------------------------------------------------------
645 sal_Bool SAL_CALL SortedResultSet::rowUpdated()
646 throw ( SQLException, RuntimeException )
648 osl::Guard< osl::Mutex > aGuard( maMutex );
650 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
652 throw SQLException();
655 return mxOriginal->rowUpdated();
658 //-------------------------------------------------------------------------
659 sal_Bool SAL_CALL SortedResultSet::rowInserted()
660 throw ( SQLException, RuntimeException )
662 osl::Guard< osl::Mutex > aGuard( maMutex );
664 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
666 throw SQLException();
669 return mxOriginal->rowInserted();
672 //-------------------------------------------------------------------------
673 sal_Bool SAL_CALL SortedResultSet::rowDeleted()
674 throw ( SQLException, RuntimeException )
676 osl::Guard< osl::Mutex > aGuard( maMutex );
678 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
680 throw SQLException();
683 return mxOriginal->rowDeleted();
686 //-------------------------------------------------------------------------
687 Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
688 throw ( SQLException, RuntimeException )
690 osl::Guard< osl::Mutex > aGuard( maMutex );
692 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
694 throw SQLException();
697 return mxOriginal->getStatement();
700 //--------------------------------------------------------------------------
701 // XRow methods.
702 //--------------------------------------------------------------------------
704 sal_Bool SAL_CALL SortedResultSet::wasNull()
705 throw( SQLException, RuntimeException )
707 osl::Guard< osl::Mutex > aGuard( maMutex );
708 return Reference< XRow >::query(mxOriginal)->wasNull();
711 //-------------------------------------------------------------------------
712 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
713 throw( SQLException, RuntimeException )
715 osl::Guard< osl::Mutex > aGuard( maMutex );
716 return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
719 //-------------------------------------------------------------------------
720 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
721 throw( SQLException, RuntimeException )
723 osl::Guard< osl::Mutex > aGuard( maMutex );
724 return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
727 //-------------------------------------------------------------------------
728 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
729 throw( SQLException, RuntimeException )
731 osl::Guard< osl::Mutex > aGuard( maMutex );
732 return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
735 //-------------------------------------------------------------------------
736 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
737 throw( SQLException, RuntimeException )
739 osl::Guard< osl::Mutex > aGuard( maMutex );
740 return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
743 //-------------------------------------------------------------------------
744 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
745 throw( SQLException, RuntimeException )
747 osl::Guard< osl::Mutex > aGuard( maMutex );
748 return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
750 //-------------------------------------------------------------------------
751 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
752 throw( SQLException, RuntimeException )
754 osl::Guard< osl::Mutex > aGuard( maMutex );
755 return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
758 //-------------------------------------------------------------------------
759 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
760 throw( SQLException, RuntimeException )
762 osl::Guard< osl::Mutex > aGuard( maMutex );
763 return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
766 //-------------------------------------------------------------------------
767 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
768 throw( SQLException, RuntimeException )
770 osl::Guard< osl::Mutex > aGuard( maMutex );
771 return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
774 //-------------------------------------------------------------------------
775 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
776 throw( SQLException, RuntimeException )
778 osl::Guard< osl::Mutex > aGuard( maMutex );
779 return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
782 //-------------------------------------------------------------------------
783 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
784 throw( SQLException, RuntimeException )
786 osl::Guard< osl::Mutex > aGuard( maMutex );
787 return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
790 //-------------------------------------------------------------------------
791 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
792 throw( SQLException, RuntimeException )
794 osl::Guard< osl::Mutex > aGuard( maMutex );
795 return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
798 //-------------------------------------------------------------------------
799 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
800 throw( SQLException, RuntimeException )
802 osl::Guard< osl::Mutex > aGuard( maMutex );
803 return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
806 //-------------------------------------------------------------------------
807 Reference< XInputStream > SAL_CALL
808 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
809 throw( SQLException, RuntimeException )
811 osl::Guard< osl::Mutex > aGuard( maMutex );
812 return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
815 //-------------------------------------------------------------------------
816 Reference< XInputStream > SAL_CALL
817 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
818 throw( SQLException, RuntimeException )
820 osl::Guard< osl::Mutex > aGuard( maMutex );
821 return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
824 //-------------------------------------------------------------------------
825 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
826 const Reference< XNameAccess >& typeMap )
827 throw( SQLException, RuntimeException )
829 osl::Guard< osl::Mutex > aGuard( maMutex );
830 return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
831 typeMap);
834 //-------------------------------------------------------------------------
835 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
836 throw( SQLException, RuntimeException )
838 osl::Guard< osl::Mutex > aGuard( maMutex );
839 return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
842 //-------------------------------------------------------------------------
843 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
844 throw( SQLException, RuntimeException )
846 osl::Guard< osl::Mutex > aGuard( maMutex );
847 return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
850 //-------------------------------------------------------------------------
851 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
852 throw( SQLException, RuntimeException )
854 osl::Guard< osl::Mutex > aGuard( maMutex );
855 return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
858 //-------------------------------------------------------------------------
859 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
860 throw( SQLException, RuntimeException )
862 osl::Guard< osl::Mutex > aGuard( maMutex );
863 return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
867 //--------------------------------------------------------------------------
868 // XCloseable methods.
869 //--------------------------------------------------------------------------
871 void SAL_CALL SortedResultSet::close()
872 throw( SQLException, RuntimeException )
874 osl::Guard< osl::Mutex > aGuard( maMutex );
875 Reference< XCloseable >::query(mxOriginal)->close();
878 //--------------------------------------------------------------------------
879 // XResultSetMetaDataSupplier methods.
880 //--------------------------------------------------------------------------
882 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
883 throw( SQLException, RuntimeException )
885 osl::Guard< osl::Mutex > aGuard( maMutex );
886 return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
890 //--------------------------------------------------------------------------
891 // XPropertySet methods.
892 //--------------------------------------------------------------------------
894 Reference< XPropertySetInfo > SAL_CALL
895 SortedResultSet::getPropertySetInfo() throw( RuntimeException )
897 osl::Guard< osl::Mutex > aGuard( maMutex );
899 if ( !mpPropSetInfo )
901 mpPropSetInfo = new SRSPropertySetInfo();
902 mpPropSetInfo->acquire();
905 return Reference< XPropertySetInfo >( mpPropSetInfo );
908 //--------------------------------------------------------------------------
909 void SAL_CALL SortedResultSet::setPropertyValue(
910 const OUString& PropertyName,
911 const Any& )
912 throw( UnknownPropertyException,
913 PropertyVetoException,
914 IllegalArgumentException,
915 WrappedTargetException,
916 RuntimeException )
918 osl::Guard< osl::Mutex > aGuard( maMutex );
920 if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) ||
921 ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) )
922 throw IllegalArgumentException();
923 else
924 throw UnknownPropertyException();
927 //--------------------------------------------------------------------------
928 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
929 throw( UnknownPropertyException,
930 WrappedTargetException,
931 RuntimeException )
933 osl::Guard< osl::Mutex > aGuard( maMutex );
935 Any aRet;
937 if ( PropertyName.compareToAscii( "RowCount" ) == 0 )
939 aRet <<= maS2O.Count();
941 else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 )
943 sal_uInt32 nOrgCount = 0;
944 sal_Bool bOrgFinal = false;
945 Any aOrgRet;
947 aRet <<= (sal_Bool) sal_False;
949 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
950 getPropertyValue( PropertyName );
951 aOrgRet >>= bOrgFinal;
953 if ( bOrgFinal )
955 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
956 getPropertyValue( OUString::createFromAscii( "RowCount" ) );
957 aOrgRet >>= nOrgCount;
958 if ( nOrgCount == maS2O.Count() )
959 aRet <<= (sal_Bool) sal_True;
962 else
963 throw UnknownPropertyException();
965 return aRet;
968 //--------------------------------------------------------------------------
969 void SAL_CALL SortedResultSet::addPropertyChangeListener(
970 const OUString& PropertyName,
971 const Reference< XPropertyChangeListener >& Listener )
972 throw( UnknownPropertyException,
973 WrappedTargetException,
974 RuntimeException )
976 osl::Guard< osl::Mutex > aGuard( maMutex );
978 if ( !mpPropChangeListeners )
979 mpPropChangeListeners =
980 new PropertyChangeListeners_Impl();
982 mpPropChangeListeners->addInterface( PropertyName, Listener );
985 //--------------------------------------------------------------------------
986 void SAL_CALL SortedResultSet::removePropertyChangeListener(
987 const OUString& PropertyName,
988 const Reference< XPropertyChangeListener >& Listener )
989 throw( UnknownPropertyException,
990 WrappedTargetException,
991 RuntimeException )
993 osl::Guard< osl::Mutex > aGuard( maMutex );
995 if ( mpPropChangeListeners )
996 mpPropChangeListeners->removeInterface( PropertyName, Listener );
999 //--------------------------------------------------------------------------
1000 void SAL_CALL SortedResultSet::addVetoableChangeListener(
1001 const OUString& PropertyName,
1002 const Reference< XVetoableChangeListener >& Listener )
1003 throw( UnknownPropertyException,
1004 WrappedTargetException,
1005 RuntimeException )
1007 osl::Guard< osl::Mutex > aGuard( maMutex );
1009 if ( !mpVetoChangeListeners )
1010 mpVetoChangeListeners =
1011 new PropertyChangeListeners_Impl();
1013 mpVetoChangeListeners->addInterface( PropertyName, Listener );
1016 //--------------------------------------------------------------------------
1017 void SAL_CALL SortedResultSet::removeVetoableChangeListener(
1018 const OUString& PropertyName,
1019 const Reference< XVetoableChangeListener >& Listener )
1020 throw( UnknownPropertyException,
1021 WrappedTargetException,
1022 RuntimeException )
1024 osl::Guard< osl::Mutex > aGuard( maMutex );
1026 if ( mpVetoChangeListeners )
1027 mpVetoChangeListeners->removeInterface( PropertyName, Listener );
1030 //--------------------------------------------------------------------------
1031 // private methods
1032 //--------------------------------------------------------------------------
1033 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1034 Reference < XResultSet > xResultTwo,
1035 long nIndexOne, long nIndexTwo,
1036 SortInfo* pSortInfo )
1038 throw( SQLException, RuntimeException )
1040 Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
1041 Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
1043 long nCompare = 0;
1044 long nColumn = pSortInfo->mnColumn;
1046 switch ( pSortInfo->mnType )
1048 case DataType::BIT :
1049 case DataType::TINYINT :
1050 case DataType::SMALLINT :
1051 case DataType::INTEGER :
1053 sal_Int32 aOne = 0;
1054 sal_Int32 aTwo = 0;
1056 if ( xResultOne->absolute( nIndexOne ) )
1057 aOne = xRowOne->getInt( nColumn );
1058 if ( xResultTwo->absolute( nIndexTwo ) )
1059 aTwo = xRowTwo->getInt( nColumn );
1061 if ( aOne < aTwo )
1062 nCompare = -1;
1063 else if ( aOne == aTwo )
1064 nCompare = 0;
1065 else
1066 nCompare = 1;
1068 break;
1070 case DataType::BIGINT :
1072 sal_Int64 aOne = 0;
1073 sal_Int64 aTwo = 0;
1075 if ( xResultOne->absolute( nIndexOne ) )
1076 aOne = xRowOne->getLong( nColumn );
1077 if ( xResultTwo->absolute( nIndexTwo ) )
1078 aTwo = xRowTwo->getLong( nColumn );
1080 if ( aOne < aTwo )
1081 nCompare = -1;
1082 else if ( aOne == aTwo )
1083 nCompare = 0;
1084 else
1085 nCompare = 1;
1087 break;
1089 case DataType::CHAR :
1090 case DataType::VARCHAR :
1091 case DataType::LONGVARCHAR :
1093 OUString aOne, aTwo;
1095 if ( xResultOne->absolute( nIndexOne ) )
1096 aOne = xRowOne->getString( nColumn );
1097 if ( xResultTwo->absolute( nIndexTwo ) )
1098 aTwo = xRowTwo->getString( nColumn );
1100 if ( ! pSortInfo->mbCaseSensitive )
1102 aOne = aOne.toAsciiLowerCase();
1103 aTwo = aTwo.toAsciiLowerCase();
1106 nCompare = aOne.compareTo( aTwo );
1107 break;
1109 case DataType::DATE :
1111 Date aOne, aTwo;
1112 sal_Int32 nTmp;
1114 if ( xResultOne->absolute( nIndexOne ) )
1115 aOne = xRowOne->getDate( nColumn );
1116 if ( xResultTwo->absolute( nIndexTwo ) )
1117 aTwo = xRowTwo->getDate( nColumn );
1119 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1120 if ( !nTmp ) {
1121 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1122 if ( !nTmp )
1123 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1126 if ( nTmp < 0 )
1127 nCompare = -1;
1128 else if ( nTmp == 0 )
1129 nCompare = 0;
1130 else
1131 nCompare = 1;
1133 break;
1135 case DataType::TIME :
1137 Time aOne, aTwo;
1138 sal_Int32 nTmp;
1140 if ( xResultOne->absolute( nIndexOne ) )
1141 aOne = xRowOne->getTime( nColumn );
1142 if ( xResultTwo->absolute( nIndexTwo ) )
1143 aTwo = xRowTwo->getTime( nColumn );
1145 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1146 if ( !nTmp ) {
1147 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1148 if ( !nTmp ) {
1149 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1150 if ( !nTmp )
1151 nTmp = (sal_Int32) aTwo.HundredthSeconds
1152 - (sal_Int32) aOne.HundredthSeconds;
1155 if ( nTmp < 0 )
1156 nCompare = -1;
1157 else if ( nTmp == 0 )
1158 nCompare = 0;
1159 else
1160 nCompare = 1;
1162 break;
1164 case DataType::TIMESTAMP :
1166 DateTime aOne, aTwo;
1167 sal_Int32 nTmp;
1169 if ( xResultOne->absolute( nIndexOne ) )
1170 aOne = xRowOne->getTimestamp( nColumn );
1171 if ( xResultTwo->absolute( nIndexTwo ) )
1172 aTwo = xRowTwo->getTimestamp( nColumn );
1174 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1175 if ( !nTmp ) {
1176 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1177 if ( !nTmp ) {
1178 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1179 if ( !nTmp ) {
1180 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1181 if ( !nTmp ) {
1182 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1183 if ( !nTmp ) {
1184 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1185 if ( !nTmp )
1186 nTmp = (sal_Int32) aTwo.HundredthSeconds
1187 - (sal_Int32) aOne.HundredthSeconds;
1188 }}}}}
1190 if ( nTmp < 0 )
1191 nCompare = -1;
1192 else if ( nTmp == 0 )
1193 nCompare = 0;
1194 else
1195 nCompare = 1;
1197 break;
1199 case DataType::REAL :
1201 float aOne = 0;
1202 float aTwo = 0;
1204 if ( xResultOne->absolute( nIndexOne ) )
1205 aOne = xRowOne->getFloat( nColumn );
1206 if ( xResultTwo->absolute( nIndexTwo ) )
1207 aTwo = xRowTwo->getFloat( nColumn );
1209 if ( aOne < aTwo )
1210 nCompare = -1;
1211 else if ( aOne == aTwo )
1212 nCompare = 0;
1213 else
1214 nCompare = 1;
1216 break;
1218 case DataType::FLOAT :
1219 case DataType::DOUBLE :
1221 double aOne = 0;
1222 double aTwo = 0;
1224 if ( xResultOne->absolute( nIndexOne ) )
1225 aOne = xRowOne->getDouble( nColumn );
1226 if ( xResultTwo->absolute( nIndexTwo ) )
1227 aTwo = xRowTwo->getDouble( nColumn );
1229 if ( aOne < aTwo )
1230 nCompare = -1;
1231 else if ( aOne == aTwo )
1232 nCompare = 0;
1233 else
1234 nCompare = 1;
1236 break;
1238 default:
1240 OSL_ENSURE( sal_False, "DataType not supported for compare!" );
1244 return nCompare;
1247 //--------------------------------------------------------------------------
1248 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1249 Reference < XResultSet > xResultTwo,
1250 long nIndexOne, long nIndexTwo )
1251 throw( SQLException, RuntimeException )
1253 long nCompare = 0;
1254 SortInfo* pInfo = mpSortInfo;
1256 while ( !nCompare && pInfo )
1258 if ( pInfo->mbUseOwnCompare )
1260 nCompare = CompareImpl( xResultOne, xResultTwo,
1261 nIndexOne, nIndexTwo, pInfo );
1263 else
1265 Any aOne, aTwo;
1267 Reference < XRow > xRowOne =
1268 Reference< XRow >::query( xResultOne );
1269 Reference < XRow > xRowTwo =
1270 Reference< XRow >::query( xResultTwo );
1272 if ( xResultOne->absolute( nIndexOne ) )
1273 aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
1274 if ( xResultTwo->absolute( nIndexTwo ) )
1275 aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
1277 nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1280 if ( ! pInfo->mbAscending )
1281 nCompare = - nCompare;
1283 pInfo = pInfo->mpNext;
1286 return nCompare;
1289 //--------------------------------------------------------------------------
1290 long SortedResultSet::Compare( SortListData *pOne,
1291 SortListData *pTwo )
1292 throw( SQLException, RuntimeException )
1294 long nIndexOne;
1295 long nIndexTwo;
1297 Reference < XResultSet > xResultOne;
1298 Reference < XResultSet > xResultTwo;
1300 if ( pOne->mbModified )
1302 xResultOne = mxOther;
1303 nIndexOne = pOne->mnOldPos;
1305 else
1307 xResultOne = mxOriginal;
1308 nIndexOne = pOne->mnCurPos;
1311 if ( pTwo->mbModified )
1313 xResultTwo = mxOther;
1314 nIndexTwo = pTwo->mnOldPos;
1316 else
1318 xResultTwo = mxOriginal;
1319 nIndexTwo = pTwo->mnCurPos;
1322 long nCompare;
1323 nCompare = CompareImpl( xResultOne, xResultTwo,
1324 nIndexOne, nIndexTwo );
1325 return nCompare;
1328 //--------------------------------------------------------------------------
1329 long SortedResultSet::FindPos( SortListData *pEntry,
1330 long _nStart, long _nEnd )
1331 throw( SQLException, RuntimeException )
1333 if ( _nStart > _nEnd )
1334 return _nStart + 1;
1336 long nStart = _nStart;
1337 long nEnd = _nEnd;
1338 long nMid = 0, nCompare = 0;
1340 SortListData *pMid;
1342 while ( nStart <= nEnd )
1344 nMid = ( nEnd - nStart ) / 2 + nStart;
1345 pMid = maS2O.GetData( nMid );
1346 nCompare = Compare( pEntry, pMid );
1348 if ( !nCompare )
1349 nCompare = ((long) pEntry ) - ( (long) pMid );
1351 if ( nCompare < 0 ) // pEntry < pMid
1352 nEnd = nMid - 1;
1353 else
1354 nStart = nMid + 1;
1357 if ( nCompare < 0 ) // pEntry < pMid
1358 return nMid;
1359 else
1360 return nMid+1;
1363 //--------------------------------------------------------------------------
1364 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1366 osl::Guard< osl::Mutex > aGuard( maMutex );
1368 if ( !mpPropChangeListeners )
1369 return;
1371 // Notify listeners interested especially in the changed property.
1372 OInterfaceContainerHelper* pPropsContainer =
1373 mpPropChangeListeners->getContainer( rEvt.PropertyName );
1374 if ( pPropsContainer )
1376 OInterfaceIteratorHelper aIter( *pPropsContainer );
1377 while ( aIter.hasMoreElements() )
1379 Reference< XPropertyChangeListener > xListener(
1380 aIter.next(), UNO_QUERY );
1381 if ( xListener.is() )
1382 xListener->propertyChange( rEvt );
1386 // Notify listeners interested in all properties.
1387 pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1388 if ( pPropsContainer )
1390 OInterfaceIteratorHelper aIter( *pPropsContainer );
1391 while ( aIter.hasMoreElements() )
1393 Reference< XPropertyChangeListener > xListener(
1394 aIter.next(), UNO_QUERY );
1395 if ( xListener.is() )
1396 xListener->propertyChange( rEvt );
1401 //-------------------------------------------------------------------------
1403 //--------------------------------------------------------------------------
1404 // public methods
1405 //--------------------------------------------------------------------------
1407 void SortedResultSet::CopyData( SortedResultSet *pSource )
1409 const SortedEntryList *pSrcS2O = pSource->GetS2OList();
1410 const SimpleList *pSrcO2S = pSource->GetO2SList();
1412 long i, nCount;
1414 maS2O.Clear();
1415 maO2S.Clear();
1416 maModList.Clear();
1418 maS2O.Insert( NULL, 0 );
1419 maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos
1421 nCount = pSrcS2O->Count();
1423 for ( i=1; i<nCount; i++ )
1425 maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
1426 maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
1429 mnLastSort = maS2O.Count();
1430 mxOther = pSource->GetResultSet();
1432 if ( !mpSortInfo )
1434 mpSortInfo = pSource->GetSortInfo();
1435 mbIsCopy = sal_True;
1439 //--------------------------------------------------------------------------
1440 void SortedResultSet::Initialize(
1441 const Sequence < NumberedSortingInfo > &xSortInfo,
1442 const Reference< XAnyCompareFactory > &xCompFactory )
1444 BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1445 // Insert dummy at pos 0
1446 SortListData *pData = new SortListData( 0 );
1447 maS2O.Insert( pData, 0 );
1449 long nIndex = 1;
1451 // now fetch all the elements from the original result set,
1452 // get there new position in the sorted result set and insert
1453 // an entry in the sorted to original mapping list
1454 try {
1455 while ( mxOriginal->absolute( nIndex ) )
1457 pData = new SortListData( nIndex );
1458 long nPos = FindPos( pData, 1, nIndex-1 );
1460 maS2O.Insert( pData, nPos );
1462 nIndex++;
1465 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::Initialize() : Got unexpected SQLException" ); }
1467 // when we have fetched all the elements, we can create the
1468 // original to sorted mapping list from the s2o list
1469 maO2S.Clear();
1470 maO2S.Insert( NULL, (sal_uInt32) 0 );
1472 // insert some dummy entries first and replace then
1473 // the entries with the right ones
1474 sal_uInt32 i;
1476 for ( i=1; i<maS2O.Count(); i++ )
1477 maO2S.Insert( (void*) 0, i ); // Insert( data, pos )
1478 for ( i=1; i<maS2O.Count(); i++ )
1479 maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
1481 mnCount = maS2O.Count() - 1;
1484 //--------------------------------------------------------------------------
1485 void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal )
1487 osl::Guard< osl::Mutex > aGuard( maMutex );
1489 if ( !mpPropChangeListeners )
1490 return;
1492 try {
1493 // check for propertyChangeEvents
1494 if ( nOldCount != GetCount() )
1496 sal_Bool bIsFinal = sal_False;
1497 PropertyChangeEvent aEvt;
1499 aEvt.PropertyName = OUString::createFromAscii( "RowCount" );
1500 aEvt.Further = sal_False;
1501 aEvt.PropertyHandle = -1;
1502 aEvt.OldValue <<= nOldCount;
1503 aEvt.NewValue <<= GetCount();
1505 PropertyChanged( aEvt );
1507 OUString aName = OUString::createFromAscii( "IsRowCountFinal" );
1508 Any aRet = getPropertyValue( aName );
1509 if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1511 aEvt.PropertyName = aName;
1512 aEvt.Further = sal_False;
1513 aEvt.PropertyHandle = -1;
1514 aEvt.OldValue <<= (sal_Bool) bWasFinal;
1515 aEvt.NewValue <<= (sal_Bool) bIsFinal;
1516 PropertyChanged( aEvt );
1520 catch ( UnknownPropertyException ) {}
1521 catch ( WrappedTargetException ) {}
1524 //-------------------------------------------------------------------------
1525 void SortedResultSet::InsertNew( long nPos, long nCount )
1527 // in der maS2O Liste alle Einträge, die >= nPos sind, um nCount
1528 // erhöhen
1529 SortListData *pData;
1530 long i, nEnd;
1532 nEnd = maS2O.Count();
1533 for ( i=1; i<=nEnd; i++ )
1535 pData = maS2O.GetData( i );
1536 if ( pData->mnCurPos >= nPos )
1538 pData->mnCurPos += nCount;
1542 // und die neuen einträge hinten an die maS2O Liste anhängen bzw
1543 // an der Position nPos in der maO2S Liste einfügen
1544 for ( i=0; i<nCount; i++ )
1546 nEnd += 1;
1547 pData = new SortListData( nEnd );
1549 maS2O.Insert( pData, nEnd ); // Insert( Wert, Position )
1550 maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Wert, Position )
1553 mnCount += nCount;
1556 //-------------------------------------------------------------------------
1557 void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents )
1559 sal_uInt32 i, j;
1560 long nOldLastSort;
1562 // correct mnLastSort first
1563 nOldLastSort = mnLastSort;
1564 if ( nPos <= mnLastSort )
1566 if ( nPos + nCount - 1 <= mnLastSort )
1567 mnLastSort -= nCount;
1568 else
1569 mnLastSort = nPos - 1;
1572 // remove the entries from the lists and correct the positions
1573 // in the original2sorted list
1574 for ( i=0; i < (sal_uInt32) nCount; i++ )
1576 long nSortPos = (long) maO2S.GetObject( nPos );
1577 maO2S.Remove( (sal_uInt32) nPos );
1579 for ( j=1; j<=maO2S.Count(); j++ )
1581 long nVal = (long) maO2S.GetObject( j );
1582 if ( nVal > nSortPos )
1584 --nVal;
1585 maO2S.Replace( (void*) nVal, j );
1589 SortListData *pData = maS2O.Remove( nSortPos );
1590 if ( pData->mbModified )
1591 maModList.Remove( (void*) pData );
1592 delete pData;
1594 // generate remove Event, but not for new entries
1595 if ( nSortPos <= nOldLastSort )
1596 pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
1599 // correct the positions in the sorted list
1600 for ( i=1; i<= maS2O.Count(); i++ )
1602 SortListData *pData = maS2O.GetData( i );
1603 if ( pData->mnCurPos > nPos )
1604 pData->mnCurPos -= nCount;
1607 mnCount -= nCount;
1610 //-------------------------------------------------------------------------
1611 void SortedResultSet::Move( long nPos, long nCount, long nOffset )
1613 if ( !nOffset )
1614 return;
1616 long i, nSortPos, nTo;
1617 SortListData *pData;
1619 for ( i=0; i<nCount; i++ )
1621 nSortPos = (long) maO2S.GetObject( nPos+i );
1622 pData = maS2O.GetData( nSortPos );
1623 pData->mnCurPos += nOffset;
1626 if ( nOffset < 0 )
1628 for ( i=nPos+nOffset; i<nPos; i++ )
1630 nSortPos = (long) maO2S.GetObject( i );
1631 pData = maS2O.GetData( nSortPos );
1632 pData->mnCurPos += nCount;
1635 else
1637 long nStart = nPos + nCount;
1638 long nEnd = nStart + nOffset;
1639 for ( i=nStart; i<nEnd; i++ )
1641 nSortPos = (long) maO2S.GetObject( i );
1642 pData = maS2O.GetData( nSortPos );
1643 pData->mnCurPos -= nCount;
1647 // remember the to be moved entries
1648 long *pTmpArr = new long[ nCount ];
1649 for ( i=0; i<nCount; i++ )
1650 pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
1652 // now move the entries, which are in the way
1653 if ( nOffset < 0 )
1655 // be carefully here, because nOffset is negative here, so an
1656 // addition is a subtraction
1657 long nFrom = nPos - 1;
1658 nTo = nPos + nCount - 1;
1660 // same for i here
1661 for ( i=0; i>nOffset; i-- )
1663 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
1664 maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
1668 else
1670 long nStart = nPos + nCount;
1671 for ( i=0; i<nOffset; i++ )
1673 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
1674 maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
1678 // finally put the remembered entries at there new location
1679 nTo = nPos + nOffset;
1680 for ( i=0; i<nCount; i++ )
1682 maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
1685 delete [] pTmpArr;
1688 //--------------------------------------------------------------------------
1689 void SortedResultSet::BuildSortInfo(
1690 Reference< XResultSet > aResult,
1691 const Sequence < NumberedSortingInfo > &xSortInfo,
1692 const Reference< XAnyCompareFactory > &xCompFactory )
1694 Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1696 if ( ! xMeta.is() )
1698 OSL_ENSURE( sal_False, "No MetaData, No Sorting!" );
1699 return;
1702 Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1703 const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1705 sal_Int32 nColumn;
1706 OUString aPropName;
1707 SortInfo *pInfo;
1709 for ( long i=xSortInfo.getLength(); i > 0; )
1711 --i;
1712 nColumn = pSortInfo[ i ].ColumnIndex;
1713 aPropName = xData->getColumnName( nColumn );
1714 pInfo = new SortInfo;
1716 if ( xCompFactory.is() )
1717 pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1718 aPropName );
1720 if ( pInfo->mxCompareFunction.is() )
1722 pInfo->mbUseOwnCompare = sal_False;
1723 pInfo->mnType = 0;
1725 else
1727 pInfo->mbUseOwnCompare = sal_True;
1728 pInfo->mnType = xData->getColumnType( nColumn );
1731 pInfo->mnColumn = nColumn;
1732 pInfo->mbAscending = pSortInfo[ i ].Ascending;
1733 pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1734 pInfo->mpNext = mpSortInfo;
1735 mpSortInfo = pInfo;
1739 //-------------------------------------------------------------------------
1740 void SortedResultSet::SetChanged( long nPos, long nCount )
1742 for ( long i=0; i<nCount; i++ )
1744 long nSortPos = (long) maO2S.GetObject( nPos );
1745 if ( nSortPos < mnLastSort )
1747 SortListData *pData = maS2O.GetData( nSortPos );
1748 if ( ! pData->mbModified )
1750 pData->mbModified = sal_True;
1751 maModList.Append( pData );
1754 nPos += 1;
1758 //-------------------------------------------------------------------------
1759 void SortedResultSet::ResortModified( EventList* pList )
1761 sal_uInt32 i, j;
1762 long nCompare, nCurPos, nNewPos;
1763 long nStart, nEnd, nOffset, nVal;
1764 SortListData *pData;
1765 ListAction *pAction;
1767 try {
1768 for ( i=0; i<maModList.Count(); i++ )
1770 pData = (SortListData*) maModList.GetObject( i );
1771 nCompare = CompareImpl( mxOther, mxOriginal,
1772 pData->mnOldPos, pData->mnCurPos );
1773 pData->mbModified = sal_False;
1774 if ( nCompare != 0 )
1776 nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
1777 if ( nCompare < 0 )
1779 nNewPos = FindPos( pData, 1, nCurPos-1 );
1780 nStart = nNewPos;
1781 nEnd = nCurPos;
1782 nOffset = 1;
1784 else
1786 nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1787 nStart = nCurPos;
1788 nEnd = mnLastSort;
1789 nOffset = -1;
1792 if ( nNewPos != nCurPos )
1794 // correct the lists!
1795 maS2O.Remove( (sal_uInt32) nCurPos );
1796 maS2O.Insert( pData, nNewPos );
1797 for ( j=1; j<maO2S.Count(); j++ )
1799 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1800 if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1802 nVal += nOffset;
1803 maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
1807 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1809 pAction = new ListAction;
1810 pAction->Position = nCurPos;
1811 pAction->Count = 1;
1812 pAction->ListActionType = ListActionType::MOVED;
1813 pAction->ActionInfo <<= nNewPos-nCurPos;
1814 pList->Insert( pAction );
1816 pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
1817 nNewPos, 1 );
1821 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortModified() : Got unexpected SQLException" ); }
1823 maModList.Clear();
1826 //-------------------------------------------------------------------------
1827 void SortedResultSet::ResortNew( EventList* pList )
1829 long i, j, nNewPos, nVal;
1830 SortListData *pData;
1832 try {
1833 for ( i = mnLastSort; i<(long)maS2O.Count(); i++ )
1835 pData = (SortListData*) maModList.GetObject( i );
1836 nNewPos = FindPos( pData, 1, mnLastSort );
1837 if ( nNewPos != i )
1839 maS2O.Remove( (sal_uInt32) i );
1840 maS2O.Insert( pData, nNewPos );
1841 // maO2S liste korigieren
1842 for ( j=1; j<(long)maO2S.Count(); j++ )
1844 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1845 if ( nVal >= nNewPos )
1846 maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
1848 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1850 mnLastSort++;
1851 pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
1854 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortNew() : Got unexpected SQLException" ); }
1857 //-------------------------------------------------------------------------
1859 // SortListData
1861 //-------------------------------------------------------------------------
1862 SortListData::SortListData( long nPos, sal_Bool bModified )
1864 mbModified = bModified;
1865 mnCurPos = nPos;
1866 mnOldPos = nPos;
1870 //=========================================================================
1871 void SortedEntryList::Clear()
1873 for ( std::deque< LISTACTION* >::size_type i = 0;
1874 i < maData.size(); ++i )
1876 delete maData[i];
1879 maData.clear();
1882 //-------------------------------------------------------------------------
1883 void SortedEntryList::Insert( SortListData *pEntry, long nPos )
1885 if ( nPos < (long) maData.size() )
1886 maData.insert( maData.begin() + nPos, pEntry );
1887 else
1888 maData.push_back( pEntry );
1891 //-------------------------------------------------------------------------
1892 SortListData* SortedEntryList::Remove( long nPos )
1894 SortListData *pData;
1896 if ( nPos < (long) maData.size() )
1898 pData = maData[ nPos ];
1899 maData.erase( maData.begin() + nPos );
1901 else
1902 pData = NULL;
1904 return pData;
1907 //-------------------------------------------------------------------------
1908 SortListData* SortedEntryList::GetData( long nPos )
1910 SortListData *pData;
1912 if ( nPos < (long) maData.size() )
1913 pData = maData[ nPos ];
1914 else
1915 pData = NULL;
1917 return pData;
1920 //-------------------------------------------------------------------------
1921 long SortedEntryList::operator [] ( long nPos ) const
1923 SortListData *pData;
1925 if ( nPos < (long) maData.size() )
1926 pData = maData[ nPos ];
1927 else
1928 pData = NULL;
1930 if ( pData )
1931 if ( ! pData->mbModified )
1932 return pData->mnCurPos;
1933 else
1935 OSL_ENSURE( sal_False, "SortedEntryList: Can't get value for modified entry!");
1936 return 0;
1938 else
1940 OSL_ENSURE( sal_False, "SortedEntryList: invalid pos!");
1941 return 0;
1945 //-------------------------------------------------------------------------
1946 //-------------------------------------------------------------------------
1947 //-------------------------------------------------------------------------
1948 void SimpleList::Remove( sal_uInt32 nPos )
1950 if ( nPos < (sal_uInt32) maData.size() )
1952 maData.erase( maData.begin() + nPos );
1956 //-------------------------------------------------------------------------
1957 void SimpleList::Remove( void* pData )
1959 sal_Bool bFound = sal_False;
1960 sal_uInt32 i;
1962 for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
1964 if ( maData[ i ] == pData )
1966 bFound = sal_True;
1967 break;
1971 if ( bFound )
1972 maData.erase( maData.begin() + i );
1975 //-------------------------------------------------------------------------
1976 void SimpleList::Insert( void* pData, sal_uInt32 nPos )
1978 if ( nPos < (sal_uInt32) maData.size() )
1979 maData.insert( maData.begin() + nPos, pData );
1980 else
1981 maData.push_back( pData );
1984 //-------------------------------------------------------------------------
1985 void* SimpleList::GetObject( sal_uInt32 nPos ) const
1987 if ( nPos < (sal_uInt32) maData.size() )
1988 return maData[ nPos ];
1989 else
1990 return NULL;
1993 //-------------------------------------------------------------------------
1994 void SimpleList::Replace( void* pData, sal_uInt32 nPos )
1996 if ( nPos < (sal_uInt32) maData.size() )
1997 maData[ nPos ] = pData;
2000 //-------------------------------------------------------------------------
2002 // class SRSPropertySetInfo.
2004 //-------------------------------------------------------------------------
2006 SRSPropertySetInfo::SRSPropertySetInfo()
2008 maProps[0].Name = OUString::createFromAscii( "RowCount" );
2009 maProps[0].Handle = -1;
2010 maProps[0].Type = ::getCppuType( (const OUString*) NULL );
2011 maProps[0].Attributes = -1;
2013 maProps[1].Name = OUString::createFromAscii( "IsRowCountFinal" );
2014 maProps[1].Handle = -1;
2015 maProps[1].Type = ::getBooleanCppuType();
2016 maProps[1].Attributes = -1;
2019 //-------------------------------------------------------------------------
2020 SRSPropertySetInfo::~SRSPropertySetInfo()
2023 //-------------------------------------------------------------------------
2024 // XInterface methods.
2025 //-------------------------------------------------------------------------
2027 XINTERFACE_IMPL_2( SRSPropertySetInfo,
2028 XTypeProvider,
2029 XPropertySetInfo );
2031 //-------------------------------------------------------------------------
2032 // XTypeProvider methods.
2033 //-------------------------------------------------------------------------
2035 XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo,
2036 XTypeProvider,
2037 XPropertySetInfo );
2039 //-------------------------------------------------------------------------
2040 // XPropertySetInfo methods.
2041 //-------------------------------------------------------------------------
2042 Sequence< Property > SAL_CALL
2043 SRSPropertySetInfo::getProperties() throw( RuntimeException )
2045 return Sequence < Property > ( maProps, 2 );
2048 //-------------------------------------------------------------------------
2049 Property SAL_CALL
2050 SRSPropertySetInfo::getPropertyByName( const OUString& Name )
2051 throw( UnknownPropertyException, RuntimeException )
2053 if ( Name.compareToAscii( "RowCount" ) == 0 )
2054 return maProps[0];
2055 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2056 return maProps[1];
2057 else
2058 throw UnknownPropertyException();
2061 //-------------------------------------------------------------------------
2062 sal_Bool SAL_CALL
2063 SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
2064 throw( RuntimeException )
2066 if ( Name.compareToAscii( "RowCount" ) == 0 )
2067 return sal_True;
2068 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2069 return sal_True;
2070 else
2071 return sal_False;