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