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