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