LibreOffice Module ucb (master)  1
sortresult.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
21 #include <vector>
22 #include "sortresult.hxx"
23 #include <com/sun/star/sdbc/DataType.hpp>
24 #include <com/sun/star/sdbc/SQLException.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 <cppuhelper/implbase.hxx>
32 #include <osl/diagnose.h>
33 #include <memory>
34 
35 using namespace com::sun::star::beans;
36 using namespace com::sun::star::container;
37 using namespace com::sun::star::io;
38 using namespace com::sun::star::lang;
39 using namespace com::sun::star::sdbc;
40 using namespace com::sun::star::ucb;
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::util;
43 using namespace comphelper;
44 using namespace cppu;
45 
46 
47 // The mutex to synchronize access to containers.
48 static osl::Mutex& getContainerMutex()
49 {
50  static osl::Mutex ourMutex;
51 
52  return ourMutex;
53 }
54 
55 
56 struct SortInfo
57 {
61  sal_Int32 mnColumn;
62  sal_Int32 mnType;
65 };
66 
67 
69 {
70  bool mbModified;
71  sal_IntPtr mnCurPos;
72  sal_IntPtr mnOldPos;
73 
74  explicit SortListData( sal_IntPtr nPos );
75 };
76 
77 
78 
79 
80 class SRSPropertySetInfo : public cppu::WeakImplHelper <
81  XPropertySetInfo >
82 {
83  Property maProps[2];
84 
85 private:
86 
87 public:
89 
90  // XPropertySetInfo
91  virtual Sequence< Property > SAL_CALL getProperties() override;
92  virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override;
93  virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
94 };
95 
98 
100 {
101 public:
104 };
105 
106 
108 {
109  mpDisposeEventListeners = nullptr;
110  mpPropChangeListeners = nullptr;
111  mpVetoChangeListeners = nullptr;
112 
113  mxOriginal = aResult;
114  mpSortInfo = nullptr;
115  mnLastSort = 0;
116  mnCurEntry = 0;
117  mnCount = 0;
118  mbIsCopy = false;
119 }
120 
121 
123 {
124  mxOriginal.clear();
125  mxOther.clear();
126 
127  if ( !mbIsCopy )
128  {
129  SortInfo *pInfo = mpSortInfo;
130  while ( pInfo )
131  {
132  mpSortInfo = pInfo->mpNext;
133  delete pInfo;
134  pInfo = mpSortInfo;
135  }
136  }
137 
138  mpSortInfo = nullptr;
139 
140  mpPropSetInfo.clear();
141 }
142 
143 
144 // XServiceInfo methods.
145 
147 {
148  return "com.sun.star.comp.ucb.SortedResultSet";
149 }
150 
151 sal_Bool SAL_CALL SortedResultSet::supportsService( const OUString& ServiceName )
152 {
153  return cppu::supportsService( this, ServiceName );
154 }
155 
156 css::uno::Sequence< OUString > SAL_CALL SortedResultSet::getSupportedServiceNames()
157 {
158  return { RESULTSET_SERVICE_NAME };
159 }
160 
161 
162 // XComponent methods.
163 
165 {
166  osl::Guard< osl::Mutex > aGuard( maMutex );
167 
168  if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
169  {
170  EventObject aEvt;
171  aEvt.Source = static_cast< XComponent * >( this );
172  mpDisposeEventListeners->disposeAndClear( aEvt );
173  }
174 
175  if ( mpPropChangeListeners )
176  {
177  EventObject aEvt;
178  aEvt.Source = static_cast< XPropertySet * >( this );
179  mpPropChangeListeners->disposeAndClear( aEvt );
180  }
181 
182  if ( mpVetoChangeListeners )
183  {
184  EventObject aEvt;
185  aEvt.Source = static_cast< XPropertySet * >( this );
186  mpVetoChangeListeners->disposeAndClear( aEvt );
187  }
188 
189  mxOriginal.clear();
190  mxOther.clear();
191 }
192 
193 
195  const Reference< XEventListener >& Listener )
196 {
197  osl::Guard< osl::Mutex > aGuard( maMutex );
198 
199  if ( !mpDisposeEventListeners )
200  mpDisposeEventListeners =
202 
203  mpDisposeEventListeners->addInterface( Listener );
204 }
205 
206 
208  const Reference< XEventListener >& Listener )
209 {
210  osl::Guard< osl::Mutex > aGuard( maMutex );
211 
212  if ( mpDisposeEventListeners )
213  mpDisposeEventListeners->removeInterface( Listener );
214 }
215 
216 
217 // XContentAccess methods.
218 
219 
220 OUString SAL_CALL
222 {
223  osl::Guard< osl::Mutex > aGuard( maMutex );
224  return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
225 }
226 
227 
230 {
231  osl::Guard< osl::Mutex > aGuard( maMutex );
232  return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
233 }
234 
235 
236 Reference< XContent > SAL_CALL
238 {
239  osl::Guard< osl::Mutex > aGuard( maMutex );
240  return Reference< XContentAccess >::query(mxOriginal)->queryContent();
241 }
242 
243 
244 // XResultSet methods.
245 
247 {
248  osl::Guard< osl::Mutex > aGuard( maMutex );
249 
250  mnCurEntry++;
251 
252  if ( mnCurEntry > 0 )
253  {
254  if ( mnCurEntry <= mnCount )
255  {
256  sal_Int32 nIndex = maS2O[ mnCurEntry ];
257  return mxOriginal->absolute( nIndex );
258  }
259  else
260  {
261  mnCurEntry = mnCount + 1;
262  }
263  }
264  return false;
265 }
266 
267 
269 {
270  if ( mnCurEntry )
271  return false;
272  else
273  return true;
274 }
275 
276 
278 {
279  if ( mnCurEntry > mnCount )
280  return true;
281  else
282  return false;
283 }
284 
285 
287 {
288  if ( mnCurEntry == 1 )
289  return true;
290  else
291  return false;
292 }
293 
294 
296 {
297  if ( mnCurEntry == mnCount )
298  return true;
299  else
300  return false;
301 }
302 
303 
305 {
306  osl::Guard< osl::Mutex > aGuard( maMutex );
307  mnCurEntry = 0;
308  mxOriginal->beforeFirst();
309 }
310 
311 
313 {
314  osl::Guard< osl::Mutex > aGuard( maMutex );
315  mnCurEntry = mnCount+1;
316  mxOriginal->afterLast();
317 }
318 
319 
321 {
322  osl::Guard< osl::Mutex > aGuard( maMutex );
323 
324  if ( mnCount )
325  {
326  mnCurEntry = 1;
327  sal_Int32 nIndex = maS2O[ mnCurEntry ];
328  return mxOriginal->absolute( nIndex );
329  }
330  else
331  {
332  mnCurEntry = 0;
333  return false;
334  }
335 }
336 
337 
339 {
340  osl::Guard< osl::Mutex > aGuard( maMutex );
341 
342  if ( mnCount )
343  {
344  mnCurEntry = mnCount;
345  sal_Int32 nIndex = maS2O[ mnCurEntry ];
346  return mxOriginal->absolute( nIndex );
347  }
348  else
349  {
350  mnCurEntry = 0;
351  return false;
352  }
353 }
354 
355 
356 sal_Int32 SAL_CALL SortedResultSet::getRow()
357 {
358  return mnCurEntry;
359 }
360 
361 
387 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
388 {
389  osl::Guard< osl::Mutex > aGuard( maMutex );
390 
391  sal_Int32 nIndex;
392 
393  if ( row > 0 )
394  {
395  if ( row <= mnCount )
396  {
397  mnCurEntry = row;
398  nIndex = maS2O[ mnCurEntry ];
399  return mxOriginal->absolute( nIndex );
400  }
401  else
402  {
403  mnCurEntry = mnCount + 1;
404  return false;
405  }
406  }
407  else if ( row == 0 )
408  {
409  throw SQLException();
410  }
411  else
412  {
413  if ( mnCount + row + 1 > 0 )
414  {
415  mnCurEntry = mnCount + row + 1;
416  nIndex = maS2O[ mnCurEntry ];
417  return mxOriginal->absolute( nIndex );
418  }
419  else
420  {
421  mnCurEntry = 0;
422  return false;
423  }
424  }
425 }
426 
427 
449 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
450 {
451  osl::Guard< osl::Mutex > aGuard( maMutex );
452 
453  if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
454  {
455  throw SQLException();
456  }
457 
458  if ( rows == 0 )
459  return true;
460 
461  sal_Int32 nTmp = mnCurEntry + rows;
462 
463  if ( nTmp <= 0 )
464  {
465  mnCurEntry = 0;
466  return false;
467  }
468  else if ( nTmp > mnCount )
469  {
470  mnCurEntry = mnCount + 1;
471  return false;
472  }
473  else
474  {
475  mnCurEntry = nTmp;
476  nTmp = maS2O[ mnCurEntry ];
477  return mxOriginal->absolute( nTmp );
478  }
479 }
480 
481 
494 {
495  osl::Guard< osl::Mutex > aGuard( maMutex );
496 
497  mnCurEntry -= 1;
498 
499  if ( mnCurEntry > 0 )
500  {
501  if ( mnCurEntry <= mnCount )
502  {
503  sal_Int32 nIndex = maS2O[ mnCurEntry ];
504  return mxOriginal->absolute( nIndex );
505  }
506  }
507  else
508  mnCurEntry = 0;
509 
510  return false;
511 }
512 
513 
515 {
516  osl::Guard< osl::Mutex > aGuard( maMutex );
517 
518  if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
519  {
520  throw SQLException();
521  }
522 
523  mxOriginal->refreshRow();
524 }
525 
526 
528 {
529  osl::Guard< osl::Mutex > aGuard( maMutex );
530 
531  if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
532  {
533  throw SQLException();
534  }
535 
536  return mxOriginal->rowUpdated();
537 }
538 
539 
541 {
542  osl::Guard< osl::Mutex > aGuard( maMutex );
543 
544  if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
545  {
546  throw SQLException();
547  }
548 
549  return mxOriginal->rowInserted();
550 }
551 
552 
554 {
555  osl::Guard< osl::Mutex > aGuard( maMutex );
556 
557  if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
558  {
559  throw SQLException();
560  }
561 
562  return mxOriginal->rowDeleted();
563 }
564 
565 
567 {
568  osl::Guard< osl::Mutex > aGuard( maMutex );
569 
570  if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
571  {
572  throw SQLException();
573  }
574 
575  return mxOriginal->getStatement();
576 }
577 
578 
579 // XRow methods.
580 
581 
583 {
584  osl::Guard< osl::Mutex > aGuard( maMutex );
585  return Reference< XRow >::query(mxOriginal)->wasNull();
586 }
587 
588 
589 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
590 {
591  osl::Guard< osl::Mutex > aGuard( maMutex );
592  return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
593 }
594 
595 
596 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
597 {
598  osl::Guard< osl::Mutex > aGuard( maMutex );
599  return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
600 }
601 
602 
603 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
604 {
605  osl::Guard< osl::Mutex > aGuard( maMutex );
606  return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
607 }
608 
609 
610 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
611 {
612  osl::Guard< osl::Mutex > aGuard( maMutex );
613  return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
614 }
615 
616 
617 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
618 {
619  osl::Guard< osl::Mutex > aGuard( maMutex );
620  return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
621 }
622 
623 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
624 {
625  osl::Guard< osl::Mutex > aGuard( maMutex );
626  return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
627 }
628 
629 
630 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
631 {
632  osl::Guard< osl::Mutex > aGuard( maMutex );
633  return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
634 }
635 
636 
637 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
638 {
639  osl::Guard< osl::Mutex > aGuard( maMutex );
640  return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
641 }
642 
643 
644 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
645 {
646  osl::Guard< osl::Mutex > aGuard( maMutex );
647  return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
648 }
649 
650 
651 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
652 {
653  osl::Guard< osl::Mutex > aGuard( maMutex );
654  return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
655 }
656 
657 
658 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
659 {
660  osl::Guard< osl::Mutex > aGuard( maMutex );
661  return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
662 }
663 
664 
665 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
666 {
667  osl::Guard< osl::Mutex > aGuard( maMutex );
668  return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
669 }
670 
671 
673 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
674 {
675  osl::Guard< osl::Mutex > aGuard( maMutex );
676  return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
677 }
678 
679 
681 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
682 {
683  osl::Guard< osl::Mutex > aGuard( maMutex );
684  return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
685 }
686 
687 
688 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
689  const Reference< XNameAccess >& typeMap )
690 {
691  osl::Guard< osl::Mutex > aGuard( maMutex );
692  return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
693  typeMap);
694 }
695 
696 
697 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
698 {
699  osl::Guard< osl::Mutex > aGuard( maMutex );
700  return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
701 }
702 
703 
704 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
705 {
706  osl::Guard< osl::Mutex > aGuard( maMutex );
707  return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
708 }
709 
710 
711 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
712 {
713  osl::Guard< osl::Mutex > aGuard( maMutex );
714  return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
715 }
716 
717 
718 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
719 {
720  osl::Guard< osl::Mutex > aGuard( maMutex );
721  return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
722 }
723 
724 
725 // XCloseable methods.
726 
727 
728 void SAL_CALL SortedResultSet::close()
729 {
730  osl::Guard< osl::Mutex > aGuard( maMutex );
731  Reference< XCloseable >::query(mxOriginal)->close();
732 }
733 
734 
735 // XResultSetMetaDataSupplier methods.
736 
737 
739 {
740  osl::Guard< osl::Mutex > aGuard( maMutex );
741  return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
742 }
743 
744 
745 // XPropertySet methods.
746 
747 
750 {
751  osl::Guard< osl::Mutex > aGuard( maMutex );
752 
753  if ( !mpPropSetInfo.is() )
754  {
755  mpPropSetInfo = new SRSPropertySetInfo();
756  }
757 
758  return Reference< XPropertySetInfo >( mpPropSetInfo.get() );
759 }
760 
761 
763  const OUString& PropertyName,
764  const Any& )
765 {
766  osl::Guard< osl::Mutex > aGuard( maMutex );
767 
768  if ( PropertyName == "RowCount" || PropertyName == "IsRowCountFinal" )
769  throw IllegalArgumentException();
770  else
771  throw UnknownPropertyException(PropertyName);
772 }
773 
774 
775 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
776 {
777  osl::Guard< osl::Mutex > aGuard( maMutex );
778 
779  Any aRet;
780 
781  if ( PropertyName == "RowCount" )
782  {
783  aRet <<= maS2O.Count();
784  }
785  else if ( PropertyName == "IsRowCountFinal" )
786  {
787  bool bOrgFinal = false;
788  Any aOrgRet;
789 
790  aRet <<= false;
791 
792  aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
793  getPropertyValue( PropertyName );
794  aOrgRet >>= bOrgFinal;
795 
796  if ( bOrgFinal )
797  {
798  aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
799  getPropertyValue("RowCount");
800  sal_uInt32 nOrgCount = 0;
801  aOrgRet >>= nOrgCount;
802  if ( nOrgCount == maS2O.Count() )
803  aRet <<= true;
804  }
805  }
806  else
807  throw UnknownPropertyException(PropertyName);
808 
809  return aRet;
810 }
811 
812 
814  const OUString& PropertyName,
815  const Reference< XPropertyChangeListener >& Listener )
816 {
817  osl::Guard< osl::Mutex > aGuard( maMutex );
818 
819  if ( !mpPropChangeListeners )
820  mpPropChangeListeners.reset(
822 
823  mpPropChangeListeners->addInterface( PropertyName, Listener );
824 }
825 
826 
828  const OUString& PropertyName,
829  const Reference< XPropertyChangeListener >& Listener )
830 {
831  osl::Guard< osl::Mutex > aGuard( maMutex );
832 
833  if ( mpPropChangeListeners )
834  mpPropChangeListeners->removeInterface( PropertyName, Listener );
835 }
836 
837 
839  const OUString& PropertyName,
840  const Reference< XVetoableChangeListener >& Listener )
841 {
842  osl::Guard< osl::Mutex > aGuard( maMutex );
843 
844  if ( !mpVetoChangeListeners )
845  mpVetoChangeListeners.reset(
847 
848  mpVetoChangeListeners->addInterface( PropertyName, Listener );
849 }
850 
851 
853  const OUString& PropertyName,
854  const Reference< XVetoableChangeListener >& Listener )
855 {
856  osl::Guard< osl::Mutex > aGuard( maMutex );
857 
858  if ( mpVetoChangeListeners )
859  mpVetoChangeListeners->removeInterface( PropertyName, Listener );
860 }
861 
862 
863 // private methods
864 
865 sal_IntPtr SortedResultSet::CompareImpl( const Reference < XResultSet >& xResultOne,
866  const Reference < XResultSet >& xResultTwo,
867  sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo,
868  SortInfo const * pSortInfo )
869 {
870  Reference < XRow > xRowOne( xResultOne, UNO_QUERY );
871  Reference < XRow > xRowTwo( xResultTwo, UNO_QUERY );
872 
873  sal_IntPtr nCompare = 0;
874  sal_Int32 nColumn = pSortInfo->mnColumn;
875 
876  switch ( pSortInfo->mnType )
877  {
878  case DataType::BIT :
879  case DataType::TINYINT :
880  case DataType::SMALLINT :
881  case DataType::INTEGER :
882  {
883  sal_Int32 aOne = 0;
884  sal_Int32 aTwo = 0;
885 
886  if ( xResultOne->absolute( nIndexOne ) )
887  aOne = xRowOne->getInt( nColumn );
888  if ( xResultTwo->absolute( nIndexTwo ) )
889  aTwo = xRowTwo->getInt( nColumn );
890 
891  if ( aOne < aTwo )
892  nCompare = -1;
893  else if ( aOne == aTwo )
894  nCompare = 0;
895  else
896  nCompare = 1;
897 
898  break;
899  }
900  case DataType::BIGINT :
901  {
902  sal_Int64 aOne = 0;
903  sal_Int64 aTwo = 0;
904 
905  if ( xResultOne->absolute( nIndexOne ) )
906  aOne = xRowOne->getLong( nColumn );
907  if ( xResultTwo->absolute( nIndexTwo ) )
908  aTwo = xRowTwo->getLong( nColumn );
909 
910  if ( aOne < aTwo )
911  nCompare = -1;
912  else if ( aOne == aTwo )
913  nCompare = 0;
914  else
915  nCompare = 1;
916 
917  break;
918  }
919  case DataType::CHAR :
920  case DataType::VARCHAR :
921  case DataType::LONGVARCHAR :
922  {
923  OUString aOne, aTwo;
924 
925  if ( xResultOne->absolute( nIndexOne ) )
926  aOne = xRowOne->getString( nColumn );
927  if ( xResultTwo->absolute( nIndexTwo ) )
928  aTwo = xRowTwo->getString( nColumn );
929 
930  if ( ! pSortInfo->mbCaseSensitive )
931  {
932  aOne = aOne.toAsciiLowerCase();
933  aTwo = aTwo.toAsciiLowerCase();
934  }
935 
936  nCompare = aOne.compareTo( aTwo );
937  break;
938  }
939  case DataType::DATE :
940  {
941  Date aOne, aTwo;
942  sal_Int32 nTmp;
943 
944  if ( xResultOne->absolute( nIndexOne ) )
945  aOne = xRowOne->getDate( nColumn );
946  if ( xResultTwo->absolute( nIndexTwo ) )
947  aTwo = xRowTwo->getDate( nColumn );
948 
949  nTmp = static_cast<sal_Int32>(aTwo.Year) - static_cast<sal_Int32>(aOne.Year);
950  if ( !nTmp ) {
951  nTmp = static_cast<sal_Int32>(aTwo.Month) - static_cast<sal_Int32>(aOne.Month);
952  if ( !nTmp )
953  nTmp = static_cast<sal_Int32>(aTwo.Day) - static_cast<sal_Int32>(aOne.Day);
954  }
955 
956  if ( nTmp < 0 )
957  nCompare = -1;
958  else if ( nTmp == 0 )
959  nCompare = 0;
960  else
961  nCompare = 1;
962 
963  break;
964  }
965  case DataType::TIME :
966  {
967  Time aOne, aTwo;
968  sal_Int32 nTmp;
969 
970  if ( xResultOne->absolute( nIndexOne ) )
971  aOne = xRowOne->getTime( nColumn );
972  if ( xResultTwo->absolute( nIndexTwo ) )
973  aTwo = xRowTwo->getTime( nColumn );
974 
975  nTmp = static_cast<sal_Int32>(aTwo.Hours) - static_cast<sal_Int32>(aOne.Hours);
976  if ( !nTmp )
977  nTmp = static_cast<sal_Int32>(aTwo.Minutes) - static_cast<sal_Int32>(aOne.Minutes);
978  if ( !nTmp )
979  nTmp = static_cast<sal_Int32>(aTwo.Seconds) - static_cast<sal_Int32>(aOne.Seconds);
980  if ( !nTmp )
981  nTmp = static_cast<sal_Int32>(aTwo.NanoSeconds)
982  - static_cast<sal_Int32>(aOne.NanoSeconds);
983 
984  if ( nTmp < 0 )
985  nCompare = -1;
986  else if ( nTmp == 0 )
987  nCompare = 0;
988  else
989  nCompare = 1;
990 
991  break;
992  }
993  case DataType::TIMESTAMP :
994  {
995  DateTime aOne, aTwo;
996  sal_Int32 nTmp;
997 
998  if ( xResultOne->absolute( nIndexOne ) )
999  aOne = xRowOne->getTimestamp( nColumn );
1000  if ( xResultTwo->absolute( nIndexTwo ) )
1001  aTwo = xRowTwo->getTimestamp( nColumn );
1002 
1003  nTmp = static_cast<sal_Int32>(aTwo.Year) - static_cast<sal_Int32>(aOne.Year);
1004  if ( !nTmp )
1005  nTmp = static_cast<sal_Int32>(aTwo.Month) - static_cast<sal_Int32>(aOne.Month);
1006  if ( !nTmp )
1007  nTmp = static_cast<sal_Int32>(aTwo.Day) - static_cast<sal_Int32>(aOne.Day);
1008  if ( !nTmp )
1009  nTmp = static_cast<sal_Int32>(aTwo.Hours) - static_cast<sal_Int32>(aOne.Hours);
1010  if ( !nTmp )
1011  nTmp = static_cast<sal_Int32>(aTwo.Minutes) - static_cast<sal_Int32>(aOne.Minutes);
1012  if ( !nTmp )
1013  nTmp = static_cast<sal_Int32>(aTwo.Seconds) - static_cast<sal_Int32>(aOne.Seconds);
1014  if ( !nTmp )
1015  nTmp = static_cast<sal_Int32>(aTwo.NanoSeconds)
1016  - static_cast<sal_Int32>(aOne.NanoSeconds);
1017 
1018  if ( nTmp < 0 )
1019  nCompare = -1;
1020  else if ( nTmp == 0 )
1021  nCompare = 0;
1022  else
1023  nCompare = 1;
1024 
1025  break;
1026  }
1027  case DataType::REAL :
1028  {
1029  float aOne = 0;
1030  float aTwo = 0;
1031 
1032  if ( xResultOne->absolute( nIndexOne ) )
1033  aOne = xRowOne->getFloat( nColumn );
1034  if ( xResultTwo->absolute( nIndexTwo ) )
1035  aTwo = xRowTwo->getFloat( nColumn );
1036 
1037  if ( aOne < aTwo )
1038  nCompare = -1;
1039  else if ( aOne == aTwo )
1040  nCompare = 0;
1041  else
1042  nCompare = 1;
1043 
1044  break;
1045  }
1046  case DataType::FLOAT :
1047  case DataType::DOUBLE :
1048  {
1049  double aOne = 0;
1050  double aTwo = 0;
1051 
1052  if ( xResultOne->absolute( nIndexOne ) )
1053  aOne = xRowOne->getDouble( nColumn );
1054  if ( xResultTwo->absolute( nIndexTwo ) )
1055  aTwo = xRowTwo->getDouble( nColumn );
1056 
1057  if ( aOne < aTwo )
1058  nCompare = -1;
1059  else if ( aOne == aTwo )
1060  nCompare = 0;
1061  else
1062  nCompare = 1;
1063 
1064  break;
1065  }
1066  default:
1067  {
1068  OSL_FAIL( "DataType not supported for compare!" );
1069  }
1070  }
1071 
1072  return nCompare;
1073 }
1074 
1075 
1076 sal_IntPtr SortedResultSet::CompareImpl( const Reference < XResultSet >& xResultOne,
1077  const Reference < XResultSet >& xResultTwo,
1078  sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo )
1079 {
1080  sal_IntPtr nCompare = 0;
1081  SortInfo* pInfo = mpSortInfo;
1082 
1083  while ( !nCompare && pInfo )
1084  {
1085  if ( pInfo->mbUseOwnCompare )
1086  {
1087  nCompare = CompareImpl( xResultOne, xResultTwo,
1088  nIndexOne, nIndexTwo, pInfo );
1089  }
1090  else
1091  {
1092  Any aOne, aTwo;
1093 
1094  Reference < XRow > xRowOne =
1095  Reference< XRow >::query( xResultOne );
1096  Reference < XRow > xRowTwo =
1097  Reference< XRow >::query( xResultTwo );
1098 
1099  if ( xResultOne->absolute( nIndexOne ) )
1100  aOne = xRowOne->getObject( pInfo->mnColumn, nullptr );
1101  if ( xResultTwo->absolute( nIndexTwo ) )
1102  aTwo = xRowTwo->getObject( pInfo->mnColumn, nullptr );
1103 
1104  nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1105  }
1106 
1107  if ( ! pInfo->mbAscending )
1108  nCompare = - nCompare;
1109 
1110  pInfo = pInfo->mpNext;
1111  }
1112 
1113  return nCompare;
1114 }
1115 
1116 
1117 sal_IntPtr SortedResultSet::Compare( SortListData const *pOne,
1118  SortListData const *pTwo )
1119 {
1120  sal_IntPtr nIndexOne;
1121  sal_IntPtr nIndexTwo;
1122 
1123  Reference < XResultSet > xResultOne;
1124  Reference < XResultSet > xResultTwo;
1125 
1126  if ( pOne->mbModified )
1127  {
1128  xResultOne = mxOther;
1129  nIndexOne = pOne->mnOldPos;
1130  }
1131  else
1132  {
1133  xResultOne = mxOriginal;
1134  nIndexOne = pOne->mnCurPos;
1135  }
1136 
1137  if ( pTwo->mbModified )
1138  {
1139  xResultTwo = mxOther;
1140  nIndexTwo = pTwo->mnOldPos;
1141  }
1142  else
1143  {
1144  xResultTwo = mxOriginal;
1145  nIndexTwo = pTwo->mnCurPos;
1146  }
1147 
1148  sal_IntPtr nCompare;
1149  nCompare = CompareImpl( xResultOne, xResultTwo,
1150  nIndexOne, nIndexTwo );
1151  return nCompare;
1152 }
1153 
1154 
1155 sal_IntPtr SortedResultSet::FindPos( SortListData const *pEntry,
1156  sal_IntPtr _nStart, sal_IntPtr _nEnd )
1157 {
1158  if ( _nStart > _nEnd )
1159  return _nStart + 1;
1160 
1161  sal_IntPtr nStart = _nStart;
1162  sal_IntPtr nEnd = _nEnd;
1163  sal_IntPtr nMid = 0, nCompare = 0;
1164 
1165 
1166  while ( nStart <= nEnd )
1167  {
1168  nMid = ( nEnd - nStart ) / 2 + nStart;
1169  SortListData *pMid = maS2O.GetData( nMid );
1170  nCompare = Compare( pEntry, pMid );
1171 
1172  if ( !nCompare )
1173  nCompare = (pEntry != pMid) ? ((pEntry < pMid) ? -1 : 1) : 0;
1174 
1175  if ( nCompare < 0 ) // pEntry < pMid
1176  nEnd = nMid - 1;
1177  else
1178  nStart = nMid + 1;
1179  }
1180 
1181  if ( nCompare < 0 ) // pEntry < pMid
1182  return nMid;
1183  else
1184  return nMid+1;
1185 }
1186 
1187 
1188 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1189 {
1190  osl::Guard< osl::Mutex > aGuard( maMutex );
1191 
1192  if ( !mpPropChangeListeners )
1193  return;
1194 
1195  // Notify listeners interested especially in the changed property.
1196  OInterfaceContainerHelper* pPropsContainer =
1197  mpPropChangeListeners->getContainer( rEvt.PropertyName );
1198  if ( pPropsContainer )
1199  {
1200  OInterfaceIteratorHelper aIter( *pPropsContainer );
1201  while ( aIter.hasMoreElements() )
1202  {
1204  aIter.next(), UNO_QUERY );
1205  if ( xListener.is() )
1206  xListener->propertyChange( rEvt );
1207  }
1208  }
1209 
1210  // Notify listeners interested in all properties.
1211  pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1212  if ( pPropsContainer )
1213  {
1214  OInterfaceIteratorHelper aIter( *pPropsContainer );
1215  while ( aIter.hasMoreElements() )
1216  {
1218  aIter.next(), UNO_QUERY );
1219  if ( xListener.is() )
1220  xListener->propertyChange( rEvt );
1221  }
1222  }
1223 }
1224 
1225 
1226 // public methods
1227 
1228 
1230 {
1231  const SortedEntryList& rSrcS2O = pSource->maS2O;
1232 
1233  sal_IntPtr i, nCount;
1234 
1235  maS2O.Clear();
1236  m_O2S.clear();
1237  m_ModList.clear();
1238 
1239  maS2O.Insert( nullptr, 0 );
1240  m_O2S.push_back(0);
1241 
1242  nCount = rSrcS2O.Count();
1243 
1244  for ( i=1; i<nCount; i++ )
1245  {
1246  maS2O.Insert( std::unique_ptr<SortListData>(new SortListData( rSrcS2O[ i ] )), i );
1247  m_O2S.push_back(pSource->m_O2S[i]);
1248  }
1249 
1250  mnLastSort = maS2O.Count();
1251  mxOther = pSource->mxOriginal;
1252 
1253  if ( !mpSortInfo )
1254  {
1255  mpSortInfo = pSource->mpSortInfo;
1256  mbIsCopy = true;
1257  }
1258 }
1259 
1260 
1262  const Sequence < NumberedSortingInfo > &xSortInfo,
1263  const Reference< XAnyCompareFactory > &xCompFactory )
1264 {
1265  BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1266  // Insert dummy at pos 0
1267  maS2O.Insert( std::unique_ptr<SortListData>(new SortListData( 0 )), 0 );
1268 
1269  sal_IntPtr nIndex = 1;
1270 
1271  // now fetch all the elements from the original result set,
1272  // get there new position in the sorted result set and insert
1273  // an entry in the sorted to original mapping list
1274  try {
1275  while ( mxOriginal->absolute( nIndex ) )
1276  {
1277  std::unique_ptr<SortListData> pData(new SortListData( nIndex ));
1278  sal_IntPtr nPos = FindPos( pData.get(), 1, nIndex-1 );
1279 
1280  maS2O.Insert( std::move(pData), nPos );
1281 
1282  nIndex++;
1283  }
1284  }
1285  catch (const SQLException&)
1286  {
1287  OSL_FAIL( "SortedResultSet::Initialize() : Got unexpected SQLException" );
1288  }
1289 
1290  // when we have fetched all the elements, we can create the
1291  // original to sorted mapping list from the s2o list
1292  m_O2S.clear();
1293  m_O2S.push_back(0);
1294 
1295  // insert some dummy entries first and replace then
1296  // the entries with the right ones
1297  size_t i;
1298 
1299  for ( i=1; i<maS2O.Count(); i++ )
1300  m_O2S.push_back(0);
1301  for ( i=1; i<maS2O.Count(); i++ )
1302  m_O2S[maS2O[i]] = i;
1303 
1304  mnCount = maS2O.Count() - 1;
1305 }
1306 
1307 
1308 void SortedResultSet::CheckProperties( sal_IntPtr nOldCount, bool bWasFinal )
1309 {
1310  osl::Guard< osl::Mutex > aGuard( maMutex );
1311 
1312  if ( !mpPropChangeListeners )
1313  return;
1314 
1315  try {
1316  // check for propertyChangeEvents
1317  if ( nOldCount != GetCount() )
1318  {
1319  bool bIsFinal = false;
1320  PropertyChangeEvent aEvt;
1321 
1322  aEvt.PropertyName = "RowCount";
1323  aEvt.Further = false;
1324  aEvt.PropertyHandle = -1;
1325  aEvt.OldValue <<= nOldCount;
1326  aEvt.NewValue <<= GetCount();
1327 
1328  PropertyChanged( aEvt );
1329 
1330  OUString aName = "IsRowCountFinal";
1331  Any aRet = getPropertyValue( aName );
1332  if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1333  {
1334  aEvt.PropertyName = aName;
1335  aEvt.Further = false;
1336  aEvt.PropertyHandle = -1;
1337  aEvt.OldValue <<= bWasFinal;
1338  aEvt.NewValue <<= bIsFinal;
1339  PropertyChanged( aEvt );
1340  }
1341  }
1342  }
1343  catch (const UnknownPropertyException&) {}
1344  catch (const WrappedTargetException&) {}
1345 }
1346 
1347 
1348 void SortedResultSet::InsertNew( sal_IntPtr nPos, sal_IntPtr nCount )
1349 {
1350  // for all entries in the msS20-list, which are >= nPos, increase by nCount
1351  sal_IntPtr i, nEnd;
1352 
1353  nEnd = maS2O.Count();
1354  for ( i=1; i<=nEnd; i++ )
1355  {
1356  SortListData *pData = maS2O.GetData( i );
1357  if ( pData->mnCurPos >= nPos )
1358  {
1359  pData->mnCurPos += nCount;
1360  }
1361  }
1362 
1363  // and append the new entries at the end of the maS2O-list or insert at the
1364  // position nPos in the maS2O-list
1365  for ( i=0; i<nCount; i++ )
1366  {
1367  nEnd += 1;
1368  std::unique_ptr<SortListData> pData(new SortListData( nEnd ));
1369 
1370  maS2O.Insert( std::move(pData), nEnd ); // Insert( Value, Position )
1371  m_O2S.insert(m_O2S.begin() + nPos + i, nEnd);
1372  }
1373 
1374  mnCount += nCount;
1375 }
1376 
1377 
1378 void SortedResultSet::Remove( sal_IntPtr nPos, sal_IntPtr nCount, EventList *pEvents )
1379 {
1380  sal_IntPtr nOldLastSort;
1381 
1382  // correct mnLastSort first
1383  nOldLastSort = mnLastSort;
1384  if ( nPos <= mnLastSort )
1385  {
1386  if ( nPos + nCount - 1 <= mnLastSort )
1387  mnLastSort -= nCount;
1388  else
1389  mnLastSort = nPos - 1;
1390  }
1391 
1392  // remove the entries from the lists and correct the positions
1393  // in the original2sorted list
1394  for ( sal_IntPtr i=0; i < nCount; i++ )
1395  {
1396  sal_IntPtr nSortPos = m_O2S[nPos];
1397  m_O2S.erase(m_O2S.begin() + nPos);
1398 
1399  for (size_t j=1; j < m_O2S.size(); ++j)
1400  {
1401  sal_IntPtr nVal = m_O2S[j];
1402  if ( nVal > nSortPos )
1403  {
1404  --nVal;
1405  m_O2S[j] = nVal;
1406  }
1407  }
1408 
1409  std::unique_ptr<SortListData> pData = maS2O.Remove( nSortPos );
1410  if ( pData->mbModified )
1411  m_ModList.erase(std::find(m_ModList.begin(), m_ModList.end(), pData.get()));
1412 
1413  // generate remove Event, but not for new entries
1414  if ( nSortPos <= nOldLastSort )
1415  pEvents->AddEvent( ListActionType::REMOVED, nSortPos );
1416  }
1417 
1418  // correct the positions in the sorted list
1419  for ( sal_uInt32 i=1; i<= maS2O.Count(); i++ )
1420  {
1421  SortListData *pData = maS2O.GetData( i );
1422  if ( pData->mnCurPos > nPos )
1423  pData->mnCurPos -= nCount;
1424  }
1425 
1426  mnCount -= nCount;
1427 }
1428 
1429 
1430 void SortedResultSet::Move( sal_IntPtr nPos, sal_IntPtr nCount, sal_IntPtr nOffset )
1431 {
1432  if ( !nOffset )
1433  return;
1434 
1435  sal_IntPtr i, nSortPos, nTo;
1437 
1438  for ( i=0; i<nCount; i++ )
1439  {
1440  nSortPos = m_O2S[nPos + i];
1441  pData = maS2O.GetData( nSortPos );
1442  pData->mnCurPos += nOffset;
1443  }
1444 
1445  if ( nOffset < 0 )
1446  {
1447  for ( i=nPos+nOffset; i<nPos; i++ )
1448  {
1449  nSortPos = m_O2S[i];
1450  pData = maS2O.GetData( nSortPos );
1451  pData->mnCurPos += nCount;
1452  }
1453  }
1454  else
1455  {
1456  sal_IntPtr nStart = nPos + nCount;
1457  sal_IntPtr nEnd = nStart + nOffset;
1458  for ( i=nStart; i<nEnd; i++ )
1459  {
1460  nSortPos = m_O2S[i];
1461  pData = maS2O.GetData( nSortPos );
1462  pData->mnCurPos -= nCount;
1463  }
1464  }
1465 
1466  // remember the to be moved entries
1467  std::unique_ptr<sal_IntPtr[]> pTmpArr(new sal_IntPtr[ nCount ]);
1468  for ( i=0; i<nCount; i++ )
1469  pTmpArr[i] = m_O2S[nPos + i];
1470 
1471  // now move the entries, which are in the way
1472  if ( nOffset < 0 )
1473  {
1474  // be carefully here, because nOffset is negative here, so an
1475  // addition is a subtraction
1476  sal_IntPtr nFrom = nPos - 1;
1477  nTo = nPos + nCount - 1;
1478 
1479  // same for i here
1480  for ( i=0; i>nOffset; i-- )
1481  {
1482  sal_IntPtr const nVal = m_O2S[nFrom + i];
1483  m_O2S[nTo + i] = nVal;
1484  }
1485 
1486  }
1487  else
1488  {
1489  sal_IntPtr nStart = nPos + nCount;
1490  for ( i=0; i<nOffset; i++ )
1491  {
1492  sal_IntPtr const nVal = m_O2S[nStart + i];
1493  m_O2S[nPos + i] = nVal;
1494  }
1495  }
1496 
1497  // finally put the remembered entries at their new location
1498  nTo = nPos + nOffset;
1499  for ( i=0; i<nCount; i++ )
1500  {
1501  m_O2S[nTo + i] = pTmpArr[i];
1502  }
1503 }
1504 
1505 
1507  const Reference< XResultSet >& aResult,
1508  const Sequence < NumberedSortingInfo > &xSortInfo,
1509  const Reference< XAnyCompareFactory > &xCompFactory )
1510 {
1511  Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1512 
1513  if ( ! xMeta.is() )
1514  {
1515  OSL_FAIL( "No MetaData, No Sorting!" );
1516  return;
1517  }
1518 
1519  Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1520  const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1521 
1522  sal_Int32 nColumn;
1523  OUString aPropName;
1524  SortInfo *pInfo;
1525 
1526  for ( sal_Int32 i=xSortInfo.getLength(); i > 0; )
1527  {
1528  --i;
1529  nColumn = pSortInfo[ i ].ColumnIndex;
1530  aPropName = xData->getColumnName( nColumn );
1531  pInfo = new SortInfo;
1532 
1533  if ( xCompFactory.is() )
1534  pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1535  aPropName );
1536 
1537  if ( pInfo->mxCompareFunction.is() )
1538  {
1539  pInfo->mbUseOwnCompare = false;
1540  pInfo->mnType = 0;
1541  }
1542  else
1543  {
1544  pInfo->mbUseOwnCompare = true;
1545  pInfo->mnType = xData->getColumnType( nColumn );
1546  }
1547 
1548  pInfo->mnColumn = nColumn;
1549  pInfo->mbAscending = pSortInfo[ i ].Ascending;
1550  pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1551  pInfo->mpNext = mpSortInfo;
1552  mpSortInfo = pInfo;
1553  }
1554 }
1555 
1556 
1557 void SortedResultSet::SetChanged( sal_IntPtr nPos, sal_IntPtr nCount )
1558 {
1559  for ( sal_IntPtr i=0; i<nCount; i++ )
1560  {
1561  sal_IntPtr const nSortPos = m_O2S[nPos];
1562  if ( nSortPos < mnLastSort )
1563  {
1564  SortListData *pData = maS2O.GetData( nSortPos );
1565  if ( ! pData->mbModified )
1566  {
1567  pData->mbModified = true;
1568  m_ModList.push_back(pData);
1569  }
1570  }
1571  nPos += 1;
1572  }
1573 }
1574 
1575 
1577 {
1578  sal_IntPtr nCompare, nCurPos, nNewPos;
1579  sal_IntPtr nStart, nEnd, nOffset, nVal;
1580 
1581  try {
1582  for (size_t i = 0; i < m_ModList.size(); ++i)
1583  {
1584  SortListData *const pData = m_ModList[i];
1585  nCompare = CompareImpl( mxOther, mxOriginal,
1586  pData->mnOldPos, pData->mnCurPos );
1587  pData->mbModified = false;
1588  if ( nCompare != 0 )
1589  {
1590  nCurPos = m_O2S[pData->mnCurPos];
1591  if ( nCompare < 0 )
1592  {
1593  nNewPos = FindPos( pData, 1, nCurPos-1 );
1594  nStart = nNewPos;
1595  nEnd = nCurPos;
1596  nOffset = 1;
1597  }
1598  else
1599  {
1600  nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1601  nStart = nCurPos;
1602  nEnd = mnLastSort;
1603  nOffset = -1;
1604  }
1605 
1606  if ( nNewPos != nCurPos )
1607  {
1608  // correct the lists!
1609  maS2O.Move( static_cast<sal_uInt32>(nCurPos), nNewPos );
1610  for (size_t j = 1; j < m_O2S.size(); ++j)
1611  {
1612  nVal = m_O2S[j];
1613  if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1614  {
1615  nVal += nOffset;
1616  m_O2S[j] = nVal;
1617  }
1618  }
1619 
1620  m_O2S[pData->mnCurPos] = nNewPos;
1621 
1622  std::unique_ptr<ListAction> pAction(new ListAction);
1623  pAction->Position = nCurPos;
1624  pAction->Count = 1;
1625  pAction->ListActionType = ListActionType::MOVED;
1626  pAction->ActionInfo <<= nNewPos-nCurPos;
1627  pList->Insert( std::move(pAction) );
1628  }
1629  pList->AddEvent( ListActionType::PROPERTIES_CHANGED, nNewPos );
1630  }
1631  }
1632  }
1633  catch (const SQLException&)
1634  {
1635  OSL_FAIL( "SortedResultSet::ResortModified() : Got unexpected SQLException" );
1636  }
1637 
1638  m_ModList.clear();
1639 }
1640 
1641 
1643 {
1644  sal_IntPtr i, nNewPos, nVal;
1645 
1646  try {
1647  for ( i = mnLastSort; i<static_cast<sal_IntPtr>(maS2O.Count()); i++ )
1648  {
1649  SortListData *const pData = m_ModList[i];
1650  nNewPos = FindPos( pData, 1, mnLastSort );
1651  if ( nNewPos != i )
1652  {
1653  maS2O.Move( static_cast<sal_uInt32>(i), nNewPos );
1654  for (size_t j=1; j< m_O2S.size(); ++j)
1655  {
1656  nVal = m_O2S[j];
1657  if ( nVal >= nNewPos )
1658  m_O2S[j] = nVal + 1;
1659  }
1660  m_O2S[pData->mnCurPos] = nNewPos;
1661  }
1662  mnLastSort++;
1663  pList->AddEvent( ListActionType::INSERTED, nNewPos );
1664  }
1665  }
1666  catch (const SQLException&)
1667  {
1668  OSL_FAIL( "SortedResultSet::ResortNew() : Got unexpected SQLException" );
1669  }
1670 }
1671 
1672 
1673 // SortListData
1674 
1675 
1676 SortListData::SortListData( sal_IntPtr nPos )
1677  : mbModified(false)
1678  , mnCurPos(nPos)
1679  , mnOldPos(nPos)
1680 {
1681 };
1682 
1684 {
1685 }
1686 
1688 {
1689 }
1690 
1692 {
1693  maData.clear();
1694 }
1695 
1696 
1697 void SortedEntryList::Insert( std::unique_ptr<SortListData> pEntry, sal_IntPtr nPos )
1698 {
1699  if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1700  maData.insert( maData.begin() + nPos, std::move(pEntry) );
1701  else
1702  maData.push_back( std::move(pEntry) );
1703 }
1704 
1705 void SortedEntryList::Move( sal_IntPtr nOldPos, sal_IntPtr nNewPos )
1706 {
1707  auto p = std::move(maData[nOldPos]);
1708  maData.erase( maData.begin() + nOldPos );
1709  maData.insert(maData.begin() + nNewPos, std::move(p));
1710 }
1711 
1712 std::unique_ptr<SortListData> SortedEntryList::Remove( sal_IntPtr nPos )
1713 {
1714  std::unique_ptr<SortListData> pData;
1715 
1716  if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1717  {
1718  pData = std::move(maData[ nPos ]);
1719  maData.erase( maData.begin() + nPos );
1720  }
1721 
1722  return pData;
1723 }
1724 
1725 
1727 {
1729 
1730  if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1731  pData = maData[ nPos ].get();
1732  else
1733  pData = nullptr;
1734 
1735  return pData;
1736 }
1737 
1738 
1739 sal_IntPtr SortedEntryList::operator [] ( sal_IntPtr nPos ) const
1740 {
1742 
1743  if ( nPos < static_cast<sal_IntPtr>(maData.size()) )
1744  pData = maData[ nPos ].get();
1745  else
1746  pData = nullptr;
1747 
1748  if ( pData )
1749  if ( ! pData->mbModified )
1750  return pData->mnCurPos;
1751  else
1752  {
1753  OSL_FAIL( "SortedEntryList: Can't get value for modified entry!");
1754  return 0;
1755  }
1756  else
1757  {
1758  OSL_FAIL( "SortedEntryList: invalid pos!");
1759  return 0;
1760  }
1761 }
1762 
1763 
1765 {
1766  maProps[0].Name = "RowCount";
1767  maProps[0].Handle = -1;
1769  maProps[0].Attributes = -1;
1770 
1771  maProps[1].Name = "IsRowCountFinal";
1772  maProps[1].Handle = -1;
1773  maProps[1].Type = cppu::UnoType<bool>::get();
1774  maProps[1].Attributes = -1;
1775 }
1776 
1777 // XPropertySetInfo methods.
1778 
1779 Sequence< Property > SAL_CALL
1781 {
1782  return Sequence < Property > ( maProps, 2 );
1783 }
1784 
1785 
1786 Property SAL_CALL
1788 {
1789  if ( Name == "RowCount" )
1790  return maProps[0];
1791  else if ( Name == "IsRowCountFinal" )
1792  return maProps[1];
1793  else
1794  throw UnknownPropertyException(Name);
1795 }
1796 
1797 
1798 sal_Bool SAL_CALL
1800 {
1801  if ( Name == "RowCount" )
1802  return true;
1803  else if ( Name == "IsRowCountFinal" )
1804  return true;
1805  else
1806  return false;
1807 }
1808 
1809 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sal_Bool SAL_CALL rowDeleted() override
Definition: sortresult.cxx:553
sal_Int32 nIndex
virtual sal_Int64 SAL_CALL getLong(sal_Int32 columnIndex) override
Definition: sortresult.cxx:623
void ResortModified(EventList *pList)
virtual sal_Bool SAL_CALL previous() override
moves the cursor to the previous row in the result set.
Definition: sortresult.cxx:493
virtual Sequence< Property > SAL_CALL getProperties() override
virtual css::uno::Reference< css::sdbc::XArray > SAL_CALL getArray(sal_Int32 columnIndex) override
Definition: sortresult.cxx:718
sal_IntPtr FindPos(SortListData const *pEntry, sal_IntPtr nStart, sal_IntPtr nEnd)
std::unique_ptr< ContentProperties > pData
virtual void SAL_CALL dispose() override
Definition: sortresult.cxx:164
void Insert(std::unique_ptr< css::ucb::ListAction > pAction)
Definition: sortresult.hxx:81
signed char sal_Int8
sal_IntPtr Compare(SortListData const *pOne, SortListData const *pTwo)
bool mbCaseSensitive
Definition: sortresult.cxx:60
#define RESULTSET_SERVICE_NAME
Definition: sortresult.hxx:87
virtual css::uno::Any SAL_CALL getObject(sal_Int32 columnIndex, const css::uno::Reference< css::container::XNameAccess > &typeMap) override
Definition: sortresult.cxx:688
SortListData * GetData(sal_IntPtr nPos)
virtual sal_Bool SAL_CALL hasPropertyByName(const OUString &Name) override
std::unique_ptr< SortListData > Remove(sal_IntPtr nPos)
void Remove(sal_IntPtr nPos, sal_IntPtr nCount, EventList *pList)
virtual sal_Int8 SAL_CALL getByte(sal_Int32 columnIndex) override
Definition: sortresult.cxx:603
virtual OUString SAL_CALL getImplementationName() override
Definition: sortresult.cxx:146
sal_Int32 mnType
Definition: sortresult.cxx:62
SortInfo * mpSortInfo
Definition: sortresult.hxx:108
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &Listener) override
Definition: sortresult.cxx:194
virtual void SAL_CALL afterLast() override
Definition: sortresult.cxx:312
virtual sal_Bool SAL_CALL isAfterLast() override
Definition: sortresult.cxx:277
virtual OUString SAL_CALL getString(sal_Int32 columnIndex) override
Definition: sortresult.cxx:589
sal_Int32 mnColumn
Definition: sortresult.cxx:61
virtual void SAL_CALL beforeFirst() override
Definition: sortresult.cxx:304
SortedEntryList maS2O
Definition: sortresult.hxx:110
virtual sal_Int32 SAL_CALL getRow() override
Definition: sortresult.cxx:356
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: sortresult.cxx:156
css::uno::XInterface *SAL_CALL next()
virtual css::util::DateTime SAL_CALL getTimestamp(sal_Int32 columnIndex) override
Definition: sortresult.cxx:665
virtual float SAL_CALL getFloat(sal_Int32 columnIndex) override
Definition: sortresult.cxx:630
static sal_IntPtr CompareImpl(const css::uno::Reference< css::sdbc::XResultSet > &xResultOne, const css::uno::Reference< css::sdbc::XResultSet > &xResultTwo, sal_IntPtr nIndexOne, sal_IntPtr nIndexTwo, SortInfo const *pSortInfo)
virtual void SAL_CALL refreshRow() override
Definition: sortresult.cxx:514
virtual void SAL_CALL addPropertyChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &Listener) override
Definition: sortresult.cxx:813
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: sortresult.cxx:749
virtual Property SAL_CALL getPropertyByName(const OUString &aName) override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getStatement() override
Definition: sortresult.cxx:566
sal_IntPtr mnOldPos
Definition: sortresult.cxx:72
virtual sal_Bool SAL_CALL next() override
Definition: sortresult.cxx:246
std::deque< std::unique_ptr< SortListData > > maData
Definition: sortresult.hxx:53
void Insert(std::unique_ptr< SortListData > pEntry, sal_IntPtr nPos)
virtual OUString SAL_CALL queryContentIdentifierString() override
Definition: sortresult.cxx:221
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
int nCount
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
void CopyData(SortedResultSet *pSource)
virtual css::uno::Reference< css::ucb::XContentIdentifier > SAL_CALL queryContentIdentifier() override
Definition: sortresult.cxx:229
virtual sal_Bool SAL_CALL isBeforeFirst() override
Definition: sortresult.cxx:268
SortListData(sal_IntPtr nPos)
SortInfo * mpNext
Definition: sortresult.cxx:63
void AddEvent(sal_IntPtr nType, sal_IntPtr nPos)
Definition: sortdynres.cxx:486
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBytes(sal_Int32 columnIndex) override
Definition: sortresult.cxx:644
Reference< XAnyCompare > mxCompareFunction
Definition: sortresult.cxx:64
::osl::Mutex maMutex
virtual css::util::Time SAL_CALL getTime(sal_Int32 columnIndex) override
Definition: sortresult.cxx:658
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
Definition: sortresult.cxx:852
void PropertyChanged(const css::beans::PropertyChangeEvent &rEvt)
virtual sal_Bool SAL_CALL wasNull() override
Definition: sortresult.cxx:582
static osl::Mutex & getContainerMutex()
Definition: sortresult.cxx:48
virtual sal_Int16 SAL_CALL getShort(sal_Int32 columnIndex) override
Definition: sortresult.cxx:610
int i
virtual sal_Bool SAL_CALL relative(sal_Int32 rows) override
moves the cursor a relative number of rows, either positive or negative.
Definition: sortresult.cxx:449
virtual css::uno::Reference< css::sdbc::XRef > SAL_CALL getRef(sal_Int32 columnIndex) override
Definition: sortresult.cxx:697
class SAL_NO_VTABLE XPropertySet
virtual sal_Bool SAL_CALL rowUpdated() override
Definition: sortresult.cxx:527
virtual sal_Bool SAL_CALL isLast() override
Definition: sortresult.cxx:295
virtual sal_Bool SAL_CALL getBoolean(sal_Int32 columnIndex) override
Definition: sortresult.cxx:596
sal_IntPtr operator[](sal_IntPtr nPos) const
virtual sal_Bool SAL_CALL isFirst() override
Definition: sortresult.cxx:286
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &Listener) override
Definition: sortresult.cxx:207
unsigned char sal_Bool
virtual sal_Bool SAL_CALL first() override
Definition: sortresult.cxx:320
css::uno::Type const & get()
std::size_t mnCount
std::deque< sal_IntPtr > m_O2S
Definition: sortresult.hxx:111
SortedResultSet(css::uno::Reference< css::sdbc::XResultSet > const &aResult)
Definition: sortresult.cxx:107
void CheckProperties(sal_IntPtr nOldCount, bool bWasFinal)
sal_IntPtr mnCurPos
Definition: sortresult.cxx:71
virtual css::uno::Reference< css::sdbc::XResultSetMetaData > SAL_CALL getMetaData() override
Definition: sortresult.cxx:738
void ResortNew(EventList *pList)
void Initialize(const css::uno::Sequence< css::ucb::NumberedSortingInfo > &xSortInfo, const css::uno::Reference< css::ucb::XAnyCompareFactory > &xCompFac)
virtual css::uno::Reference< css::sdbc::XClob > SAL_CALL getClob(sal_Int32 columnIndex) override
Definition: sortresult.cxx:711
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: sortresult.cxx:151
void SetChanged(sal_IntPtr nPos, sal_IntPtr nCount)
virtual sal_Bool SAL_CALL absolute(sal_Int32 row) override
moves the cursor to the given row number in the result set.
Definition: sortresult.cxx:387
bool mbAscending
Definition: sortresult.cxx:59
virtual ~SortedResultSet() override
Definition: sortresult.cxx:122
virtual void SAL_CALL removePropertyChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &Listener) override
Definition: sortresult.cxx:827
void Move(sal_IntPtr nOldPos, sal_IntPtr nNewPos)
virtual double SAL_CALL getDouble(sal_Int32 columnIndex) override
Definition: sortresult.cxx:637
OUString aName
bool mbUseOwnCompare
Definition: sortresult.cxx:58
virtual sal_Int32 SAL_CALL getInt(sal_Int32 columnIndex) override
Definition: sortresult.cxx:617
virtual sal_Bool SAL_CALL last() override
Definition: sortresult.cxx:338
virtual sal_Bool SAL_CALL rowInserted() override
Definition: sortresult.cxx:540
void * p
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
Definition: sortresult.cxx:775
void BuildSortInfo(const css::uno::Reference< css::sdbc::XResultSet > &aResult, const css::uno::Sequence< css::ucb::NumberedSortingInfo > &xSortInfo, const css::uno::Reference< css::ucb::XAnyCompareFactory > &xCompFac)
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent() override
Definition: sortresult.cxx:237
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getBinaryStream(sal_Int32 columnIndex) override
Definition: sortresult.cxx:673
virtual css::uno::Reference< css::sdbc::XBlob > SAL_CALL getBlob(sal_Int32 columnIndex) override
Definition: sortresult.cxx:704
void Move(sal_IntPtr nPos, sal_IntPtr nCount, sal_IntPtr nOffset)
void InsertNew(sal_IntPtr nPos, sal_IntPtr nCount)
sal_uInt32 Count() const
Definition: sortresult.hxx:59
virtual void SAL_CALL close() override
Definition: sortresult.cxx:728
virtual void SAL_CALL setPropertyValue(const OUString &PropertyName, const css::uno::Any &Value) override
Definition: sortresult.cxx:762
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &Listener) override
Definition: sortresult.cxx:838
virtual css::uno::Reference< css::io::XInputStream > SAL_CALL getCharacterStream(sal_Int32 columnIndex) override
Definition: sortresult.cxx:681
virtual css::util::Date SAL_CALL getDate(sal_Int32 columnIndex) override
Definition: sortresult.cxx:651
Property maProps[2]
Definition: sortresult.cxx:83
OMultiTypeInterfaceContainerHelperVar< OUString > PropertyChangeListenerContainer_Impl
Definition: sortresult.cxx:97
sal_uInt16 nPos
bool SAL_CALL hasMoreElements() const
css::uno::Reference< css::sdbc::XResultSet > mxOriginal
Definition: sortresult.hxx:104