Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / ucb / source / sorter / sortresult.cxx
blobac4668524517f9c3e051b3b46bb069f776fdf8c7
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 <com/sun/star/sdbc/DataType.hpp>
24 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
25 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
26 #include <com/sun/star/ucb/ListActionType.hpp>
27 #include <com/sun/star/ucb/XAnyCompare.hpp>
28 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
29 #include <cppuhelper/implbase1.hxx>
30 #include <cppuhelper/interfacecontainer.hxx>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <osl/diagnose.h>
34 using namespace com::sun::star::beans;
35 using namespace com::sun::star::container;
36 using namespace com::sun::star::io;
37 using namespace com::sun::star::lang;
38 using namespace com::sun::star::sdbc;
39 using namespace com::sun::star::ucb;
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::util;
42 using namespace cppu;
47 // The mutex to synchronize access to containers.
48 static osl::Mutex& getContainerMutex()
50 static osl::Mutex* pMutex = NULL;
51 if( !pMutex )
53 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
54 if( !pMutex )
56 static osl::Mutex aMutex;
57 pMutex = &aMutex;
61 return *pMutex;
66 struct SortInfo
68 bool mbUseOwnCompare;
69 bool mbAscending;
70 bool mbCaseSensitive;
71 sal_Int32 mnColumn;
72 sal_Int32 mnType;
73 SortInfo* mpNext;
74 Reference < XAnyCompare > mxCompareFunction;
79 struct SortListData
81 bool mbModified;
82 sal_IntPtr mnCurPos;
83 sal_IntPtr mnOldPos;
85 SortListData( sal_IntPtr nPos, bool bModified = false );
90 // class SRSPropertySetInfo.
94 class SRSPropertySetInfo : public cppu::WeakImplHelper1 <
95 XPropertySetInfo >
97 Property maProps[2];
99 private:
101 public:
102 SRSPropertySetInfo();
103 virtual ~SRSPropertySetInfo();
105 // XPropertySetInfo
106 virtual Sequence< Property > SAL_CALL getProperties()
107 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
108 virtual Property SAL_CALL getPropertyByName( const OUString& aName )
109 throw( UnknownPropertyException, RuntimeException, std::exception ) SAL_OVERRIDE;
110 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
111 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
114 typedef OMultiTypeInterfaceContainerHelperVar<OUString>
115 PropertyChangeListenerContainer_Impl;
117 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
119 public:
120 PropertyChangeListeners_Impl()
121 : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
125 SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
127 mpDisposeEventListeners = NULL;
128 mpPropChangeListeners = NULL;
129 mpVetoChangeListeners = NULL;
130 mpPropSetInfo = NULL;
132 mxOriginal = aResult;
133 mpSortInfo = NULL;
134 mnLastSort = 0;
135 mnCurEntry = 0;
136 mnCount = 0;
137 mbIsCopy = false;
141 SortedResultSet::~SortedResultSet()
143 mxOriginal.clear();
144 mxOther.clear();
146 if ( !mbIsCopy )
148 SortInfo *pInfo = mpSortInfo;
149 while ( pInfo )
151 mpSortInfo = pInfo->mpNext;
152 delete pInfo;
153 pInfo = mpSortInfo;
157 mpSortInfo = NULL;
159 if ( mpPropSetInfo )
160 mpPropSetInfo->release();
162 delete mpPropChangeListeners;
163 delete mpVetoChangeListeners;
167 // XServiceInfo methods.
169 OUString SAL_CALL SortedResultSet::getImplementationName()
170 throw( css::uno::RuntimeException, std::exception )
172 return getImplementationName_Static();
175 OUString SortedResultSet::getImplementationName_Static()
177 return OUString( "com.sun.star.comp.ucb.SortedResultSet" );
180 sal_Bool SAL_CALL SortedResultSet::supportsService( const OUString& ServiceName )
181 throw( css::uno::RuntimeException, std::exception )
183 return cppu::supportsService( this, ServiceName );
186 css::uno::Sequence< OUString > SAL_CALL SortedResultSet::getSupportedServiceNames()
187 throw( css::uno::RuntimeException, std::exception )
189 return getSupportedServiceNames_Static();
192 css::uno::Sequence< OUString >SortedResultSet::getSupportedServiceNames_Static()
194 css::uno::Sequence< OUString > aSNS( 1 );
195 aSNS.getArray()[ 0 ] = OUString( RESULTSET_SERVICE_NAME );
196 return aSNS;
200 // XComponent methods.
202 void SAL_CALL SortedResultSet::dispose()
203 throw( RuntimeException, std::exception )
205 osl::Guard< osl::Mutex > aGuard( maMutex );
207 if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
209 EventObject aEvt;
210 aEvt.Source = static_cast< XComponent * >( this );
211 mpDisposeEventListeners->disposeAndClear( aEvt );
214 if ( mpPropChangeListeners )
216 EventObject aEvt;
217 aEvt.Source = static_cast< XPropertySet * >( this );
218 mpPropChangeListeners->disposeAndClear( aEvt );
221 if ( mpVetoChangeListeners )
223 EventObject aEvt;
224 aEvt.Source = static_cast< XPropertySet * >( this );
225 mpVetoChangeListeners->disposeAndClear( aEvt );
228 mxOriginal.clear();
229 mxOther.clear();
233 void SAL_CALL SortedResultSet::addEventListener(
234 const Reference< XEventListener >& Listener )
235 throw( RuntimeException, std::exception )
237 osl::Guard< osl::Mutex > aGuard( maMutex );
239 if ( !mpDisposeEventListeners )
240 mpDisposeEventListeners =
241 new OInterfaceContainerHelper( getContainerMutex() );
243 mpDisposeEventListeners->addInterface( Listener );
247 void SAL_CALL SortedResultSet::removeEventListener(
248 const Reference< XEventListener >& Listener )
249 throw( RuntimeException, std::exception )
251 osl::Guard< osl::Mutex > aGuard( maMutex );
253 if ( mpDisposeEventListeners )
254 mpDisposeEventListeners->removeInterface( Listener );
258 // XContentAccess methods.
261 OUString SAL_CALL
262 SortedResultSet::queryContentIdentifierString()
263 throw( RuntimeException, std::exception )
265 osl::Guard< osl::Mutex > aGuard( maMutex );
266 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
270 Reference< XContentIdentifier > SAL_CALL
271 SortedResultSet::queryContentIdentifier()
272 throw( RuntimeException, std::exception )
274 osl::Guard< osl::Mutex > aGuard( maMutex );
275 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
279 Reference< XContent > SAL_CALL
280 SortedResultSet::queryContent()
281 throw( RuntimeException, std::exception )
283 osl::Guard< osl::Mutex > aGuard( maMutex );
284 return Reference< XContentAccess >::query(mxOriginal)->queryContent();
289 // XResultSet methods.
291 sal_Bool SAL_CALL SortedResultSet::next()
292 throw ( SQLException, RuntimeException, std::exception )
294 osl::Guard< osl::Mutex > aGuard( maMutex );
296 mnCurEntry++;
298 if ( mnCurEntry > 0 )
300 if ( mnCurEntry <= mnCount )
302 sal_Int32 nIndex = maS2O[ mnCurEntry ];
303 return mxOriginal->absolute( nIndex );
305 else
307 mnCurEntry = mnCount + 1;
310 return sal_False;
314 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
315 throw ( SQLException, RuntimeException, std::exception )
317 if ( mnCurEntry )
318 return sal_False;
319 else
320 return sal_True;
324 sal_Bool SAL_CALL SortedResultSet::isAfterLast()
325 throw ( SQLException, RuntimeException, std::exception )
327 if ( mnCurEntry > mnCount )
328 return sal_True;
329 else
330 return sal_False;
334 sal_Bool SAL_CALL SortedResultSet::isFirst()
335 throw ( SQLException, RuntimeException, std::exception )
337 if ( mnCurEntry == 1 )
338 return sal_True;
339 else
340 return sal_False;
344 sal_Bool SAL_CALL SortedResultSet::isLast()
345 throw ( SQLException, RuntimeException, std::exception )
347 if ( mnCurEntry == mnCount )
348 return sal_True;
349 else
350 return sal_False;
354 void SAL_CALL SortedResultSet::beforeFirst()
355 throw ( SQLException, RuntimeException, std::exception )
357 osl::Guard< osl::Mutex > aGuard( maMutex );
358 mnCurEntry = 0;
359 mxOriginal->beforeFirst();
363 void SAL_CALL SortedResultSet::afterLast()
364 throw ( SQLException, RuntimeException, std::exception )
366 osl::Guard< osl::Mutex > aGuard( maMutex );
367 mnCurEntry = mnCount+1;
368 mxOriginal->afterLast();
372 sal_Bool SAL_CALL SortedResultSet::first()
373 throw ( SQLException, RuntimeException, std::exception )
375 osl::Guard< osl::Mutex > aGuard( maMutex );
377 if ( mnCount )
379 mnCurEntry = 1;
380 sal_Int32 nIndex = maS2O[ mnCurEntry ];
381 return mxOriginal->absolute( nIndex );
383 else
385 mnCurEntry = 0;
386 return sal_False;
391 sal_Bool SAL_CALL SortedResultSet::last()
392 throw ( SQLException, RuntimeException, std::exception )
394 osl::Guard< osl::Mutex > aGuard( maMutex );
396 if ( mnCount )
398 mnCurEntry = mnCount;
399 sal_Int32 nIndex = maS2O[ mnCurEntry ];
400 return mxOriginal->absolute( nIndex );
402 else
404 mnCurEntry = 0;
405 return sal_False;
410 sal_Int32 SAL_CALL SortedResultSet::getRow()
411 throw ( SQLException, RuntimeException, std::exception )
413 return mnCurEntry;
418 moves the cursor to the given row number in the result set.
419 <p>If the row number is positive, the cursor moves to the given row
420 number with respect to the beginning of the result set. The first
421 row is row 1, the second is row 2, and so on.
422 <p>If the given row number is negative, the cursor moves to an
423 absolute row position with respect to the end of the result set.
424 For example, calling <code>moveToPosition(-1)</code> positions the
425 cursor on the last row, <code>moveToPosition(-2)</code> indicates the
426 next-to-last row, and so on.
427 <p>An attempt to position the cursor beyond the first/last row in the
428 result set leaves the cursor before/after the first/last row,
429 respectively.
430 <p>Note: Calling <code>moveToPosition(1)</code> is the same
431 as calling <code>moveToFirst()</code>. Calling
432 <code>moveToPosition(-1)</code> is the same as calling
433 <code>moveToLast()</code>.
434 @param row
435 is the number of rows to move. Could be negative.
436 @returns
437 <TRUE/> if the cursor is on a row; <FALSE/> otherwise
438 @throws SQLException
439 if a database access error occurs or if row is 0, or the result set
440 type is FORWARD_ONLY.
442 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
443 throw ( SQLException, RuntimeException, std::exception )
445 osl::Guard< osl::Mutex > aGuard( maMutex );
447 sal_Int32 nIndex;
449 if ( row > 0 )
451 if ( row <= mnCount )
453 mnCurEntry = row;
454 nIndex = maS2O[ mnCurEntry ];
455 return mxOriginal->absolute( nIndex );
457 else
459 mnCurEntry = mnCount + 1;
460 return sal_False;
463 else if ( row == 0 )
465 throw SQLException();
467 else
469 if ( mnCount + row + 1 > 0 )
471 mnCurEntry = mnCount + row + 1;
472 nIndex = maS2O[ mnCurEntry ];
473 return mxOriginal->absolute( nIndex );
475 else
477 mnCurEntry = 0;
478 return sal_False;
485 moves the cursor a relative number of rows, either positive or negative.
487 Attempting to move beyond the first/last row in the result set positions
488 the cursor before/after the first/last row. Calling
489 <code>moveRelative(0)</code> is valid, but does not change the cursor
490 position.
491 <p>Note: Calling <code>moveRelative(1)</code> is different from calling
492 <code>moveNext()</code> because is makes sense to call
493 <code>moveNext()</code> when there is no current row, for example,
494 when the cursor is positioned before the first row or after the last
495 row of the result set.
496 @param rows
497 is the number of rows to move. Could be negative.
498 @returns
499 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
500 the result set.
501 @throws SQLException
502 if a database access error occurs or if there is no
503 current row, or the result set type is FORWARD_ONLY.
505 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
506 throw ( SQLException, RuntimeException, std::exception )
508 osl::Guard< osl::Mutex > aGuard( maMutex );
510 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
512 throw SQLException();
515 if ( rows == 0 )
516 return sal_True;
518 sal_Int32 nTmp = mnCurEntry + rows;
520 if ( nTmp <= 0 )
522 mnCurEntry = 0;
523 return sal_False;
525 else if ( nTmp > mnCount )
527 mnCurEntry = mnCount + 1;
528 return sal_False;
530 else
532 mnCurEntry = nTmp;
533 nTmp = maS2O[ mnCurEntry ];
534 return mxOriginal->absolute( nTmp );
540 moves the cursor to the previous row in the result set.
541 <p>Note: <code>previous()</code> is not the same as
542 <code>relative(-1)</code> because it makes sense to call
543 <code>previous()</code> when there is no current row.
544 @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
545 the result set.
546 @throws SQLException
547 if a database access error occurs or the result set type
548 is FORWARD_ONLY.
550 sal_Bool SAL_CALL SortedResultSet::previous()
551 throw ( SQLException, RuntimeException, std::exception )
553 osl::Guard< osl::Mutex > aGuard( maMutex );
555 mnCurEntry -= 1;
557 if ( mnCurEntry > 0 )
559 if ( mnCurEntry <= mnCount )
561 sal_Int32 nIndex = maS2O[ mnCurEntry ];
562 return mxOriginal->absolute( nIndex );
565 else
566 mnCurEntry = 0;
568 return sal_False;
572 void SAL_CALL SortedResultSet::refreshRow()
573 throw ( SQLException, RuntimeException, std::exception )
575 osl::Guard< osl::Mutex > aGuard( maMutex );
577 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
579 throw SQLException();
582 mxOriginal->refreshRow();
586 sal_Bool SAL_CALL SortedResultSet::rowUpdated()
587 throw ( SQLException, RuntimeException, std::exception )
589 osl::Guard< osl::Mutex > aGuard( maMutex );
591 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
593 throw SQLException();
596 return mxOriginal->rowUpdated();
600 sal_Bool SAL_CALL SortedResultSet::rowInserted()
601 throw ( SQLException, RuntimeException, std::exception )
603 osl::Guard< osl::Mutex > aGuard( maMutex );
605 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
607 throw SQLException();
610 return mxOriginal->rowInserted();
614 sal_Bool SAL_CALL SortedResultSet::rowDeleted()
615 throw ( SQLException, RuntimeException, std::exception )
617 osl::Guard< osl::Mutex > aGuard( maMutex );
619 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
621 throw SQLException();
624 return mxOriginal->rowDeleted();
628 Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
629 throw ( SQLException, RuntimeException, std::exception )
631 osl::Guard< osl::Mutex > aGuard( maMutex );
633 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
635 throw SQLException();
638 return mxOriginal->getStatement();
642 // XRow methods.
645 sal_Bool SAL_CALL SortedResultSet::wasNull()
646 throw( SQLException, RuntimeException, std::exception )
648 osl::Guard< osl::Mutex > aGuard( maMutex );
649 return Reference< XRow >::query(mxOriginal)->wasNull();
653 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
654 throw( SQLException, RuntimeException, std::exception )
656 osl::Guard< osl::Mutex > aGuard( maMutex );
657 return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
661 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
662 throw( SQLException, RuntimeException, std::exception )
664 osl::Guard< osl::Mutex > aGuard( maMutex );
665 return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
669 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
670 throw( SQLException, RuntimeException, std::exception )
672 osl::Guard< osl::Mutex > aGuard( maMutex );
673 return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
677 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
678 throw( SQLException, RuntimeException, std::exception )
680 osl::Guard< osl::Mutex > aGuard( maMutex );
681 return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
685 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
686 throw( SQLException, RuntimeException, std::exception )
688 osl::Guard< osl::Mutex > aGuard( maMutex );
689 return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
692 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
693 throw( SQLException, RuntimeException, std::exception )
695 osl::Guard< osl::Mutex > aGuard( maMutex );
696 return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
700 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
701 throw( SQLException, RuntimeException, std::exception )
703 osl::Guard< osl::Mutex > aGuard( maMutex );
704 return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
708 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
709 throw( SQLException, RuntimeException, std::exception )
711 osl::Guard< osl::Mutex > aGuard( maMutex );
712 return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
716 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
717 throw( SQLException, RuntimeException, std::exception )
719 osl::Guard< osl::Mutex > aGuard( maMutex );
720 return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
724 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
725 throw( SQLException, RuntimeException, std::exception )
727 osl::Guard< osl::Mutex > aGuard( maMutex );
728 return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
732 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
733 throw( SQLException, RuntimeException, std::exception )
735 osl::Guard< osl::Mutex > aGuard( maMutex );
736 return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
740 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
741 throw( SQLException, RuntimeException, std::exception )
743 osl::Guard< osl::Mutex > aGuard( maMutex );
744 return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
748 Reference< XInputStream > SAL_CALL
749 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
750 throw( SQLException, RuntimeException, std::exception )
752 osl::Guard< osl::Mutex > aGuard( maMutex );
753 return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
757 Reference< XInputStream > SAL_CALL
758 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
759 throw( SQLException, RuntimeException, std::exception )
761 osl::Guard< osl::Mutex > aGuard( maMutex );
762 return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
766 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
767 const Reference< XNameAccess >& typeMap )
768 throw( SQLException, RuntimeException, std::exception )
770 osl::Guard< osl::Mutex > aGuard( maMutex );
771 return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
772 typeMap);
776 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
777 throw( SQLException, RuntimeException, std::exception )
779 osl::Guard< osl::Mutex > aGuard( maMutex );
780 return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
784 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
785 throw( SQLException, RuntimeException, std::exception )
787 osl::Guard< osl::Mutex > aGuard( maMutex );
788 return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
792 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
793 throw( SQLException, RuntimeException, std::exception )
795 osl::Guard< osl::Mutex > aGuard( maMutex );
796 return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
800 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
801 throw( SQLException, RuntimeException, std::exception )
803 osl::Guard< osl::Mutex > aGuard( maMutex );
804 return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
809 // XCloseable methods.
812 void SAL_CALL SortedResultSet::close()
813 throw( SQLException, RuntimeException, std::exception )
815 osl::Guard< osl::Mutex > aGuard( maMutex );
816 Reference< XCloseable >::query(mxOriginal)->close();
820 // XResultSetMetaDataSupplier methods.
823 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
824 throw( SQLException, RuntimeException, std::exception )
826 osl::Guard< osl::Mutex > aGuard( maMutex );
827 return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
832 // XPropertySet methods.
835 Reference< XPropertySetInfo > SAL_CALL
836 SortedResultSet::getPropertySetInfo() throw( RuntimeException, std::exception )
838 osl::Guard< osl::Mutex > aGuard( maMutex );
840 if ( !mpPropSetInfo )
842 mpPropSetInfo = new SRSPropertySetInfo();
843 mpPropSetInfo->acquire();
846 return Reference< XPropertySetInfo >( mpPropSetInfo );
850 void SAL_CALL SortedResultSet::setPropertyValue(
851 const OUString& PropertyName,
852 const Any& )
853 throw( UnknownPropertyException,
854 PropertyVetoException,
855 IllegalArgumentException,
856 WrappedTargetException,
857 RuntimeException, std::exception )
859 osl::Guard< osl::Mutex > aGuard( maMutex );
861 if ( PropertyName.equalsAscii( "RowCount" ) ||
862 PropertyName.equalsAscii( "IsRowCountFinal" ) )
863 throw IllegalArgumentException();
864 else
865 throw UnknownPropertyException();
869 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
870 throw( UnknownPropertyException,
871 WrappedTargetException,
872 RuntimeException, std::exception )
874 osl::Guard< osl::Mutex > aGuard( maMutex );
876 Any aRet;
878 if ( PropertyName.equalsAscii( "RowCount" ) )
880 aRet <<= maS2O.Count();
882 else if ( PropertyName.equalsAscii( "IsRowCountFinal" ) )
884 bool bOrgFinal = false;
885 Any aOrgRet;
887 aRet <<= false;
889 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
890 getPropertyValue( PropertyName );
891 aOrgRet >>= bOrgFinal;
893 if ( bOrgFinal )
895 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
896 getPropertyValue("RowCount");
897 sal_uInt32 nOrgCount = 0;
898 aOrgRet >>= nOrgCount;
899 if ( nOrgCount == maS2O.Count() )
900 aRet <<= true;
903 else
904 throw UnknownPropertyException();
906 return aRet;
910 void SAL_CALL SortedResultSet::addPropertyChangeListener(
911 const OUString& PropertyName,
912 const Reference< XPropertyChangeListener >& Listener )
913 throw( UnknownPropertyException,
914 WrappedTargetException,
915 RuntimeException, std::exception )
917 osl::Guard< osl::Mutex > aGuard( maMutex );
919 if ( !mpPropChangeListeners )
920 mpPropChangeListeners =
921 new PropertyChangeListeners_Impl();
923 mpPropChangeListeners->addInterface( PropertyName, Listener );
927 void SAL_CALL SortedResultSet::removePropertyChangeListener(
928 const OUString& PropertyName,
929 const Reference< XPropertyChangeListener >& Listener )
930 throw( UnknownPropertyException,
931 WrappedTargetException,
932 RuntimeException, std::exception )
934 osl::Guard< osl::Mutex > aGuard( maMutex );
936 if ( mpPropChangeListeners )
937 mpPropChangeListeners->removeInterface( PropertyName, Listener );
941 void SAL_CALL SortedResultSet::addVetoableChangeListener(
942 const OUString& PropertyName,
943 const Reference< XVetoableChangeListener >& Listener )
944 throw( UnknownPropertyException,
945 WrappedTargetException,
946 RuntimeException, std::exception )
948 osl::Guard< osl::Mutex > aGuard( maMutex );
950 if ( !mpVetoChangeListeners )
951 mpVetoChangeListeners =
952 new PropertyChangeListeners_Impl();
954 mpVetoChangeListeners->addInterface( PropertyName, Listener );
958 void SAL_CALL SortedResultSet::removeVetoableChangeListener(
959 const OUString& PropertyName,
960 const Reference< XVetoableChangeListener >& Listener )
961 throw( UnknownPropertyException,
962 WrappedTargetException,
963 RuntimeException, std::exception )
965 osl::Guard< osl::Mutex > aGuard( maMutex );
967 if ( mpVetoChangeListeners )
968 mpVetoChangeListeners->removeInterface( PropertyName, Listener );
972 // private methods
974 sal_IntPtr SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
975 Reference < XResultSet > xResultTwo,
976 sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo,
977 SortInfo* pSortInfo )
979 throw( SQLException, RuntimeException )
981 Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
982 Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
984 sal_IntPtr nCompare = 0;
985 sal_IntPtr nColumn = pSortInfo->mnColumn;
987 switch ( pSortInfo->mnType )
989 case DataType::BIT :
990 case DataType::TINYINT :
991 case DataType::SMALLINT :
992 case DataType::INTEGER :
994 sal_Int32 aOne = 0;
995 sal_Int32 aTwo = 0;
997 if ( xResultOne->absolute( nIndexOne ) )
998 aOne = xRowOne->getInt( nColumn );
999 if ( xResultTwo->absolute( nIndexTwo ) )
1000 aTwo = xRowTwo->getInt( nColumn );
1002 if ( aOne < aTwo )
1003 nCompare = -1;
1004 else if ( aOne == aTwo )
1005 nCompare = 0;
1006 else
1007 nCompare = 1;
1009 break;
1011 case DataType::BIGINT :
1013 sal_Int64 aOne = 0;
1014 sal_Int64 aTwo = 0;
1016 if ( xResultOne->absolute( nIndexOne ) )
1017 aOne = xRowOne->getLong( nColumn );
1018 if ( xResultTwo->absolute( nIndexTwo ) )
1019 aTwo = xRowTwo->getLong( nColumn );
1021 if ( aOne < aTwo )
1022 nCompare = -1;
1023 else if ( aOne == aTwo )
1024 nCompare = 0;
1025 else
1026 nCompare = 1;
1028 break;
1030 case DataType::CHAR :
1031 case DataType::VARCHAR :
1032 case DataType::LONGVARCHAR :
1034 OUString aOne, aTwo;
1036 if ( xResultOne->absolute( nIndexOne ) )
1037 aOne = xRowOne->getString( nColumn );
1038 if ( xResultTwo->absolute( nIndexTwo ) )
1039 aTwo = xRowTwo->getString( nColumn );
1041 if ( ! pSortInfo->mbCaseSensitive )
1043 aOne = aOne.toAsciiLowerCase();
1044 aTwo = aTwo.toAsciiLowerCase();
1047 nCompare = aOne.compareTo( aTwo );
1048 break;
1050 case DataType::DATE :
1052 Date aOne, aTwo;
1053 sal_Int32 nTmp;
1055 if ( xResultOne->absolute( nIndexOne ) )
1056 aOne = xRowOne->getDate( nColumn );
1057 if ( xResultTwo->absolute( nIndexTwo ) )
1058 aTwo = xRowTwo->getDate( nColumn );
1060 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1061 if ( !nTmp ) {
1062 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1063 if ( !nTmp )
1064 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1067 if ( nTmp < 0 )
1068 nCompare = -1;
1069 else if ( nTmp == 0 )
1070 nCompare = 0;
1071 else
1072 nCompare = 1;
1074 break;
1076 case DataType::TIME :
1078 Time aOne, aTwo;
1079 sal_Int32 nTmp;
1081 if ( xResultOne->absolute( nIndexOne ) )
1082 aOne = xRowOne->getTime( nColumn );
1083 if ( xResultTwo->absolute( nIndexTwo ) )
1084 aTwo = xRowTwo->getTime( nColumn );
1086 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1087 if ( !nTmp ) {
1088 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1089 if ( !nTmp ) {
1090 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1091 if ( !nTmp )
1092 nTmp = (sal_Int32) aTwo.NanoSeconds
1093 - (sal_Int32) aOne.NanoSeconds;
1096 if ( nTmp < 0 )
1097 nCompare = -1;
1098 else if ( nTmp == 0 )
1099 nCompare = 0;
1100 else
1101 nCompare = 1;
1103 break;
1105 case DataType::TIMESTAMP :
1107 DateTime aOne, aTwo;
1108 sal_Int32 nTmp;
1110 if ( xResultOne->absolute( nIndexOne ) )
1111 aOne = xRowOne->getTimestamp( nColumn );
1112 if ( xResultTwo->absolute( nIndexTwo ) )
1113 aTwo = xRowTwo->getTimestamp( nColumn );
1115 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1116 if ( !nTmp ) {
1117 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1118 if ( !nTmp ) {
1119 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1120 if ( !nTmp ) {
1121 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1122 if ( !nTmp ) {
1123 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1124 if ( !nTmp ) {
1125 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1126 if ( !nTmp )
1127 nTmp = (sal_Int32) aTwo.NanoSeconds
1128 - (sal_Int32) aOne.NanoSeconds;
1129 }}}}}
1131 if ( nTmp < 0 )
1132 nCompare = -1;
1133 else if ( nTmp == 0 )
1134 nCompare = 0;
1135 else
1136 nCompare = 1;
1138 break;
1140 case DataType::REAL :
1142 float aOne = 0;
1143 float aTwo = 0;
1145 if ( xResultOne->absolute( nIndexOne ) )
1146 aOne = xRowOne->getFloat( nColumn );
1147 if ( xResultTwo->absolute( nIndexTwo ) )
1148 aTwo = xRowTwo->getFloat( nColumn );
1150 if ( aOne < aTwo )
1151 nCompare = -1;
1152 else if ( aOne == aTwo )
1153 nCompare = 0;
1154 else
1155 nCompare = 1;
1157 break;
1159 case DataType::FLOAT :
1160 case DataType::DOUBLE :
1162 double aOne = 0;
1163 double aTwo = 0;
1165 if ( xResultOne->absolute( nIndexOne ) )
1166 aOne = xRowOne->getDouble( nColumn );
1167 if ( xResultTwo->absolute( nIndexTwo ) )
1168 aTwo = xRowTwo->getDouble( nColumn );
1170 if ( aOne < aTwo )
1171 nCompare = -1;
1172 else if ( aOne == aTwo )
1173 nCompare = 0;
1174 else
1175 nCompare = 1;
1177 break;
1179 default:
1181 OSL_FAIL( "DataType not supported for compare!" );
1185 return nCompare;
1189 sal_IntPtr SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1190 Reference < XResultSet > xResultTwo,
1191 sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo )
1192 throw( SQLException, RuntimeException )
1194 sal_IntPtr nCompare = 0;
1195 SortInfo* pInfo = mpSortInfo;
1197 while ( !nCompare && pInfo )
1199 if ( pInfo->mbUseOwnCompare )
1201 nCompare = CompareImpl( xResultOne, xResultTwo,
1202 nIndexOne, nIndexTwo, pInfo );
1204 else
1206 Any aOne, aTwo;
1208 Reference < XRow > xRowOne =
1209 Reference< XRow >::query( xResultOne );
1210 Reference < XRow > xRowTwo =
1211 Reference< XRow >::query( xResultTwo );
1213 if ( xResultOne->absolute( nIndexOne ) )
1214 aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
1215 if ( xResultTwo->absolute( nIndexTwo ) )
1216 aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
1218 nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1221 if ( ! pInfo->mbAscending )
1222 nCompare = - nCompare;
1224 pInfo = pInfo->mpNext;
1227 return nCompare;
1231 sal_IntPtr SortedResultSet::Compare( SortListData *pOne,
1232 SortListData *pTwo )
1233 throw( SQLException, RuntimeException )
1235 sal_IntPtr nIndexOne;
1236 sal_IntPtr nIndexTwo;
1238 Reference < XResultSet > xResultOne;
1239 Reference < XResultSet > xResultTwo;
1241 if ( pOne->mbModified )
1243 xResultOne = mxOther;
1244 nIndexOne = pOne->mnOldPos;
1246 else
1248 xResultOne = mxOriginal;
1249 nIndexOne = pOne->mnCurPos;
1252 if ( pTwo->mbModified )
1254 xResultTwo = mxOther;
1255 nIndexTwo = pTwo->mnOldPos;
1257 else
1259 xResultTwo = mxOriginal;
1260 nIndexTwo = pTwo->mnCurPos;
1263 sal_IntPtr nCompare;
1264 nCompare = CompareImpl( xResultOne, xResultTwo,
1265 nIndexOne, nIndexTwo );
1266 return nCompare;
1270 sal_IntPtr SortedResultSet::FindPos( SortListData *pEntry,
1271 sal_IntPtr _nStart, sal_IntPtr _nEnd )
1272 throw( SQLException, RuntimeException )
1274 if ( _nStart > _nEnd )
1275 return _nStart + 1;
1277 sal_IntPtr nStart = _nStart;
1278 sal_IntPtr nEnd = _nEnd;
1279 sal_IntPtr nMid = 0, nCompare = 0;
1281 SortListData *pMid;
1283 while ( nStart <= nEnd )
1285 nMid = ( nEnd - nStart ) / 2 + nStart;
1286 pMid = maS2O.GetData( nMid );
1287 nCompare = Compare( pEntry, pMid );
1289 if ( !nCompare )
1290 nCompare = ((sal_IntPtr) pEntry ) - ( (sal_IntPtr) pMid );
1292 if ( nCompare < 0 ) // pEntry < pMid
1293 nEnd = nMid - 1;
1294 else
1295 nStart = nMid + 1;
1298 if ( nCompare < 0 ) // pEntry < pMid
1299 return nMid;
1300 else
1301 return nMid+1;
1305 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1307 osl::Guard< osl::Mutex > aGuard( maMutex );
1309 if ( !mpPropChangeListeners )
1310 return;
1312 // Notify listeners interested especially in the changed property.
1313 OInterfaceContainerHelper* pPropsContainer =
1314 mpPropChangeListeners->getContainer( rEvt.PropertyName );
1315 if ( pPropsContainer )
1317 OInterfaceIteratorHelper aIter( *pPropsContainer );
1318 while ( aIter.hasMoreElements() )
1320 Reference< XPropertyChangeListener > xListener(
1321 aIter.next(), UNO_QUERY );
1322 if ( xListener.is() )
1323 xListener->propertyChange( rEvt );
1327 // Notify listeners interested in all properties.
1328 pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1329 if ( pPropsContainer )
1331 OInterfaceIteratorHelper aIter( *pPropsContainer );
1332 while ( aIter.hasMoreElements() )
1334 Reference< XPropertyChangeListener > xListener(
1335 aIter.next(), UNO_QUERY );
1336 if ( xListener.is() )
1337 xListener->propertyChange( rEvt );
1345 // public methods
1348 void SortedResultSet::CopyData( SortedResultSet *pSource )
1350 const SortedEntryList *pSrcS2O = pSource->GetS2OList();
1351 const SimpleList *pSrcO2S = pSource->GetO2SList();
1353 sal_IntPtr i, nCount;
1355 maS2O.Clear();
1356 maO2S.Clear();
1357 maModList.Clear();
1359 maS2O.Insert( NULL, 0 );
1360 maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos
1362 nCount = pSrcS2O->Count();
1364 for ( i=1; i<nCount; i++ )
1366 maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
1367 maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
1370 mnLastSort = maS2O.Count();
1371 mxOther = pSource->GetResultSet();
1373 if ( !mpSortInfo )
1375 mpSortInfo = pSource->GetSortInfo();
1376 mbIsCopy = true;
1381 void SortedResultSet::Initialize(
1382 const Sequence < NumberedSortingInfo > &xSortInfo,
1383 const Reference< XAnyCompareFactory > &xCompFactory )
1385 BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1386 // Insert dummy at pos 0
1387 SortListData *pData = new SortListData( 0 );
1388 maS2O.Insert( pData, 0 );
1390 sal_IntPtr nIndex = 1;
1392 // now fetch all the elements from the original result set,
1393 // get there new position in the sorted result set and insert
1394 // an entry in the sorted to original mapping list
1395 try {
1396 while ( mxOriginal->absolute( nIndex ) )
1398 pData = new SortListData( nIndex );
1399 sal_IntPtr nPos = FindPos( pData, 1, nIndex-1 );
1401 maS2O.Insert( pData, nPos );
1403 nIndex++;
1406 catch (const SQLException&)
1408 OSL_FAIL( "SortedResultSet::Initialize() : Got unexpected SQLException" );
1411 // when we have fetched all the elements, we can create the
1412 // original to sorted mapping list from the s2o list
1413 maO2S.Clear();
1414 maO2S.Insert( NULL, (sal_uInt32) 0 );
1416 // insert some dummy entries first and replace then
1417 // the entries with the right ones
1418 size_t i;
1420 for ( i=1; i<maS2O.Count(); i++ )
1421 maO2S.Insert( (void*) 0, i ); // Insert( data, pos )
1422 for ( i=1; i<maS2O.Count(); i++ )
1423 maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
1425 mnCount = maS2O.Count() - 1;
1429 void SortedResultSet::CheckProperties( sal_IntPtr nOldCount, bool bWasFinal )
1431 osl::Guard< osl::Mutex > aGuard( maMutex );
1433 if ( !mpPropChangeListeners )
1434 return;
1436 try {
1437 // check for propertyChangeEvents
1438 if ( nOldCount != GetCount() )
1440 bool bIsFinal = false;
1441 PropertyChangeEvent aEvt;
1443 aEvt.PropertyName = "RowCount";
1444 aEvt.Further = sal_False;
1445 aEvt.PropertyHandle = -1;
1446 aEvt.OldValue <<= nOldCount;
1447 aEvt.NewValue <<= GetCount();
1449 PropertyChanged( aEvt );
1451 OUString aName = "IsRowCountFinal";
1452 Any aRet = getPropertyValue( aName );
1453 if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1455 aEvt.PropertyName = aName;
1456 aEvt.Further = sal_False;
1457 aEvt.PropertyHandle = -1;
1458 aEvt.OldValue <<= bWasFinal;
1459 aEvt.NewValue <<= bIsFinal;
1460 PropertyChanged( aEvt );
1464 catch (const UnknownPropertyException&) {}
1465 catch (const WrappedTargetException&) {}
1469 void SortedResultSet::InsertNew( sal_IntPtr nPos, sal_IntPtr nCount )
1471 // for all entries in the msS20-list, which are >= nPos, increase by nCount
1472 SortListData *pData;
1473 sal_IntPtr i, nEnd;
1475 nEnd = maS2O.Count();
1476 for ( i=1; i<=nEnd; i++ )
1478 pData = maS2O.GetData( i );
1479 if ( pData->mnCurPos >= nPos )
1481 pData->mnCurPos += nCount;
1485 // and append the new entries at the end of the maS20-list or insert at the
1486 // position nPos in the maS2O-list
1487 for ( i=0; i<nCount; i++ )
1489 nEnd += 1;
1490 pData = new SortListData( nEnd );
1492 maS2O.Insert( pData, nEnd ); // Insert( Value, Position )
1493 maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Value, Position )
1496 mnCount += nCount;
1500 void SortedResultSet::Remove( sal_IntPtr nPos, sal_IntPtr nCount, EventList *pEvents )
1502 sal_uInt32 i, j;
1503 sal_IntPtr nOldLastSort;
1505 // correct mnLastSort first
1506 nOldLastSort = mnLastSort;
1507 if ( nPos <= mnLastSort )
1509 if ( nPos + nCount - 1 <= mnLastSort )
1510 mnLastSort -= nCount;
1511 else
1512 mnLastSort = nPos - 1;
1515 // remove the entries from the lists and correct the positions
1516 // in the original2sorted list
1517 for ( i=0; i < (sal_uInt32) nCount; i++ )
1519 sal_IntPtr nSortPos = (sal_IntPtr) maO2S.GetObject( nPos );
1520 maO2S.Remove( (sal_uInt32) nPos );
1522 for ( j=1; j<=maO2S.Count(); j++ )
1524 sal_IntPtr nVal = (sal_IntPtr) maO2S.GetObject( j );
1525 if ( nVal > nSortPos )
1527 --nVal;
1528 maO2S.Replace( (void*) nVal, j );
1532 SortListData *pData = maS2O.Remove( nSortPos );
1533 if ( pData->mbModified )
1534 maModList.Remove( (void*) pData );
1535 delete pData;
1537 // generate remove Event, but not for new entries
1538 if ( nSortPos <= nOldLastSort )
1539 pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
1542 // correct the positions in the sorted list
1543 for ( i=1; i<= maS2O.Count(); i++ )
1545 SortListData *pData = maS2O.GetData( i );
1546 if ( pData->mnCurPos > nPos )
1547 pData->mnCurPos -= nCount;
1550 mnCount -= nCount;
1554 void SortedResultSet::Move( sal_IntPtr nPos, sal_IntPtr nCount, sal_IntPtr nOffset )
1556 if ( !nOffset )
1557 return;
1559 sal_IntPtr i, nSortPos, nTo;
1560 SortListData *pData;
1562 for ( i=0; i<nCount; i++ )
1564 nSortPos = (sal_IntPtr) maO2S.GetObject( nPos+i );
1565 pData = maS2O.GetData( nSortPos );
1566 pData->mnCurPos += nOffset;
1569 if ( nOffset < 0 )
1571 for ( i=nPos+nOffset; i<nPos; i++ )
1573 nSortPos = (sal_IntPtr) maO2S.GetObject( i );
1574 pData = maS2O.GetData( nSortPos );
1575 pData->mnCurPos += nCount;
1578 else
1580 sal_IntPtr nStart = nPos + nCount;
1581 sal_IntPtr nEnd = nStart + nOffset;
1582 for ( i=nStart; i<nEnd; i++ )
1584 nSortPos = (sal_IntPtr) maO2S.GetObject( i );
1585 pData = maS2O.GetData( nSortPos );
1586 pData->mnCurPos -= nCount;
1590 // remember the to be moved entries
1591 sal_IntPtr *pTmpArr = new sal_IntPtr[ nCount ];
1592 for ( i=0; i<nCount; i++ )
1593 pTmpArr[i] = (sal_IntPtr)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
1595 // now move the entries, which are in the way
1596 if ( nOffset < 0 )
1598 // be carefully here, because nOffset is negative here, so an
1599 // addition is a subtraction
1600 sal_IntPtr nFrom = nPos - 1;
1601 nTo = nPos + nCount - 1;
1603 // same for i here
1604 for ( i=0; i>nOffset; i-- )
1606 sal_IntPtr nVal = (sal_IntPtr) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
1607 maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
1611 else
1613 sal_IntPtr nStart = nPos + nCount;
1614 for ( i=0; i<nOffset; i++ )
1616 sal_IntPtr nVal = (sal_IntPtr) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
1617 maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
1621 // finally put the remembered entries at there new location
1622 nTo = nPos + nOffset;
1623 for ( i=0; i<nCount; i++ )
1625 maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
1628 delete [] pTmpArr;
1632 void SortedResultSet::BuildSortInfo(
1633 Reference< XResultSet > aResult,
1634 const Sequence < NumberedSortingInfo > &xSortInfo,
1635 const Reference< XAnyCompareFactory > &xCompFactory )
1637 Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1639 if ( ! xMeta.is() )
1641 OSL_FAIL( "No MetaData, No Sorting!" );
1642 return;
1645 Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1646 const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1648 sal_Int32 nColumn;
1649 OUString aPropName;
1650 SortInfo *pInfo;
1652 for ( sal_IntPtr i=xSortInfo.getLength(); i > 0; )
1654 --i;
1655 nColumn = pSortInfo[ i ].ColumnIndex;
1656 aPropName = xData->getColumnName( nColumn );
1657 pInfo = new SortInfo;
1659 if ( xCompFactory.is() )
1660 pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1661 aPropName );
1663 if ( pInfo->mxCompareFunction.is() )
1665 pInfo->mbUseOwnCompare = false;
1666 pInfo->mnType = 0;
1668 else
1670 pInfo->mbUseOwnCompare = true;
1671 pInfo->mnType = xData->getColumnType( nColumn );
1674 pInfo->mnColumn = nColumn;
1675 pInfo->mbAscending = pSortInfo[ i ].Ascending;
1676 pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1677 pInfo->mpNext = mpSortInfo;
1678 mpSortInfo = pInfo;
1683 void SortedResultSet::SetChanged( sal_IntPtr nPos, sal_IntPtr nCount )
1685 for ( sal_IntPtr i=0; i<nCount; i++ )
1687 sal_IntPtr nSortPos = (sal_IntPtr) maO2S.GetObject( nPos );
1688 if ( nSortPos < mnLastSort )
1690 SortListData *pData = maS2O.GetData( nSortPos );
1691 if ( ! pData->mbModified )
1693 pData->mbModified = true;
1694 maModList.Append( pData );
1697 nPos += 1;
1702 void SortedResultSet::ResortModified( EventList* pList )
1704 sal_uInt32 i, j;
1705 sal_IntPtr nCompare, nCurPos, nNewPos;
1706 sal_IntPtr nStart, nEnd, nOffset, nVal;
1707 SortListData *pData;
1708 ListAction *pAction;
1710 try {
1711 for ( i=0; i<maModList.Count(); i++ )
1713 pData = (SortListData*) maModList.GetObject( i );
1714 nCompare = CompareImpl( mxOther, mxOriginal,
1715 pData->mnOldPos, pData->mnCurPos );
1716 pData->mbModified = false;
1717 if ( nCompare != 0 )
1719 nCurPos = (sal_IntPtr) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
1720 if ( nCompare < 0 )
1722 nNewPos = FindPos( pData, 1, nCurPos-1 );
1723 nStart = nNewPos;
1724 nEnd = nCurPos;
1725 nOffset = 1;
1727 else
1729 nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1730 nStart = nCurPos;
1731 nEnd = mnLastSort;
1732 nOffset = -1;
1735 if ( nNewPos != nCurPos )
1737 // correct the lists!
1738 maS2O.Remove( (sal_uInt32) nCurPos );
1739 maS2O.Insert( pData, nNewPos );
1740 for ( j=1; j<maO2S.Count(); j++ )
1742 nVal = (sal_IntPtr) maO2S.GetObject( (sal_uInt32)( j ) );
1743 if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1745 nVal += nOffset;
1746 maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
1750 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1752 pAction = new ListAction;
1753 pAction->Position = nCurPos;
1754 pAction->Count = 1;
1755 pAction->ListActionType = ListActionType::MOVED;
1756 pAction->ActionInfo <<= nNewPos-nCurPos;
1757 pList->Insert( pAction );
1759 pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
1760 nNewPos, 1 );
1764 catch (const SQLException&)
1766 OSL_FAIL( "SortedResultSet::ResortModified() : Got unexpected SQLException" );
1769 maModList.Clear();
1773 void SortedResultSet::ResortNew( EventList* pList )
1775 sal_IntPtr i, j, nNewPos, nVal;
1776 SortListData *pData;
1778 try {
1779 for ( i = mnLastSort; i<(sal_IntPtr)maS2O.Count(); i++ )
1781 pData = (SortListData*) maModList.GetObject( i );
1782 nNewPos = FindPos( pData, 1, mnLastSort );
1783 if ( nNewPos != i )
1785 maS2O.Remove( (sal_uInt32) i );
1786 maS2O.Insert( pData, nNewPos );
1787 // maO2S liste korigieren
1788 for ( j=1; j<(sal_IntPtr)maO2S.Count(); j++ )
1790 nVal = (sal_IntPtr) maO2S.GetObject( (sal_uInt32)( j ) );
1791 if ( nVal >= nNewPos )
1792 maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
1794 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1796 mnLastSort++;
1797 pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
1800 catch (const SQLException&)
1802 OSL_FAIL( "SortedResultSet::ResortNew() : Got unexpected SQLException" );
1808 // SortListData
1811 SortListData::SortListData( sal_IntPtr nPos, bool bModified )
1813 mbModified = bModified;
1814 mnCurPos = nPos;
1815 mnOldPos = nPos;
1820 void SortedEntryList::Clear()
1822 for ( std::deque< ListAction* >::size_type i = 0;
1823 i < maData.size(); ++i )
1825 delete maData[i];
1828 maData.clear();
1832 void SortedEntryList::Insert( SortListData *pEntry, sal_IntPtr nPos )
1834 if ( nPos < (sal_IntPtr) maData.size() )
1835 maData.insert( maData.begin() + nPos, pEntry );
1836 else
1837 maData.push_back( pEntry );
1841 SortListData* SortedEntryList::Remove( sal_IntPtr nPos )
1843 SortListData *pData;
1845 if ( nPos < (sal_IntPtr) maData.size() )
1847 pData = maData[ nPos ];
1848 maData.erase( maData.begin() + nPos );
1850 else
1851 pData = NULL;
1853 return pData;
1857 SortListData* SortedEntryList::GetData( sal_IntPtr nPos )
1859 SortListData *pData;
1861 if ( nPos < (sal_IntPtr) maData.size() )
1862 pData = maData[ nPos ];
1863 else
1864 pData = NULL;
1866 return pData;
1870 sal_IntPtr SortedEntryList::operator [] ( sal_IntPtr nPos ) const
1872 SortListData *pData;
1874 if ( nPos < (sal_IntPtr) maData.size() )
1875 pData = maData[ nPos ];
1876 else
1877 pData = NULL;
1879 if ( pData )
1880 if ( ! pData->mbModified )
1881 return pData->mnCurPos;
1882 else
1884 OSL_FAIL( "SortedEntryList: Can't get value for modified entry!");
1885 return 0;
1887 else
1889 OSL_FAIL( "SortedEntryList: invalid pos!");
1890 return 0;
1897 void SimpleList::Remove( sal_uInt32 nPos )
1899 if ( nPos < (sal_uInt32) maData.size() )
1901 maData.erase( maData.begin() + nPos );
1906 void SimpleList::Remove( void* pData )
1908 bool bFound = false;
1909 sal_uInt32 i;
1911 for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
1913 if ( maData[ i ] == pData )
1915 bFound = true;
1916 break;
1920 if ( bFound )
1921 maData.erase( maData.begin() + i );
1925 void SimpleList::Insert( void* pData, sal_uInt32 nPos )
1927 if ( nPos < (sal_uInt32) maData.size() )
1928 maData.insert( maData.begin() + nPos, pData );
1929 else
1930 maData.push_back( pData );
1934 void* SimpleList::GetObject( sal_uInt32 nPos ) const
1936 if ( nPos < (sal_uInt32) maData.size() )
1937 return maData[ nPos ];
1938 else
1939 return NULL;
1943 void SimpleList::Replace( void* pData, sal_uInt32 nPos )
1945 if ( nPos < (sal_uInt32) maData.size() )
1946 maData[ nPos ] = pData;
1951 // class SRSPropertySetInfo.
1955 SRSPropertySetInfo::SRSPropertySetInfo()
1957 maProps[0].Name = "RowCount";
1958 maProps[0].Handle = -1;
1959 maProps[0].Type = ::getCppuType( (const OUString*) NULL );
1960 maProps[0].Attributes = -1;
1962 maProps[1].Name = "IsRowCountFinal";
1963 maProps[1].Handle = -1;
1964 maProps[1].Type = ::getBooleanCppuType();
1965 maProps[1].Attributes = -1;
1969 SRSPropertySetInfo::~SRSPropertySetInfo()
1972 // XPropertySetInfo methods.
1974 Sequence< Property > SAL_CALL
1975 SRSPropertySetInfo::getProperties() throw( RuntimeException, std::exception )
1977 return Sequence < Property > ( maProps, 2 );
1981 Property SAL_CALL
1982 SRSPropertySetInfo::getPropertyByName( const OUString& Name )
1983 throw( UnknownPropertyException, RuntimeException, std::exception )
1985 if ( Name.equalsAscii( "RowCount" ) )
1986 return maProps[0];
1987 else if ( Name.equalsAscii( "IsRowCountFinal" ) )
1988 return maProps[1];
1989 else
1990 throw UnknownPropertyException();
1994 sal_Bool SAL_CALL
1995 SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
1996 throw( RuntimeException, std::exception )
1998 if ( Name.equalsAscii( "RowCount" ) )
1999 return sal_True;
2000 else if ( Name.equalsAscii( "IsRowCountFinal" ) )
2001 return sal_True;
2002 else
2003 return sal_False;
2006 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */