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