bump product version to 4.1.6.2
[LibreOffice.git] / ucb / source / sorter / sortresult.cxx
blob4e72d45932ed4fb3ce03edf85ee85a84ca0d2997
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <vector>
22 #include <sortresult.hxx>
23 #include <cppuhelper/interfacecontainer.hxx>
24 #include <com/sun/star/sdbc/DataType.hpp>
25 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
26 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
27 #include <com/sun/star/ucb/ListActionType.hpp>
28 #include <com/sun/star/ucb/XAnyCompare.hpp>
29 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
30 #include <osl/diagnose.h>
32 //-----------------------------------------------------------------------------
33 using namespace com::sun::star::beans;
34 using namespace com::sun::star::container;
35 using namespace com::sun::star::io;
36 using namespace com::sun::star::lang;
37 using namespace com::sun::star::sdbc;
38 using namespace com::sun::star::ucb;
39 using namespace com::sun::star::uno;
40 using namespace com::sun::star::util;
41 using namespace cppu;
44 //=========================================================================
46 // The mutex to synchronize access to containers.
47 static osl::Mutex& getContainerMutex()
49 static osl::Mutex* pMutex = NULL;
50 if( !pMutex )
52 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
53 if( !pMutex )
55 static osl::Mutex aMutex;
56 pMutex = &aMutex;
60 return *pMutex;
63 //==========================================================================
65 struct SortInfo
67 sal_Bool mbUseOwnCompare;
68 sal_Bool mbAscending;
69 sal_Bool mbCaseSensitive;
70 sal_Int32 mnColumn;
71 sal_Int32 mnType;
72 SortInfo* mpNext;
73 Reference < XAnyCompare > mxCompareFunction;
76 //-----------------------------------------------------------------------------
78 struct SortListData
80 sal_Bool mbModified;
81 long mnCurPos;
82 long mnOldPos;
84 SortListData( long nPos, sal_Bool bModified = sal_False );
87 //============================================================================
89 // class SRSPropertySetInfo.
91 //============================================================================
93 class SRSPropertySetInfo :
94 public OWeakObject,
95 public XTypeProvider,
96 public XPropertySetInfo
98 Property maProps[2];
100 private:
102 public:
103 SRSPropertySetInfo();
104 virtual ~SRSPropertySetInfo();
106 // XInterface
107 XINTERFACE_DECL()
109 // XTypeProvider
110 XTYPEPROVIDER_DECL()
112 // XPropertySetInfo
113 virtual Sequence< Property > SAL_CALL getProperties()
114 throw( RuntimeException );
115 virtual Property SAL_CALL getPropertyByName( const OUString& aName )
116 throw( UnknownPropertyException, RuntimeException );
117 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
118 throw( RuntimeException );
121 //=========================================================================
123 // PropertyChangeListenerContainer_Impl.
125 //=========================================================================
127 struct equalStr_Impl
129 bool operator()( const OUString& s1, const OUString& s2 ) const
131 return !!( s1 == s2 );
135 struct hashStr_Impl
137 size_t operator()( const OUString& rName ) const
139 return rName.hashCode();
143 typedef OMultiTypeInterfaceContainerHelperVar
145 OUString,
146 hashStr_Impl,
147 equalStr_Impl
148 > PropertyChangeListenerContainer_Impl;
150 //=========================================================================
152 // class PropertyChangeListeners_Impl
154 //=========================================================================
156 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
158 public:
159 PropertyChangeListeners_Impl()
160 : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
163 //==========================================================================
164 SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
166 mpDisposeEventListeners = NULL;
167 mpPropChangeListeners = NULL;
168 mpVetoChangeListeners = NULL;
169 mpPropSetInfo = NULL;
171 mxOriginal = aResult;
172 mpSortInfo = NULL;
173 mnLastSort = 0;
174 mnCurEntry = 0;
175 mnCount = 0;
176 mbIsCopy = sal_False;
179 //--------------------------------------------------------------------------
180 SortedResultSet::~SortedResultSet()
182 mxOriginal.clear();
183 mxOther.clear();
185 if ( !mbIsCopy )
187 SortInfo *pInfo = mpSortInfo;
188 while ( pInfo )
190 mpSortInfo = pInfo->mpNext;
191 delete pInfo;
192 pInfo = mpSortInfo;
196 mpSortInfo = NULL;
198 if ( mpPropSetInfo )
199 mpPropSetInfo->release();
201 delete mpPropChangeListeners;
202 delete mpVetoChangeListeners;
205 //--------------------------------------------------------------------------
206 // XInterface methods.
207 //--------------------------------------------------------------------------
209 XINTERFACE_IMPL_9( SortedResultSet,
210 XTypeProvider,
211 XServiceInfo,
212 XComponent,
213 XContentAccess,
214 XResultSet,
215 XRow,
216 XCloseable,
217 XResultSetMetaDataSupplier,
218 XPropertySet );
220 //--------------------------------------------------------------------------
221 // XTypeProvider methods.
222 //--------------------------------------------------------------------------
224 XTYPEPROVIDER_IMPL_9( SortedResultSet,
225 XTypeProvider,
226 XServiceInfo,
227 XComponent,
228 XContentAccess,
229 XResultSet,
230 XRow,
231 XCloseable,
232 XResultSetMetaDataSupplier,
233 XPropertySet );
235 //--------------------------------------------------------------------------
236 // XServiceInfo methods.
237 //--------------------------------------------------------------------------
239 XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet,
240 OUString( "com.sun.star.comp.ucb.SortedResultSet" ),
241 OUString( RESULTSET_SERVICE_NAME ) );
243 //--------------------------------------------------------------------------
244 // XComponent methods.
245 //--------------------------------------------------------------------------
246 void SAL_CALL SortedResultSet::dispose()
247 throw( RuntimeException )
249 osl::Guard< osl::Mutex > aGuard( maMutex );
251 if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
253 EventObject aEvt;
254 aEvt.Source = static_cast< XComponent * >( this );
255 mpDisposeEventListeners->disposeAndClear( aEvt );
258 if ( mpPropChangeListeners )
260 EventObject aEvt;
261 aEvt.Source = static_cast< XPropertySet * >( this );
262 mpPropChangeListeners->disposeAndClear( aEvt );
265 if ( mpVetoChangeListeners )
267 EventObject aEvt;
268 aEvt.Source = static_cast< XPropertySet * >( this );
269 mpVetoChangeListeners->disposeAndClear( aEvt );
272 mxOriginal.clear();
273 mxOther.clear();
276 //--------------------------------------------------------------------------
277 void SAL_CALL SortedResultSet::addEventListener(
278 const Reference< XEventListener >& Listener )
279 throw( RuntimeException )
281 osl::Guard< osl::Mutex > aGuard( maMutex );
283 if ( !mpDisposeEventListeners )
284 mpDisposeEventListeners =
285 new OInterfaceContainerHelper( getContainerMutex() );
287 mpDisposeEventListeners->addInterface( Listener );
290 //--------------------------------------------------------------------------
291 void SAL_CALL SortedResultSet::removeEventListener(
292 const Reference< XEventListener >& Listener )
293 throw( RuntimeException )
295 osl::Guard< osl::Mutex > aGuard( maMutex );
297 if ( mpDisposeEventListeners )
298 mpDisposeEventListeners->removeInterface( Listener );
301 //--------------------------------------------------------------------------
302 // XContentAccess methods.
303 //--------------------------------------------------------------------------
305 OUString SAL_CALL
306 SortedResultSet::queryContentIdentifierString()
307 throw( RuntimeException )
309 osl::Guard< osl::Mutex > aGuard( maMutex );
310 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
313 //--------------------------------------------------------------------------
314 Reference< XContentIdentifier > SAL_CALL
315 SortedResultSet::queryContentIdentifier()
316 throw( RuntimeException )
318 osl::Guard< osl::Mutex > aGuard( maMutex );
319 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
322 //--------------------------------------------------------------------------
323 Reference< XContent > SAL_CALL
324 SortedResultSet::queryContent()
325 throw( RuntimeException )
327 osl::Guard< osl::Mutex > aGuard( maMutex );
328 return Reference< XContentAccess >::query(mxOriginal)->queryContent();
332 //--------------------------------------------------------------------------
333 // XResultSet methods.
334 //--------------------------------------------------------------------------
335 sal_Bool SAL_CALL SortedResultSet::next()
336 throw ( SQLException, RuntimeException )
338 osl::Guard< osl::Mutex > aGuard( maMutex );
340 mnCurEntry++;
342 if ( mnCurEntry > 0 )
344 if ( mnCurEntry <= mnCount )
346 sal_Int32 nIndex = maS2O[ mnCurEntry ];
347 return mxOriginal->absolute( nIndex );
349 else
351 mnCurEntry = mnCount + 1;
354 return sal_False;
357 //-------------------------------------------------------------------------
358 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
359 throw ( SQLException, RuntimeException )
361 if ( mnCurEntry )
362 return sal_False;
363 else
364 return sal_True;
367 //-------------------------------------------------------------------------
368 sal_Bool SAL_CALL SortedResultSet::isAfterLast()
369 throw ( SQLException, RuntimeException )
371 if ( mnCurEntry > mnCount )
372 return sal_True;
373 else
374 return sal_False;
377 //-------------------------------------------------------------------------
378 sal_Bool SAL_CALL SortedResultSet::isFirst()
379 throw ( SQLException, RuntimeException )
381 if ( mnCurEntry == 1 )
382 return sal_True;
383 else
384 return sal_False;
387 //-------------------------------------------------------------------------
388 sal_Bool SAL_CALL SortedResultSet::isLast()
389 throw ( SQLException, RuntimeException )
391 if ( mnCurEntry == mnCount )
392 return sal_True;
393 else
394 return sal_False;
397 //-------------------------------------------------------------------------
398 void SAL_CALL SortedResultSet::beforeFirst()
399 throw ( SQLException, RuntimeException )
401 osl::Guard< osl::Mutex > aGuard( maMutex );
402 mnCurEntry = 0;
403 mxOriginal->beforeFirst();
406 //-------------------------------------------------------------------------
407 void SAL_CALL SortedResultSet::afterLast()
408 throw ( SQLException, RuntimeException )
410 osl::Guard< osl::Mutex > aGuard( maMutex );
411 mnCurEntry = mnCount+1;
412 mxOriginal->afterLast();
415 //-------------------------------------------------------------------------
416 sal_Bool SAL_CALL SortedResultSet::first()
417 throw ( SQLException, RuntimeException )
419 osl::Guard< osl::Mutex > aGuard( maMutex );
421 if ( mnCount )
423 mnCurEntry = 1;
424 sal_Int32 nIndex = maS2O[ mnCurEntry ];
425 return mxOriginal->absolute( nIndex );
427 else
429 mnCurEntry = 0;
430 return sal_False;
434 //-------------------------------------------------------------------------
435 sal_Bool SAL_CALL SortedResultSet::last()
436 throw ( SQLException, RuntimeException )
438 osl::Guard< osl::Mutex > aGuard( maMutex );
440 if ( mnCount )
442 mnCurEntry = mnCount;
443 sal_Int32 nIndex = maS2O[ mnCurEntry ];
444 return mxOriginal->absolute( nIndex );
446 else
448 mnCurEntry = 0;
449 return sal_False;
453 //-------------------------------------------------------------------------
454 sal_Int32 SAL_CALL SortedResultSet::getRow()
455 throw ( SQLException, RuntimeException )
457 return mnCurEntry;
460 //-------------------------------------------------------------------------
462 moves the cursor to the given row number in the result set.
463 <p>If the row number is positive, the cursor moves to the given row
464 number with respect to the beginning of the result set. The first
465 row is row 1, the second is row 2, and so on.
466 <p>If the given row number is negative, the cursor moves to an
467 absolute row position with respect to the end of the result set.
468 For example, calling <code>moveToPosition(-1)</code> positions the
469 cursor on the last row, <code>moveToPosition(-2)</code> indicates the
470 next-to-last row, and so on.
471 <p>An attempt to position the cursor beyond the first/last row in the
472 result set leaves the cursor before/after the first/last row,
473 respectively.
474 <p>Note: Calling <code>moveToPosition(1)</code> is the same
475 as calling <code>moveToFirst()</code>. Calling
476 <code>moveToPosition(-1)</code> is the same as calling
477 <code>moveToLast()</code>.
478 @param row
479 is the number of rows to move. Could be negative.
480 @returns
481 <TRUE/> if the cursor is on a row; <FALSE/> otherwise
482 @throws SQLException
483 if a database access error occurs or if row is 0, or the result set
484 type is FORWARD_ONLY.
486 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
487 throw ( SQLException, RuntimeException )
489 osl::Guard< osl::Mutex > aGuard( maMutex );
491 sal_Int32 nIndex;
493 if ( row > 0 )
495 if ( row <= mnCount )
497 mnCurEntry = row;
498 nIndex = maS2O[ mnCurEntry ];
499 return mxOriginal->absolute( nIndex );
501 else
503 mnCurEntry = mnCount + 1;
504 return sal_False;
507 else if ( row == 0 )
509 throw SQLException();
511 else
513 if ( mnCount + row + 1 > 0 )
515 mnCurEntry = mnCount + row + 1;
516 nIndex = maS2O[ mnCurEntry ];
517 return mxOriginal->absolute( nIndex );
519 else
521 mnCurEntry = 0;
522 return sal_False;
527 //-------------------------------------------------------------------------
529 moves the cursor a relative number of rows, either positive or negative.
531 Attempting to move beyond the first/last row in the result set positions
532 the cursor before/after the first/last row. Calling
533 <code>moveRelative(0)</code> is valid, but does not change the cursor
534 position.
535 <p>Note: Calling <code>moveRelative(1)</code> is different from calling
536 <code>moveNext()</code> because is makes sense to call
537 <code>moveNext()</code> when there is no current row, for example,
538 when the cursor is positioned before the first row or after the last
539 row of the result set.
540 @param rows
541 is the number of rows to move. Could be negative.
542 @returns
543 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
544 the result set.
545 @throws SQLException
546 if a database access error occurs or if there is no
547 current row, or the result set type is FORWARD_ONLY.
549 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
550 throw ( SQLException, RuntimeException )
552 osl::Guard< osl::Mutex > aGuard( maMutex );
554 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
556 throw SQLException();
559 if ( rows == 0 )
560 return sal_True;
562 sal_Int32 nTmp = mnCurEntry + rows;
564 if ( nTmp <= 0 )
566 mnCurEntry = 0;
567 return sal_False;
569 else if ( nTmp > mnCount )
571 mnCurEntry = mnCount + 1;
572 return sal_False;
574 else
576 mnCurEntry = nTmp;
577 nTmp = maS2O[ mnCurEntry ];
578 return mxOriginal->absolute( nTmp );
582 //-------------------------------------------------------------------------
584 moves the cursor to the previous row in the result set.
585 <p>Note: <code>previous()</code> is not the same as
586 <code>relative(-1)</code> because it makes sense to call
587 <code>previous()</code> when there is no current row.
588 @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
589 the result set.
590 @throws SQLException
591 if a database access error occurs or the result set type
592 is FORWARD_ONLY.
594 sal_Bool SAL_CALL SortedResultSet::previous()
595 throw ( SQLException, RuntimeException )
597 osl::Guard< osl::Mutex > aGuard( maMutex );
599 mnCurEntry -= 1;
601 if ( mnCurEntry > 0 )
603 if ( mnCurEntry <= mnCount )
605 sal_Int32 nIndex = maS2O[ mnCurEntry ];
606 return mxOriginal->absolute( nIndex );
609 else
610 mnCurEntry = 0;
612 return sal_False;
615 //-------------------------------------------------------------------------
616 void SAL_CALL SortedResultSet::refreshRow()
617 throw ( SQLException, RuntimeException )
619 osl::Guard< osl::Mutex > aGuard( maMutex );
621 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
623 throw SQLException();
626 mxOriginal->refreshRow();
629 //-------------------------------------------------------------------------
630 sal_Bool SAL_CALL SortedResultSet::rowUpdated()
631 throw ( SQLException, RuntimeException )
633 osl::Guard< osl::Mutex > aGuard( maMutex );
635 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
637 throw SQLException();
640 return mxOriginal->rowUpdated();
643 //-------------------------------------------------------------------------
644 sal_Bool SAL_CALL SortedResultSet::rowInserted()
645 throw ( SQLException, RuntimeException )
647 osl::Guard< osl::Mutex > aGuard( maMutex );
649 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
651 throw SQLException();
654 return mxOriginal->rowInserted();
657 //-------------------------------------------------------------------------
658 sal_Bool SAL_CALL SortedResultSet::rowDeleted()
659 throw ( SQLException, RuntimeException )
661 osl::Guard< osl::Mutex > aGuard( maMutex );
663 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
665 throw SQLException();
668 return mxOriginal->rowDeleted();
671 //-------------------------------------------------------------------------
672 Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
673 throw ( SQLException, RuntimeException )
675 osl::Guard< osl::Mutex > aGuard( maMutex );
677 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
679 throw SQLException();
682 return mxOriginal->getStatement();
685 //--------------------------------------------------------------------------
686 // XRow methods.
687 //--------------------------------------------------------------------------
689 sal_Bool SAL_CALL SortedResultSet::wasNull()
690 throw( SQLException, RuntimeException )
692 osl::Guard< osl::Mutex > aGuard( maMutex );
693 return Reference< XRow >::query(mxOriginal)->wasNull();
696 //-------------------------------------------------------------------------
697 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
698 throw( SQLException, RuntimeException )
700 osl::Guard< osl::Mutex > aGuard( maMutex );
701 return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
704 //-------------------------------------------------------------------------
705 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
706 throw( SQLException, RuntimeException )
708 osl::Guard< osl::Mutex > aGuard( maMutex );
709 return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
712 //-------------------------------------------------------------------------
713 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
714 throw( SQLException, RuntimeException )
716 osl::Guard< osl::Mutex > aGuard( maMutex );
717 return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
720 //-------------------------------------------------------------------------
721 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
722 throw( SQLException, RuntimeException )
724 osl::Guard< osl::Mutex > aGuard( maMutex );
725 return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
728 //-------------------------------------------------------------------------
729 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
730 throw( SQLException, RuntimeException )
732 osl::Guard< osl::Mutex > aGuard( maMutex );
733 return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
735 //-------------------------------------------------------------------------
736 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
737 throw( SQLException, RuntimeException )
739 osl::Guard< osl::Mutex > aGuard( maMutex );
740 return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
743 //-------------------------------------------------------------------------
744 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
745 throw( SQLException, RuntimeException )
747 osl::Guard< osl::Mutex > aGuard( maMutex );
748 return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
751 //-------------------------------------------------------------------------
752 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
753 throw( SQLException, RuntimeException )
755 osl::Guard< osl::Mutex > aGuard( maMutex );
756 return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
759 //-------------------------------------------------------------------------
760 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
761 throw( SQLException, RuntimeException )
763 osl::Guard< osl::Mutex > aGuard( maMutex );
764 return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
767 //-------------------------------------------------------------------------
768 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
769 throw( SQLException, RuntimeException )
771 osl::Guard< osl::Mutex > aGuard( maMutex );
772 return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
775 //-------------------------------------------------------------------------
776 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
777 throw( SQLException, RuntimeException )
779 osl::Guard< osl::Mutex > aGuard( maMutex );
780 return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
783 //-------------------------------------------------------------------------
784 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
785 throw( SQLException, RuntimeException )
787 osl::Guard< osl::Mutex > aGuard( maMutex );
788 return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
791 //-------------------------------------------------------------------------
792 Reference< XInputStream > SAL_CALL
793 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
794 throw( SQLException, RuntimeException )
796 osl::Guard< osl::Mutex > aGuard( maMutex );
797 return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
800 //-------------------------------------------------------------------------
801 Reference< XInputStream > SAL_CALL
802 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
803 throw( SQLException, RuntimeException )
805 osl::Guard< osl::Mutex > aGuard( maMutex );
806 return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
809 //-------------------------------------------------------------------------
810 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
811 const Reference< XNameAccess >& typeMap )
812 throw( SQLException, RuntimeException )
814 osl::Guard< osl::Mutex > aGuard( maMutex );
815 return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
816 typeMap);
819 //-------------------------------------------------------------------------
820 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
821 throw( SQLException, RuntimeException )
823 osl::Guard< osl::Mutex > aGuard( maMutex );
824 return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
827 //-------------------------------------------------------------------------
828 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
829 throw( SQLException, RuntimeException )
831 osl::Guard< osl::Mutex > aGuard( maMutex );
832 return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
835 //-------------------------------------------------------------------------
836 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
837 throw( SQLException, RuntimeException )
839 osl::Guard< osl::Mutex > aGuard( maMutex );
840 return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
843 //-------------------------------------------------------------------------
844 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
845 throw( SQLException, RuntimeException )
847 osl::Guard< osl::Mutex > aGuard( maMutex );
848 return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
852 //--------------------------------------------------------------------------
853 // XCloseable methods.
854 //--------------------------------------------------------------------------
856 void SAL_CALL SortedResultSet::close()
857 throw( SQLException, RuntimeException )
859 osl::Guard< osl::Mutex > aGuard( maMutex );
860 Reference< XCloseable >::query(mxOriginal)->close();
863 //--------------------------------------------------------------------------
864 // XResultSetMetaDataSupplier methods.
865 //--------------------------------------------------------------------------
867 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
868 throw( SQLException, RuntimeException )
870 osl::Guard< osl::Mutex > aGuard( maMutex );
871 return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
875 //--------------------------------------------------------------------------
876 // XPropertySet methods.
877 //--------------------------------------------------------------------------
879 Reference< XPropertySetInfo > SAL_CALL
880 SortedResultSet::getPropertySetInfo() throw( RuntimeException )
882 osl::Guard< osl::Mutex > aGuard( maMutex );
884 if ( !mpPropSetInfo )
886 mpPropSetInfo = new SRSPropertySetInfo();
887 mpPropSetInfo->acquire();
890 return Reference< XPropertySetInfo >( mpPropSetInfo );
893 //--------------------------------------------------------------------------
894 void SAL_CALL SortedResultSet::setPropertyValue(
895 const OUString& PropertyName,
896 const Any& )
897 throw( UnknownPropertyException,
898 PropertyVetoException,
899 IllegalArgumentException,
900 WrappedTargetException,
901 RuntimeException )
903 osl::Guard< osl::Mutex > aGuard( maMutex );
905 if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) ||
906 ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) )
907 throw IllegalArgumentException();
908 else
909 throw UnknownPropertyException();
912 //--------------------------------------------------------------------------
913 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
914 throw( UnknownPropertyException,
915 WrappedTargetException,
916 RuntimeException )
918 osl::Guard< osl::Mutex > aGuard( maMutex );
920 Any aRet;
922 if ( PropertyName.compareToAscii( "RowCount" ) == 0 )
924 aRet <<= maS2O.Count();
926 else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 )
928 sal_Bool bOrgFinal = false;
929 Any aOrgRet;
931 aRet <<= (sal_Bool) sal_False;
933 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
934 getPropertyValue( PropertyName );
935 aOrgRet >>= bOrgFinal;
937 if ( bOrgFinal )
939 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
940 getPropertyValue( OUString("RowCount") );
941 sal_uInt32 nOrgCount = 0;
942 aOrgRet >>= nOrgCount;
943 if ( nOrgCount == maS2O.Count() )
944 aRet <<= (sal_Bool) sal_True;
947 else
948 throw UnknownPropertyException();
950 return aRet;
953 //--------------------------------------------------------------------------
954 void SAL_CALL SortedResultSet::addPropertyChangeListener(
955 const OUString& PropertyName,
956 const Reference< XPropertyChangeListener >& Listener )
957 throw( UnknownPropertyException,
958 WrappedTargetException,
959 RuntimeException )
961 osl::Guard< osl::Mutex > aGuard( maMutex );
963 if ( !mpPropChangeListeners )
964 mpPropChangeListeners =
965 new PropertyChangeListeners_Impl();
967 mpPropChangeListeners->addInterface( PropertyName, Listener );
970 //--------------------------------------------------------------------------
971 void SAL_CALL SortedResultSet::removePropertyChangeListener(
972 const OUString& PropertyName,
973 const Reference< XPropertyChangeListener >& Listener )
974 throw( UnknownPropertyException,
975 WrappedTargetException,
976 RuntimeException )
978 osl::Guard< osl::Mutex > aGuard( maMutex );
980 if ( mpPropChangeListeners )
981 mpPropChangeListeners->removeInterface( PropertyName, Listener );
984 //--------------------------------------------------------------------------
985 void SAL_CALL SortedResultSet::addVetoableChangeListener(
986 const OUString& PropertyName,
987 const Reference< XVetoableChangeListener >& Listener )
988 throw( UnknownPropertyException,
989 WrappedTargetException,
990 RuntimeException )
992 osl::Guard< osl::Mutex > aGuard( maMutex );
994 if ( !mpVetoChangeListeners )
995 mpVetoChangeListeners =
996 new PropertyChangeListeners_Impl();
998 mpVetoChangeListeners->addInterface( PropertyName, Listener );
1001 //--------------------------------------------------------------------------
1002 void SAL_CALL SortedResultSet::removeVetoableChangeListener(
1003 const OUString& PropertyName,
1004 const Reference< XVetoableChangeListener >& Listener )
1005 throw( UnknownPropertyException,
1006 WrappedTargetException,
1007 RuntimeException )
1009 osl::Guard< osl::Mutex > aGuard( maMutex );
1011 if ( mpVetoChangeListeners )
1012 mpVetoChangeListeners->removeInterface( PropertyName, Listener );
1015 //--------------------------------------------------------------------------
1016 // private methods
1017 //--------------------------------------------------------------------------
1018 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1019 Reference < XResultSet > xResultTwo,
1020 long nIndexOne, long nIndexTwo,
1021 SortInfo* pSortInfo )
1023 throw( SQLException, RuntimeException )
1025 Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
1026 Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
1028 long nCompare = 0;
1029 long nColumn = pSortInfo->mnColumn;
1031 switch ( pSortInfo->mnType )
1033 case DataType::BIT :
1034 case DataType::TINYINT :
1035 case DataType::SMALLINT :
1036 case DataType::INTEGER :
1038 sal_Int32 aOne = 0;
1039 sal_Int32 aTwo = 0;
1041 if ( xResultOne->absolute( nIndexOne ) )
1042 aOne = xRowOne->getInt( nColumn );
1043 if ( xResultTwo->absolute( nIndexTwo ) )
1044 aTwo = xRowTwo->getInt( nColumn );
1046 if ( aOne < aTwo )
1047 nCompare = -1;
1048 else if ( aOne == aTwo )
1049 nCompare = 0;
1050 else
1051 nCompare = 1;
1053 break;
1055 case DataType::BIGINT :
1057 sal_Int64 aOne = 0;
1058 sal_Int64 aTwo = 0;
1060 if ( xResultOne->absolute( nIndexOne ) )
1061 aOne = xRowOne->getLong( nColumn );
1062 if ( xResultTwo->absolute( nIndexTwo ) )
1063 aTwo = xRowTwo->getLong( nColumn );
1065 if ( aOne < aTwo )
1066 nCompare = -1;
1067 else if ( aOne == aTwo )
1068 nCompare = 0;
1069 else
1070 nCompare = 1;
1072 break;
1074 case DataType::CHAR :
1075 case DataType::VARCHAR :
1076 case DataType::LONGVARCHAR :
1078 OUString aOne, aTwo;
1080 if ( xResultOne->absolute( nIndexOne ) )
1081 aOne = xRowOne->getString( nColumn );
1082 if ( xResultTwo->absolute( nIndexTwo ) )
1083 aTwo = xRowTwo->getString( nColumn );
1085 if ( ! pSortInfo->mbCaseSensitive )
1087 aOne = aOne.toAsciiLowerCase();
1088 aTwo = aTwo.toAsciiLowerCase();
1091 nCompare = aOne.compareTo( aTwo );
1092 break;
1094 case DataType::DATE :
1096 Date aOne, aTwo;
1097 sal_Int32 nTmp;
1099 if ( xResultOne->absolute( nIndexOne ) )
1100 aOne = xRowOne->getDate( nColumn );
1101 if ( xResultTwo->absolute( nIndexTwo ) )
1102 aTwo = xRowTwo->getDate( nColumn );
1104 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1105 if ( !nTmp ) {
1106 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1107 if ( !nTmp )
1108 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1111 if ( nTmp < 0 )
1112 nCompare = -1;
1113 else if ( nTmp == 0 )
1114 nCompare = 0;
1115 else
1116 nCompare = 1;
1118 break;
1120 case DataType::TIME :
1122 Time aOne, aTwo;
1123 sal_Int32 nTmp;
1125 if ( xResultOne->absolute( nIndexOne ) )
1126 aOne = xRowOne->getTime( nColumn );
1127 if ( xResultTwo->absolute( nIndexTwo ) )
1128 aTwo = xRowTwo->getTime( nColumn );
1130 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1131 if ( !nTmp ) {
1132 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1133 if ( !nTmp ) {
1134 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1135 if ( !nTmp )
1136 nTmp = (sal_Int32) aTwo.NanoSeconds
1137 - (sal_Int32) aOne.NanoSeconds;
1140 if ( nTmp < 0 )
1141 nCompare = -1;
1142 else if ( nTmp == 0 )
1143 nCompare = 0;
1144 else
1145 nCompare = 1;
1147 break;
1149 case DataType::TIMESTAMP :
1151 DateTime aOne, aTwo;
1152 sal_Int32 nTmp;
1154 if ( xResultOne->absolute( nIndexOne ) )
1155 aOne = xRowOne->getTimestamp( nColumn );
1156 if ( xResultTwo->absolute( nIndexTwo ) )
1157 aTwo = xRowTwo->getTimestamp( nColumn );
1159 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1160 if ( !nTmp ) {
1161 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1162 if ( !nTmp ) {
1163 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1164 if ( !nTmp ) {
1165 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1166 if ( !nTmp ) {
1167 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1168 if ( !nTmp ) {
1169 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1170 if ( !nTmp )
1171 nTmp = (sal_Int32) aTwo.NanoSeconds
1172 - (sal_Int32) aOne.NanoSeconds;
1173 }}}}}
1175 if ( nTmp < 0 )
1176 nCompare = -1;
1177 else if ( nTmp == 0 )
1178 nCompare = 0;
1179 else
1180 nCompare = 1;
1182 break;
1184 case DataType::REAL :
1186 float aOne = 0;
1187 float aTwo = 0;
1189 if ( xResultOne->absolute( nIndexOne ) )
1190 aOne = xRowOne->getFloat( nColumn );
1191 if ( xResultTwo->absolute( nIndexTwo ) )
1192 aTwo = xRowTwo->getFloat( nColumn );
1194 if ( aOne < aTwo )
1195 nCompare = -1;
1196 else if ( aOne == aTwo )
1197 nCompare = 0;
1198 else
1199 nCompare = 1;
1201 break;
1203 case DataType::FLOAT :
1204 case DataType::DOUBLE :
1206 double aOne = 0;
1207 double aTwo = 0;
1209 if ( xResultOne->absolute( nIndexOne ) )
1210 aOne = xRowOne->getDouble( nColumn );
1211 if ( xResultTwo->absolute( nIndexTwo ) )
1212 aTwo = xRowTwo->getDouble( nColumn );
1214 if ( aOne < aTwo )
1215 nCompare = -1;
1216 else if ( aOne == aTwo )
1217 nCompare = 0;
1218 else
1219 nCompare = 1;
1221 break;
1223 default:
1225 OSL_FAIL( "DataType not supported for compare!" );
1229 return nCompare;
1232 //--------------------------------------------------------------------------
1233 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1234 Reference < XResultSet > xResultTwo,
1235 long nIndexOne, long nIndexTwo )
1236 throw( SQLException, RuntimeException )
1238 long nCompare = 0;
1239 SortInfo* pInfo = mpSortInfo;
1241 while ( !nCompare && pInfo )
1243 if ( pInfo->mbUseOwnCompare )
1245 nCompare = CompareImpl( xResultOne, xResultTwo,
1246 nIndexOne, nIndexTwo, pInfo );
1248 else
1250 Any aOne, aTwo;
1252 Reference < XRow > xRowOne =
1253 Reference< XRow >::query( xResultOne );
1254 Reference < XRow > xRowTwo =
1255 Reference< XRow >::query( xResultTwo );
1257 if ( xResultOne->absolute( nIndexOne ) )
1258 aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
1259 if ( xResultTwo->absolute( nIndexTwo ) )
1260 aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
1262 nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1265 if ( ! pInfo->mbAscending )
1266 nCompare = - nCompare;
1268 pInfo = pInfo->mpNext;
1271 return nCompare;
1274 //--------------------------------------------------------------------------
1275 long SortedResultSet::Compare( SortListData *pOne,
1276 SortListData *pTwo )
1277 throw( SQLException, RuntimeException )
1279 long nIndexOne;
1280 long nIndexTwo;
1282 Reference < XResultSet > xResultOne;
1283 Reference < XResultSet > xResultTwo;
1285 if ( pOne->mbModified )
1287 xResultOne = mxOther;
1288 nIndexOne = pOne->mnOldPos;
1290 else
1292 xResultOne = mxOriginal;
1293 nIndexOne = pOne->mnCurPos;
1296 if ( pTwo->mbModified )
1298 xResultTwo = mxOther;
1299 nIndexTwo = pTwo->mnOldPos;
1301 else
1303 xResultTwo = mxOriginal;
1304 nIndexTwo = pTwo->mnCurPos;
1307 long nCompare;
1308 nCompare = CompareImpl( xResultOne, xResultTwo,
1309 nIndexOne, nIndexTwo );
1310 return nCompare;
1313 //--------------------------------------------------------------------------
1314 long SortedResultSet::FindPos( SortListData *pEntry,
1315 long _nStart, long _nEnd )
1316 throw( SQLException, RuntimeException )
1318 if ( _nStart > _nEnd )
1319 return _nStart + 1;
1321 long nStart = _nStart;
1322 long nEnd = _nEnd;
1323 long nMid = 0, nCompare = 0;
1325 SortListData *pMid;
1327 while ( nStart <= nEnd )
1329 nMid = ( nEnd - nStart ) / 2 + nStart;
1330 pMid = maS2O.GetData( nMid );
1331 nCompare = Compare( pEntry, pMid );
1333 if ( !nCompare )
1334 nCompare = ((long) pEntry ) - ( (long) pMid );
1336 if ( nCompare < 0 ) // pEntry < pMid
1337 nEnd = nMid - 1;
1338 else
1339 nStart = nMid + 1;
1342 if ( nCompare < 0 ) // pEntry < pMid
1343 return nMid;
1344 else
1345 return nMid+1;
1348 //--------------------------------------------------------------------------
1349 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1351 osl::Guard< osl::Mutex > aGuard( maMutex );
1353 if ( !mpPropChangeListeners )
1354 return;
1356 // Notify listeners interested especially in the changed property.
1357 OInterfaceContainerHelper* pPropsContainer =
1358 mpPropChangeListeners->getContainer( rEvt.PropertyName );
1359 if ( pPropsContainer )
1361 OInterfaceIteratorHelper aIter( *pPropsContainer );
1362 while ( aIter.hasMoreElements() )
1364 Reference< XPropertyChangeListener > xListener(
1365 aIter.next(), UNO_QUERY );
1366 if ( xListener.is() )
1367 xListener->propertyChange( rEvt );
1371 // Notify listeners interested in all properties.
1372 pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1373 if ( pPropsContainer )
1375 OInterfaceIteratorHelper aIter( *pPropsContainer );
1376 while ( aIter.hasMoreElements() )
1378 Reference< XPropertyChangeListener > xListener(
1379 aIter.next(), UNO_QUERY );
1380 if ( xListener.is() )
1381 xListener->propertyChange( rEvt );
1386 //-------------------------------------------------------------------------
1388 //--------------------------------------------------------------------------
1389 // public methods
1390 //--------------------------------------------------------------------------
1392 void SortedResultSet::CopyData( SortedResultSet *pSource )
1394 const SortedEntryList *pSrcS2O = pSource->GetS2OList();
1395 const SimpleList *pSrcO2S = pSource->GetO2SList();
1397 long i, nCount;
1399 maS2O.Clear();
1400 maO2S.Clear();
1401 maModList.Clear();
1403 maS2O.Insert( NULL, 0 );
1404 maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos
1406 nCount = pSrcS2O->Count();
1408 for ( i=1; i<nCount; i++ )
1410 maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
1411 maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
1414 mnLastSort = maS2O.Count();
1415 mxOther = pSource->GetResultSet();
1417 if ( !mpSortInfo )
1419 mpSortInfo = pSource->GetSortInfo();
1420 mbIsCopy = sal_True;
1424 //--------------------------------------------------------------------------
1425 void SortedResultSet::Initialize(
1426 const Sequence < NumberedSortingInfo > &xSortInfo,
1427 const Reference< XAnyCompareFactory > &xCompFactory )
1429 BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1430 // Insert dummy at pos 0
1431 SortListData *pData = new SortListData( 0 );
1432 maS2O.Insert( pData, 0 );
1434 long nIndex = 1;
1436 // now fetch all the elements from the original result set,
1437 // get there new position in the sorted result set and insert
1438 // an entry in the sorted to original mapping list
1439 try {
1440 while ( mxOriginal->absolute( nIndex ) )
1442 pData = new SortListData( nIndex );
1443 long nPos = FindPos( pData, 1, nIndex-1 );
1445 maS2O.Insert( pData, nPos );
1447 nIndex++;
1450 catch (const SQLException&)
1452 OSL_FAIL( "SortedResultSet::Initialize() : Got unexpected SQLException" );
1455 // when we have fetched all the elements, we can create the
1456 // original to sorted mapping list from the s2o list
1457 maO2S.Clear();
1458 maO2S.Insert( NULL, (sal_uInt32) 0 );
1460 // insert some dummy entries first and replace then
1461 // the entries with the right ones
1462 size_t i;
1464 for ( i=1; i<maS2O.Count(); i++ )
1465 maO2S.Insert( (void*) 0, i ); // Insert( data, pos )
1466 for ( i=1; i<maS2O.Count(); i++ )
1467 maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
1469 mnCount = maS2O.Count() - 1;
1472 //--------------------------------------------------------------------------
1473 void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal )
1475 osl::Guard< osl::Mutex > aGuard( maMutex );
1477 if ( !mpPropChangeListeners )
1478 return;
1480 try {
1481 // check for propertyChangeEvents
1482 if ( nOldCount != GetCount() )
1484 sal_Bool bIsFinal = sal_False;
1485 PropertyChangeEvent aEvt;
1487 aEvt.PropertyName = OUString("RowCount");
1488 aEvt.Further = sal_False;
1489 aEvt.PropertyHandle = -1;
1490 aEvt.OldValue <<= nOldCount;
1491 aEvt.NewValue <<= GetCount();
1493 PropertyChanged( aEvt );
1495 OUString aName = OUString("IsRowCountFinal");
1496 Any aRet = getPropertyValue( aName );
1497 if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1499 aEvt.PropertyName = aName;
1500 aEvt.Further = sal_False;
1501 aEvt.PropertyHandle = -1;
1502 aEvt.OldValue <<= (sal_Bool) bWasFinal;
1503 aEvt.NewValue <<= (sal_Bool) bIsFinal;
1504 PropertyChanged( aEvt );
1508 catch (const UnknownPropertyException&) {}
1509 catch (const WrappedTargetException&) {}
1512 //-------------------------------------------------------------------------
1513 void SortedResultSet::InsertNew( long nPos, long nCount )
1515 // for all entries in the msS20-list, which are >= nPos, increase by nCount
1516 SortListData *pData;
1517 long i, nEnd;
1519 nEnd = maS2O.Count();
1520 for ( i=1; i<=nEnd; i++ )
1522 pData = maS2O.GetData( i );
1523 if ( pData->mnCurPos >= nPos )
1525 pData->mnCurPos += nCount;
1529 // and append the new entries at the end of the maS20-list or insert at the
1530 // position nPos in the maS2O-list
1531 for ( i=0; i<nCount; i++ )
1533 nEnd += 1;
1534 pData = new SortListData( nEnd );
1536 maS2O.Insert( pData, nEnd ); // Insert( Value, Position )
1537 maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Value, Position )
1540 mnCount += nCount;
1543 //-------------------------------------------------------------------------
1544 void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents )
1546 sal_uInt32 i, j;
1547 long nOldLastSort;
1549 // correct mnLastSort first
1550 nOldLastSort = mnLastSort;
1551 if ( nPos <= mnLastSort )
1553 if ( nPos + nCount - 1 <= mnLastSort )
1554 mnLastSort -= nCount;
1555 else
1556 mnLastSort = nPos - 1;
1559 // remove the entries from the lists and correct the positions
1560 // in the original2sorted list
1561 for ( i=0; i < (sal_uInt32) nCount; i++ )
1563 long nSortPos = (long) maO2S.GetObject( nPos );
1564 maO2S.Remove( (sal_uInt32) nPos );
1566 for ( j=1; j<=maO2S.Count(); j++ )
1568 long nVal = (long) maO2S.GetObject( j );
1569 if ( nVal > nSortPos )
1571 --nVal;
1572 maO2S.Replace( (void*) nVal, j );
1576 SortListData *pData = maS2O.Remove( nSortPos );
1577 if ( pData->mbModified )
1578 maModList.Remove( (void*) pData );
1579 delete pData;
1581 // generate remove Event, but not for new entries
1582 if ( nSortPos <= nOldLastSort )
1583 pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
1586 // correct the positions in the sorted list
1587 for ( i=1; i<= maS2O.Count(); i++ )
1589 SortListData *pData = maS2O.GetData( i );
1590 if ( pData->mnCurPos > nPos )
1591 pData->mnCurPos -= nCount;
1594 mnCount -= nCount;
1597 //-------------------------------------------------------------------------
1598 void SortedResultSet::Move( long nPos, long nCount, long nOffset )
1600 if ( !nOffset )
1601 return;
1603 long i, nSortPos, nTo;
1604 SortListData *pData;
1606 for ( i=0; i<nCount; i++ )
1608 nSortPos = (long) maO2S.GetObject( nPos+i );
1609 pData = maS2O.GetData( nSortPos );
1610 pData->mnCurPos += nOffset;
1613 if ( nOffset < 0 )
1615 for ( i=nPos+nOffset; i<nPos; i++ )
1617 nSortPos = (long) maO2S.GetObject( i );
1618 pData = maS2O.GetData( nSortPos );
1619 pData->mnCurPos += nCount;
1622 else
1624 long nStart = nPos + nCount;
1625 long nEnd = nStart + nOffset;
1626 for ( i=nStart; i<nEnd; i++ )
1628 nSortPos = (long) maO2S.GetObject( i );
1629 pData = maS2O.GetData( nSortPos );
1630 pData->mnCurPos -= nCount;
1634 // remember the to be moved entries
1635 long *pTmpArr = new long[ nCount ];
1636 for ( i=0; i<nCount; i++ )
1637 pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
1639 // now move the entries, which are in the way
1640 if ( nOffset < 0 )
1642 // be carefully here, because nOffset is negative here, so an
1643 // addition is a subtraction
1644 long nFrom = nPos - 1;
1645 nTo = nPos + nCount - 1;
1647 // same for i here
1648 for ( i=0; i>nOffset; i-- )
1650 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
1651 maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
1655 else
1657 long nStart = nPos + nCount;
1658 for ( i=0; i<nOffset; i++ )
1660 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
1661 maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
1665 // finally put the remembered entries at there new location
1666 nTo = nPos + nOffset;
1667 for ( i=0; i<nCount; i++ )
1669 maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
1672 delete [] pTmpArr;
1675 //--------------------------------------------------------------------------
1676 void SortedResultSet::BuildSortInfo(
1677 Reference< XResultSet > aResult,
1678 const Sequence < NumberedSortingInfo > &xSortInfo,
1679 const Reference< XAnyCompareFactory > &xCompFactory )
1681 Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1683 if ( ! xMeta.is() )
1685 OSL_FAIL( "No MetaData, No Sorting!" );
1686 return;
1689 Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1690 const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1692 sal_Int32 nColumn;
1693 OUString aPropName;
1694 SortInfo *pInfo;
1696 for ( long i=xSortInfo.getLength(); i > 0; )
1698 --i;
1699 nColumn = pSortInfo[ i ].ColumnIndex;
1700 aPropName = xData->getColumnName( nColumn );
1701 pInfo = new SortInfo;
1703 if ( xCompFactory.is() )
1704 pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1705 aPropName );
1707 if ( pInfo->mxCompareFunction.is() )
1709 pInfo->mbUseOwnCompare = sal_False;
1710 pInfo->mnType = 0;
1712 else
1714 pInfo->mbUseOwnCompare = sal_True;
1715 pInfo->mnType = xData->getColumnType( nColumn );
1718 pInfo->mnColumn = nColumn;
1719 pInfo->mbAscending = pSortInfo[ i ].Ascending;
1720 pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1721 pInfo->mpNext = mpSortInfo;
1722 mpSortInfo = pInfo;
1726 //-------------------------------------------------------------------------
1727 void SortedResultSet::SetChanged( long nPos, long nCount )
1729 for ( long i=0; i<nCount; i++ )
1731 long nSortPos = (long) maO2S.GetObject( nPos );
1732 if ( nSortPos < mnLastSort )
1734 SortListData *pData = maS2O.GetData( nSortPos );
1735 if ( ! pData->mbModified )
1737 pData->mbModified = sal_True;
1738 maModList.Append( pData );
1741 nPos += 1;
1745 //-------------------------------------------------------------------------
1746 void SortedResultSet::ResortModified( EventList* pList )
1748 sal_uInt32 i, j;
1749 long nCompare, nCurPos, nNewPos;
1750 long nStart, nEnd, nOffset, nVal;
1751 SortListData *pData;
1752 ListAction *pAction;
1754 try {
1755 for ( i=0; i<maModList.Count(); i++ )
1757 pData = (SortListData*) maModList.GetObject( i );
1758 nCompare = CompareImpl( mxOther, mxOriginal,
1759 pData->mnOldPos, pData->mnCurPos );
1760 pData->mbModified = sal_False;
1761 if ( nCompare != 0 )
1763 nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
1764 if ( nCompare < 0 )
1766 nNewPos = FindPos( pData, 1, nCurPos-1 );
1767 nStart = nNewPos;
1768 nEnd = nCurPos;
1769 nOffset = 1;
1771 else
1773 nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1774 nStart = nCurPos;
1775 nEnd = mnLastSort;
1776 nOffset = -1;
1779 if ( nNewPos != nCurPos )
1781 // correct the lists!
1782 maS2O.Remove( (sal_uInt32) nCurPos );
1783 maS2O.Insert( pData, nNewPos );
1784 for ( j=1; j<maO2S.Count(); j++ )
1786 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1787 if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1789 nVal += nOffset;
1790 maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
1794 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1796 pAction = new ListAction;
1797 pAction->Position = nCurPos;
1798 pAction->Count = 1;
1799 pAction->ListActionType = ListActionType::MOVED;
1800 pAction->ActionInfo <<= nNewPos-nCurPos;
1801 pList->Insert( pAction );
1803 pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
1804 nNewPos, 1 );
1808 catch (const SQLException&)
1810 OSL_FAIL( "SortedResultSet::ResortModified() : Got unexpected SQLException" );
1813 maModList.Clear();
1816 //-------------------------------------------------------------------------
1817 void SortedResultSet::ResortNew( EventList* pList )
1819 long i, j, nNewPos, nVal;
1820 SortListData *pData;
1822 try {
1823 for ( i = mnLastSort; i<(long)maS2O.Count(); i++ )
1825 pData = (SortListData*) maModList.GetObject( i );
1826 nNewPos = FindPos( pData, 1, mnLastSort );
1827 if ( nNewPos != i )
1829 maS2O.Remove( (sal_uInt32) i );
1830 maS2O.Insert( pData, nNewPos );
1831 // maO2S liste korigieren
1832 for ( j=1; j<(long)maO2S.Count(); j++ )
1834 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1835 if ( nVal >= nNewPos )
1836 maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
1838 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1840 mnLastSort++;
1841 pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
1844 catch (const SQLException&)
1846 OSL_FAIL( "SortedResultSet::ResortNew() : Got unexpected SQLException" );
1850 //-------------------------------------------------------------------------
1852 // SortListData
1854 //-------------------------------------------------------------------------
1855 SortListData::SortListData( long nPos, sal_Bool bModified )
1857 mbModified = bModified;
1858 mnCurPos = nPos;
1859 mnOldPos = nPos;
1863 //=========================================================================
1864 void SortedEntryList::Clear()
1866 for ( std::deque< ListAction* >::size_type i = 0;
1867 i < maData.size(); ++i )
1869 delete maData[i];
1872 maData.clear();
1875 //-------------------------------------------------------------------------
1876 void SortedEntryList::Insert( SortListData *pEntry, long nPos )
1878 if ( nPos < (long) maData.size() )
1879 maData.insert( maData.begin() + nPos, pEntry );
1880 else
1881 maData.push_back( pEntry );
1884 //-------------------------------------------------------------------------
1885 SortListData* SortedEntryList::Remove( long nPos )
1887 SortListData *pData;
1889 if ( nPos < (long) maData.size() )
1891 pData = maData[ nPos ];
1892 maData.erase( maData.begin() + nPos );
1894 else
1895 pData = NULL;
1897 return pData;
1900 //-------------------------------------------------------------------------
1901 SortListData* SortedEntryList::GetData( long nPos )
1903 SortListData *pData;
1905 if ( nPos < (long) maData.size() )
1906 pData = maData[ nPos ];
1907 else
1908 pData = NULL;
1910 return pData;
1913 //-------------------------------------------------------------------------
1914 long SortedEntryList::operator [] ( long nPos ) const
1916 SortListData *pData;
1918 if ( nPos < (long) maData.size() )
1919 pData = maData[ nPos ];
1920 else
1921 pData = NULL;
1923 if ( pData )
1924 if ( ! pData->mbModified )
1925 return pData->mnCurPos;
1926 else
1928 OSL_FAIL( "SortedEntryList: Can't get value for modified entry!");
1929 return 0;
1931 else
1933 OSL_FAIL( "SortedEntryList: invalid pos!");
1934 return 0;
1938 //-------------------------------------------------------------------------
1939 //-------------------------------------------------------------------------
1940 //-------------------------------------------------------------------------
1941 void SimpleList::Remove( sal_uInt32 nPos )
1943 if ( nPos < (sal_uInt32) maData.size() )
1945 maData.erase( maData.begin() + nPos );
1949 //-------------------------------------------------------------------------
1950 void SimpleList::Remove( void* pData )
1952 sal_Bool bFound = sal_False;
1953 sal_uInt32 i;
1955 for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
1957 if ( maData[ i ] == pData )
1959 bFound = sal_True;
1960 break;
1964 if ( bFound )
1965 maData.erase( maData.begin() + i );
1968 //-------------------------------------------------------------------------
1969 void SimpleList::Insert( void* pData, sal_uInt32 nPos )
1971 if ( nPos < (sal_uInt32) maData.size() )
1972 maData.insert( maData.begin() + nPos, pData );
1973 else
1974 maData.push_back( pData );
1977 //-------------------------------------------------------------------------
1978 void* SimpleList::GetObject( sal_uInt32 nPos ) const
1980 if ( nPos < (sal_uInt32) maData.size() )
1981 return maData[ nPos ];
1982 else
1983 return NULL;
1986 //-------------------------------------------------------------------------
1987 void SimpleList::Replace( void* pData, sal_uInt32 nPos )
1989 if ( nPos < (sal_uInt32) maData.size() )
1990 maData[ nPos ] = pData;
1993 //-------------------------------------------------------------------------
1995 // class SRSPropertySetInfo.
1997 //-------------------------------------------------------------------------
1999 SRSPropertySetInfo::SRSPropertySetInfo()
2001 maProps[0].Name = OUString("RowCount");
2002 maProps[0].Handle = -1;
2003 maProps[0].Type = ::getCppuType( (const OUString*) NULL );
2004 maProps[0].Attributes = -1;
2006 maProps[1].Name = OUString("IsRowCountFinal");
2007 maProps[1].Handle = -1;
2008 maProps[1].Type = ::getBooleanCppuType();
2009 maProps[1].Attributes = -1;
2012 //-------------------------------------------------------------------------
2013 SRSPropertySetInfo::~SRSPropertySetInfo()
2016 //-------------------------------------------------------------------------
2017 // XInterface methods.
2018 //-------------------------------------------------------------------------
2020 XINTERFACE_IMPL_2( SRSPropertySetInfo,
2021 XTypeProvider,
2022 XPropertySetInfo );
2024 //-------------------------------------------------------------------------
2025 // XTypeProvider methods.
2026 //-------------------------------------------------------------------------
2028 XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo,
2029 XTypeProvider,
2030 XPropertySetInfo );
2032 //-------------------------------------------------------------------------
2033 // XPropertySetInfo methods.
2034 //-------------------------------------------------------------------------
2035 Sequence< Property > SAL_CALL
2036 SRSPropertySetInfo::getProperties() throw( RuntimeException )
2038 return Sequence < Property > ( maProps, 2 );
2041 //-------------------------------------------------------------------------
2042 Property SAL_CALL
2043 SRSPropertySetInfo::getPropertyByName( const OUString& Name )
2044 throw( UnknownPropertyException, RuntimeException )
2046 if ( Name.compareToAscii( "RowCount" ) == 0 )
2047 return maProps[0];
2048 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2049 return maProps[1];
2050 else
2051 throw UnknownPropertyException();
2054 //-------------------------------------------------------------------------
2055 sal_Bool SAL_CALL
2056 SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
2057 throw( RuntimeException )
2059 if ( Name.compareToAscii( "RowCount" ) == 0 )
2060 return sal_True;
2061 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2062 return sal_True;
2063 else
2064 return sal_False;
2067 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */