1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sorter.hxx"
26
27 #include <vector>
28 #include <sortresult.hxx>
29 #include <cppuhelper/interfacecontainer.hxx>
30 #include <com/sun/star/sdbc/DataType.hpp>
31 #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
32 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
33 #include <com/sun/star/ucb/ListActionType.hpp>
34 #include <com/sun/star/ucb/XAnyCompare.hpp>
35 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
36 #include <osl/diagnose.h>
37
38 //-----------------------------------------------------------------------------
39 using namespace com::sun::star::beans;
40 using namespace com::sun::star::container;
41 using namespace com::sun::star::io;
42 using namespace com::sun::star::lang;
43 using namespace com::sun::star::sdbc;
44 using namespace com::sun::star::ucb;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::util;
47 using namespace cppu;
48 using namespace rtl;
49
50 //=========================================================================
51
52 // The mutex to synchronize access to containers.
getContainerMutex()53 static osl::Mutex& getContainerMutex()
54 {
55 static osl::Mutex* pMutex = NULL;
56 if( !pMutex )
57 {
58 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
59 if( !pMutex )
60 {
61 static osl::Mutex aMutex;
62 pMutex = &aMutex;
63 }
64 }
65
66 return *pMutex;
67 }
68
69 //==========================================================================
70
71 struct SortInfo
72 {
73 sal_Bool mbUseOwnCompare;
74 sal_Bool mbAscending;
75 sal_Bool mbCaseSensitive;
76 sal_Int32 mnColumn;
77 sal_Int32 mnType;
78 SortInfo* mpNext;
79 Reference < XAnyCompare > mxCompareFunction;
80 };
81
82 //-----------------------------------------------------------------------------
83
84 struct SortListData
85 {
86 sal_Bool mbModified;
87 long mnCurPos;
88 long mnOldPos;
89
90 SortListData( long nPos, sal_Bool bModified = sal_False );
91 };
92
93 //============================================================================
94 //
95 // class SRSPropertySetInfo.
96 //
97 //============================================================================
98
99 class SRSPropertySetInfo :
100 public OWeakObject,
101 public XTypeProvider,
102 public XPropertySetInfo
103 {
104 Property maProps[2];
105
106 private:
107
108 public:
109 SRSPropertySetInfo();
110 virtual ~SRSPropertySetInfo();
111
112 // XInterface
113 XINTERFACE_DECL()
114
115 // XTypeProvider
116 XTYPEPROVIDER_DECL()
117
118 // XPropertySetInfo
119 virtual Sequence< Property > SAL_CALL getProperties()
120 throw( RuntimeException );
121 virtual Property SAL_CALL getPropertyByName( const OUString& aName )
122 throw( UnknownPropertyException, RuntimeException );
123 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name )
124 throw( RuntimeException );
125 };
126
127 //=========================================================================
128 //
129 // PropertyChangeListenerContainer_Impl.
130 //
131 //=========================================================================
132
133 struct equalStr_Impl
134 {
operator ()equalStr_Impl135 bool operator()( const OUString& s1, const OUString& s2 ) const
136 {
137 return !!( s1 == s2 );
138 }
139 };
140
141 struct hashStr_Impl
142 {
operator ()hashStr_Impl143 size_t operator()( const OUString& rName ) const
144 {
145 return rName.hashCode();
146 }
147 };
148
149 typedef OMultiTypeInterfaceContainerHelperVar
150 <
151 OUString,
152 hashStr_Impl,
153 equalStr_Impl
154 > PropertyChangeListenerContainer_Impl;
155
156 //=========================================================================
157 //
158 // class PropertyChangeListeners_Impl
159 //
160 //=========================================================================
161
162 class PropertyChangeListeners_Impl : public PropertyChangeListenerContainer_Impl
163 {
164 public:
PropertyChangeListeners_Impl()165 PropertyChangeListeners_Impl()
166 : PropertyChangeListenerContainer_Impl( getContainerMutex() ) {}
167 };
168
169 //==========================================================================
SortedResultSet(Reference<XResultSet> aResult)170 SortedResultSet::SortedResultSet( Reference< XResultSet > aResult )
171 {
172 mpDisposeEventListeners = NULL;
173 mpPropChangeListeners = NULL;
174 mpVetoChangeListeners = NULL;
175 mpPropSetInfo = NULL;
176
177 mxOriginal = aResult;
178 mpSortInfo = NULL;
179 mnLastSort = 0;
180 mnCurEntry = 0;
181 mnCount = 0;
182 mbIsCopy = sal_False;
183 }
184
185 //--------------------------------------------------------------------------
~SortedResultSet()186 SortedResultSet::~SortedResultSet()
187 {
188 mxOriginal.clear();
189 mxOther.clear();
190
191 if ( !mbIsCopy )
192 {
193 SortInfo *pInfo = mpSortInfo;
194 while ( pInfo )
195 {
196 mpSortInfo = pInfo->mpNext;
197 delete pInfo;
198 pInfo = mpSortInfo;
199 }
200 }
201
202 mpSortInfo = NULL;
203
204 if ( mpPropSetInfo )
205 mpPropSetInfo->release();
206
207 delete mpPropChangeListeners;
208 delete mpVetoChangeListeners;
209 }
210
211 //--------------------------------------------------------------------------
212 // XInterface methods.
213 //--------------------------------------------------------------------------
214
215 XINTERFACE_IMPL_9( SortedResultSet,
216 XTypeProvider,
217 XServiceInfo,
218 XComponent,
219 XContentAccess,
220 XResultSet,
221 XRow,
222 XCloseable,
223 XResultSetMetaDataSupplier,
224 XPropertySet );
225
226 //--------------------------------------------------------------------------
227 // XTypeProvider methods.
228 //--------------------------------------------------------------------------
229
230 XTYPEPROVIDER_IMPL_9( SortedResultSet,
231 XTypeProvider,
232 XServiceInfo,
233 XComponent,
234 XContentAccess,
235 XResultSet,
236 XRow,
237 XCloseable,
238 XResultSetMetaDataSupplier,
239 XPropertySet );
240
241 //--------------------------------------------------------------------------
242 // XServiceInfo methods.
243 //--------------------------------------------------------------------------
244
245 XSERVICEINFO_NOFACTORY_IMPL_1( SortedResultSet,
246 OUString::createFromAscii(
247 "com.sun.star.comp.ucb.SortedResultSet" ),
248 OUString::createFromAscii(
249 RESULTSET_SERVICE_NAME ) );
250
251 //--------------------------------------------------------------------------
252 // XComponent methods.
253 //--------------------------------------------------------------------------
dispose()254 void SAL_CALL SortedResultSet::dispose()
255 throw( RuntimeException )
256 {
257 osl::Guard< osl::Mutex > aGuard( maMutex );
258
259 if ( mpDisposeEventListeners && mpDisposeEventListeners->getLength() )
260 {
261 EventObject aEvt;
262 aEvt.Source = static_cast< XComponent * >( this );
263 mpDisposeEventListeners->disposeAndClear( aEvt );
264 }
265
266 if ( mpPropChangeListeners )
267 {
268 EventObject aEvt;
269 aEvt.Source = static_cast< XPropertySet * >( this );
270 mpPropChangeListeners->disposeAndClear( aEvt );
271 }
272
273 if ( mpVetoChangeListeners )
274 {
275 EventObject aEvt;
276 aEvt.Source = static_cast< XPropertySet * >( this );
277 mpVetoChangeListeners->disposeAndClear( aEvt );
278 }
279
280 mxOriginal.clear();
281 mxOther.clear();
282 }
283
284 //--------------------------------------------------------------------------
addEventListener(const Reference<XEventListener> & Listener)285 void SAL_CALL SortedResultSet::addEventListener(
286 const Reference< XEventListener >& Listener )
287 throw( RuntimeException )
288 {
289 osl::Guard< osl::Mutex > aGuard( maMutex );
290
291 if ( !mpDisposeEventListeners )
292 mpDisposeEventListeners =
293 new OInterfaceContainerHelper( getContainerMutex() );
294
295 mpDisposeEventListeners->addInterface( Listener );
296 }
297
298 //--------------------------------------------------------------------------
removeEventListener(const Reference<XEventListener> & Listener)299 void SAL_CALL SortedResultSet::removeEventListener(
300 const Reference< XEventListener >& Listener )
301 throw( RuntimeException )
302 {
303 osl::Guard< osl::Mutex > aGuard( maMutex );
304
305 if ( mpDisposeEventListeners )
306 mpDisposeEventListeners->removeInterface( Listener );
307 }
308
309 //--------------------------------------------------------------------------
310 // XContentAccess methods.
311 //--------------------------------------------------------------------------
312
313 OUString SAL_CALL
queryContentIdentifierString()314 SortedResultSet::queryContentIdentifierString()
315 throw( RuntimeException )
316 {
317 osl::Guard< osl::Mutex > aGuard( maMutex );
318 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifierString();
319 }
320
321 //--------------------------------------------------------------------------
322 Reference< XContentIdentifier > SAL_CALL
queryContentIdentifier()323 SortedResultSet::queryContentIdentifier()
324 throw( RuntimeException )
325 {
326 osl::Guard< osl::Mutex > aGuard( maMutex );
327 return Reference< XContentAccess >::query(mxOriginal)->queryContentIdentifier();
328 }
329
330 //--------------------------------------------------------------------------
331 Reference< XContent > SAL_CALL
queryContent()332 SortedResultSet::queryContent()
333 throw( RuntimeException )
334 {
335 osl::Guard< osl::Mutex > aGuard( maMutex );
336 return Reference< XContentAccess >::query(mxOriginal)->queryContent();
337 }
338
339
340 //--------------------------------------------------------------------------
341 // XResultSet methods.
342 //--------------------------------------------------------------------------
next()343 sal_Bool SAL_CALL SortedResultSet::next()
344 throw ( SQLException, RuntimeException )
345 {
346 osl::Guard< osl::Mutex > aGuard( maMutex );
347
348 mnCurEntry++;
349
350 if ( mnCurEntry > 0 )
351 {
352 if ( mnCurEntry <= mnCount )
353 {
354 sal_Int32 nIndex = maS2O[ mnCurEntry ];
355 return mxOriginal->absolute( nIndex );
356 }
357 else
358 {
359 mnCurEntry = mnCount + 1;
360 }
361 }
362 return sal_False;
363 }
364
365 //-------------------------------------------------------------------------
isBeforeFirst()366 sal_Bool SAL_CALL SortedResultSet::isBeforeFirst()
367 throw ( SQLException, RuntimeException )
368 {
369 if ( mnCurEntry )
370 return sal_False;
371 else
372 return sal_True;
373 }
374
375 //-------------------------------------------------------------------------
isAfterLast()376 sal_Bool SAL_CALL SortedResultSet::isAfterLast()
377 throw ( SQLException, RuntimeException )
378 {
379 if ( mnCurEntry > mnCount )
380 return sal_True;
381 else
382 return sal_False;
383 }
384
385 //-------------------------------------------------------------------------
isFirst()386 sal_Bool SAL_CALL SortedResultSet::isFirst()
387 throw ( SQLException, RuntimeException )
388 {
389 if ( mnCurEntry == 1 )
390 return sal_True;
391 else
392 return sal_False;
393 }
394
395 //-------------------------------------------------------------------------
isLast()396 sal_Bool SAL_CALL SortedResultSet::isLast()
397 throw ( SQLException, RuntimeException )
398 {
399 if ( mnCurEntry == mnCount )
400 return sal_True;
401 else
402 return sal_False;
403 }
404
405 //-------------------------------------------------------------------------
beforeFirst()406 void SAL_CALL SortedResultSet::beforeFirst()
407 throw ( SQLException, RuntimeException )
408 {
409 osl::Guard< osl::Mutex > aGuard( maMutex );
410 mnCurEntry = 0;
411 mxOriginal->beforeFirst();
412 }
413
414 //-------------------------------------------------------------------------
afterLast()415 void SAL_CALL SortedResultSet::afterLast()
416 throw ( SQLException, RuntimeException )
417 {
418 osl::Guard< osl::Mutex > aGuard( maMutex );
419 mnCurEntry = mnCount+1;
420 mxOriginal->afterLast();
421 }
422
423 //-------------------------------------------------------------------------
first()424 sal_Bool SAL_CALL SortedResultSet::first()
425 throw ( SQLException, RuntimeException )
426 {
427 osl::Guard< osl::Mutex > aGuard( maMutex );
428
429 if ( mnCount )
430 {
431 mnCurEntry = 1;
432 sal_Int32 nIndex = maS2O[ mnCurEntry ];
433 return mxOriginal->absolute( nIndex );
434 }
435 else
436 {
437 mnCurEntry = 0;
438 return sal_False;
439 }
440 }
441
442 //-------------------------------------------------------------------------
last()443 sal_Bool SAL_CALL SortedResultSet::last()
444 throw ( SQLException, RuntimeException )
445 {
446 osl::Guard< osl::Mutex > aGuard( maMutex );
447
448 if ( mnCount )
449 {
450 mnCurEntry = mnCount;
451 sal_Int32 nIndex = maS2O[ mnCurEntry ];
452 return mxOriginal->absolute( nIndex );
453 }
454 else
455 {
456 mnCurEntry = 0;
457 return sal_False;
458 }
459 }
460
461 //-------------------------------------------------------------------------
getRow()462 sal_Int32 SAL_CALL SortedResultSet::getRow()
463 throw ( SQLException, RuntimeException )
464 {
465 return mnCurEntry;
466 }
467
468 //-------------------------------------------------------------------------
469 /**
470 moves the cursor to the given row number in the result set.
471 <p>If the row number is positive, the cursor moves to the given row
472 number with respect to the beginning of the result set. The first
473 row is row 1, the second is row 2, and so on.
474 <p>If the given row number is negative, the cursor moves to an
475 absolute row position with respect to the end of the result set.
476 For example, calling <code>moveToPosition(-1)</code> positions the
477 cursor on the last row, <code>moveToPosition(-2)</code> indicates the
478 next-to-last row, and so on.
479 <p>An attempt to position the cursor beyond the first/last row in the
480 result set leaves the cursor before/after the first/last row,
481 respectively.
482 <p>Note: Calling <code>moveToPosition(1)</code> is the same
483 as calling <code>moveToFirst()</code>. Calling
484 <code>moveToPosition(-1)</code> is the same as calling
485 <code>moveToLast()</code>.
486 @param row
487 is the number of rows to move. Could be negative.
488 @returns
489 <TRUE/> if the cursor is on a row; <FALSE/> otherwise
490 @throws SQLException
491 if a database access error occurs or if row is 0, or the result set
492 type is FORWARD_ONLY.
493 */
absolute(sal_Int32 row)494 sal_Bool SAL_CALL SortedResultSet::absolute( sal_Int32 row )
495 throw ( SQLException, RuntimeException )
496 {
497 osl::Guard< osl::Mutex > aGuard( maMutex );
498
499 sal_Int32 nIndex;
500
501 if ( row > 0 )
502 {
503 if ( row <= mnCount )
504 {
505 mnCurEntry = row;
506 nIndex = maS2O[ mnCurEntry ];
507 return mxOriginal->absolute( nIndex );
508 }
509 else
510 {
511 mnCurEntry = mnCount + 1;
512 return sal_False;
513 }
514 }
515 else if ( row == 0 )
516 {
517 throw SQLException();
518 }
519 else
520 {
521 if ( mnCount + row + 1 > 0 )
522 {
523 mnCurEntry = mnCount + row + 1;
524 nIndex = maS2O[ mnCurEntry ];
525 return mxOriginal->absolute( nIndex );
526 }
527 else
528 {
529 mnCurEntry = 0;
530 return sal_False;
531 }
532 }
533 }
534
535 //-------------------------------------------------------------------------
536 /**
537 moves the cursor a relative number of rows, either positive or negative.
538 <p>
539 Attempting to move beyond the first/last row in the result set positions
540 the cursor before/after the first/last row. Calling
541 <code>moveRelative(0)</code> is valid, but does not change the cursor
542 position.
543 <p>Note: Calling <code>moveRelative(1)</code> is different from calling
544 <code>moveNext()</code> because is makes sense to call
545 <code>moveNext()</code> when there is no current row, for example,
546 when the cursor is positioned before the first row or after the last
547 row of the result set.
548 @param rows
549 is the number of rows to move. Could be negative.
550 @returns
551 <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
552 the result set.
553 @throws SQLException
554 if a database access error occurs or if there is no
555 current row, or the result set type is FORWARD_ONLY.
556 */
relative(sal_Int32 rows)557 sal_Bool SAL_CALL SortedResultSet::relative( sal_Int32 rows )
558 throw ( SQLException, RuntimeException )
559 {
560 osl::Guard< osl::Mutex > aGuard( maMutex );
561
562 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
563 {
564 throw SQLException();
565 }
566
567 if ( rows == 0 )
568 return sal_True;
569
570 sal_Int32 nTmp = mnCurEntry + rows;
571
572 if ( nTmp <= 0 )
573 {
574 mnCurEntry = 0;
575 return sal_False;
576 }
577 else if ( nTmp > mnCount )
578 {
579 mnCurEntry = mnCount + 1;
580 return sal_False;
581 }
582 else
583 {
584 mnCurEntry = nTmp;
585 nTmp = maS2O[ mnCurEntry ];
586 return mxOriginal->absolute( nTmp );
587 }
588 }
589
590 //-------------------------------------------------------------------------
591 /**
592 moves the cursor to the previous row in the result set.
593 <p>Note: <code>previous()</code> is not the same as
594 <code>relative(-1)</code> because it makes sense to call
595 <code>previous()</code> when there is no current row.
596 @returns <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
597 the result set.
598 @throws SQLException
599 if a database access error occurs or the result set type
600 is FORWARD_ONLY.
601 */
previous()602 sal_Bool SAL_CALL SortedResultSet::previous()
603 throw ( SQLException, RuntimeException )
604 {
605 osl::Guard< osl::Mutex > aGuard( maMutex );
606
607 mnCurEntry -= 1;
608
609 if ( mnCurEntry > 0 )
610 {
611 if ( mnCurEntry <= mnCount )
612 {
613 sal_Int32 nIndex = maS2O[ mnCurEntry ];
614 return mxOriginal->absolute( nIndex );
615 }
616 }
617 else
618 mnCurEntry = 0;
619
620 return sal_False;
621 }
622
623 //-------------------------------------------------------------------------
refreshRow()624 void SAL_CALL SortedResultSet::refreshRow()
625 throw ( SQLException, RuntimeException )
626 {
627 osl::Guard< osl::Mutex > aGuard( maMutex );
628
629 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
630 {
631 throw SQLException();
632 }
633
634 mxOriginal->refreshRow();
635 }
636
637 //-------------------------------------------------------------------------
rowUpdated()638 sal_Bool SAL_CALL SortedResultSet::rowUpdated()
639 throw ( SQLException, RuntimeException )
640 {
641 osl::Guard< osl::Mutex > aGuard( maMutex );
642
643 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
644 {
645 throw SQLException();
646 }
647
648 return mxOriginal->rowUpdated();
649 }
650
651 //-------------------------------------------------------------------------
rowInserted()652 sal_Bool SAL_CALL SortedResultSet::rowInserted()
653 throw ( SQLException, RuntimeException )
654 {
655 osl::Guard< osl::Mutex > aGuard( maMutex );
656
657 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
658 {
659 throw SQLException();
660 }
661
662 return mxOriginal->rowInserted();
663 }
664
665 //-------------------------------------------------------------------------
rowDeleted()666 sal_Bool SAL_CALL SortedResultSet::rowDeleted()
667 throw ( SQLException, RuntimeException )
668 {
669 osl::Guard< osl::Mutex > aGuard( maMutex );
670
671 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
672 {
673 throw SQLException();
674 }
675
676 return mxOriginal->rowDeleted();
677 }
678
679 //-------------------------------------------------------------------------
getStatement()680 Reference< XInterface > SAL_CALL SortedResultSet::getStatement()
681 throw ( SQLException, RuntimeException )
682 {
683 osl::Guard< osl::Mutex > aGuard( maMutex );
684
685 if ( ( mnCurEntry <= 0 ) || ( mnCurEntry > mnCount ) )
686 {
687 throw SQLException();
688 }
689
690 return mxOriginal->getStatement();
691 }
692
693 //--------------------------------------------------------------------------
694 // XRow methods.
695 //--------------------------------------------------------------------------
696
wasNull()697 sal_Bool SAL_CALL SortedResultSet::wasNull()
698 throw( SQLException, RuntimeException )
699 {
700 osl::Guard< osl::Mutex > aGuard( maMutex );
701 return Reference< XRow >::query(mxOriginal)->wasNull();
702 }
703
704 //-------------------------------------------------------------------------
getString(sal_Int32 columnIndex)705 OUString SAL_CALL SortedResultSet::getString( sal_Int32 columnIndex )
706 throw( SQLException, RuntimeException )
707 {
708 osl::Guard< osl::Mutex > aGuard( maMutex );
709 return Reference< XRow >::query(mxOriginal)->getString( columnIndex );
710 }
711
712 //-------------------------------------------------------------------------
getBoolean(sal_Int32 columnIndex)713 sal_Bool SAL_CALL SortedResultSet::getBoolean( sal_Int32 columnIndex )
714 throw( SQLException, RuntimeException )
715 {
716 osl::Guard< osl::Mutex > aGuard( maMutex );
717 return Reference< XRow >::query(mxOriginal)->getBoolean( columnIndex );
718 }
719
720 //-------------------------------------------------------------------------
getByte(sal_Int32 columnIndex)721 sal_Int8 SAL_CALL SortedResultSet::getByte( sal_Int32 columnIndex )
722 throw( SQLException, RuntimeException )
723 {
724 osl::Guard< osl::Mutex > aGuard( maMutex );
725 return Reference< XRow >::query(mxOriginal)->getByte( columnIndex );
726 }
727
728 //-------------------------------------------------------------------------
getShort(sal_Int32 columnIndex)729 sal_Int16 SAL_CALL SortedResultSet::getShort( sal_Int32 columnIndex )
730 throw( SQLException, RuntimeException )
731 {
732 osl::Guard< osl::Mutex > aGuard( maMutex );
733 return Reference< XRow >::query(mxOriginal)->getShort( columnIndex );
734 }
735
736 //-------------------------------------------------------------------------
getInt(sal_Int32 columnIndex)737 sal_Int32 SAL_CALL SortedResultSet::getInt( sal_Int32 columnIndex )
738 throw( SQLException, RuntimeException )
739 {
740 osl::Guard< osl::Mutex > aGuard( maMutex );
741 return Reference< XRow >::query(mxOriginal)->getInt( columnIndex );
742 }
743 //-------------------------------------------------------------------------
getLong(sal_Int32 columnIndex)744 sal_Int64 SAL_CALL SortedResultSet::getLong( sal_Int32 columnIndex )
745 throw( SQLException, RuntimeException )
746 {
747 osl::Guard< osl::Mutex > aGuard( maMutex );
748 return Reference< XRow >::query(mxOriginal)->getLong( columnIndex );
749 }
750
751 //-------------------------------------------------------------------------
getFloat(sal_Int32 columnIndex)752 float SAL_CALL SortedResultSet::getFloat( sal_Int32 columnIndex )
753 throw( SQLException, RuntimeException )
754 {
755 osl::Guard< osl::Mutex > aGuard( maMutex );
756 return Reference< XRow >::query(mxOriginal)->getFloat( columnIndex );
757 }
758
759 //-------------------------------------------------------------------------
getDouble(sal_Int32 columnIndex)760 double SAL_CALL SortedResultSet::getDouble( sal_Int32 columnIndex )
761 throw( SQLException, RuntimeException )
762 {
763 osl::Guard< osl::Mutex > aGuard( maMutex );
764 return Reference< XRow >::query(mxOriginal)->getDouble( columnIndex );
765 }
766
767 //-------------------------------------------------------------------------
getBytes(sal_Int32 columnIndex)768 Sequence< sal_Int8 > SAL_CALL SortedResultSet::getBytes( sal_Int32 columnIndex )
769 throw( SQLException, RuntimeException )
770 {
771 osl::Guard< osl::Mutex > aGuard( maMutex );
772 return Reference< XRow >::query(mxOriginal)->getBytes( columnIndex );
773 }
774
775 //-------------------------------------------------------------------------
getDate(sal_Int32 columnIndex)776 Date SAL_CALL SortedResultSet::getDate( sal_Int32 columnIndex )
777 throw( SQLException, RuntimeException )
778 {
779 osl::Guard< osl::Mutex > aGuard( maMutex );
780 return Reference< XRow >::query(mxOriginal)->getDate( columnIndex );
781 }
782
783 //-------------------------------------------------------------------------
getTime(sal_Int32 columnIndex)784 Time SAL_CALL SortedResultSet::getTime( sal_Int32 columnIndex )
785 throw( SQLException, RuntimeException )
786 {
787 osl::Guard< osl::Mutex > aGuard( maMutex );
788 return Reference< XRow >::query(mxOriginal)->getTime( columnIndex );
789 }
790
791 //-------------------------------------------------------------------------
getTimestamp(sal_Int32 columnIndex)792 DateTime SAL_CALL SortedResultSet::getTimestamp( sal_Int32 columnIndex )
793 throw( SQLException, RuntimeException )
794 {
795 osl::Guard< osl::Mutex > aGuard( maMutex );
796 return Reference< XRow >::query(mxOriginal)->getTimestamp( columnIndex );
797 }
798
799 //-------------------------------------------------------------------------
800 Reference< XInputStream > SAL_CALL
getBinaryStream(sal_Int32 columnIndex)801 SortedResultSet::getBinaryStream( sal_Int32 columnIndex )
802 throw( SQLException, RuntimeException )
803 {
804 osl::Guard< osl::Mutex > aGuard( maMutex );
805 return Reference< XRow >::query(mxOriginal)->getBinaryStream( columnIndex );
806 }
807
808 //-------------------------------------------------------------------------
809 Reference< XInputStream > SAL_CALL
getCharacterStream(sal_Int32 columnIndex)810 SortedResultSet::getCharacterStream( sal_Int32 columnIndex )
811 throw( SQLException, RuntimeException )
812 {
813 osl::Guard< osl::Mutex > aGuard( maMutex );
814 return Reference< XRow >::query(mxOriginal)->getCharacterStream( columnIndex );
815 }
816
817 //-------------------------------------------------------------------------
getObject(sal_Int32 columnIndex,const Reference<XNameAccess> & typeMap)818 Any SAL_CALL SortedResultSet::getObject( sal_Int32 columnIndex,
819 const Reference< XNameAccess >& typeMap )
820 throw( SQLException, RuntimeException )
821 {
822 osl::Guard< osl::Mutex > aGuard( maMutex );
823 return Reference< XRow >::query(mxOriginal)->getObject( columnIndex,
824 typeMap);
825 }
826
827 //-------------------------------------------------------------------------
getRef(sal_Int32 columnIndex)828 Reference< XRef > SAL_CALL SortedResultSet::getRef( sal_Int32 columnIndex )
829 throw( SQLException, RuntimeException )
830 {
831 osl::Guard< osl::Mutex > aGuard( maMutex );
832 return Reference< XRow >::query(mxOriginal)->getRef( columnIndex );
833 }
834
835 //-------------------------------------------------------------------------
getBlob(sal_Int32 columnIndex)836 Reference< XBlob > SAL_CALL SortedResultSet::getBlob( sal_Int32 columnIndex )
837 throw( SQLException, RuntimeException )
838 {
839 osl::Guard< osl::Mutex > aGuard( maMutex );
840 return Reference< XRow >::query(mxOriginal)->getBlob( columnIndex );
841 }
842
843 //-------------------------------------------------------------------------
getClob(sal_Int32 columnIndex)844 Reference< XClob > SAL_CALL SortedResultSet::getClob( sal_Int32 columnIndex )
845 throw( SQLException, RuntimeException )
846 {
847 osl::Guard< osl::Mutex > aGuard( maMutex );
848 return Reference< XRow >::query(mxOriginal)->getClob( columnIndex );
849 }
850
851 //-------------------------------------------------------------------------
getArray(sal_Int32 columnIndex)852 Reference< XArray > SAL_CALL SortedResultSet::getArray( sal_Int32 columnIndex )
853 throw( SQLException, RuntimeException )
854 {
855 osl::Guard< osl::Mutex > aGuard( maMutex );
856 return Reference< XRow >::query(mxOriginal)->getArray( columnIndex );
857 }
858
859
860 //--------------------------------------------------------------------------
861 // XCloseable methods.
862 //--------------------------------------------------------------------------
863
close()864 void SAL_CALL SortedResultSet::close()
865 throw( SQLException, RuntimeException )
866 {
867 osl::Guard< osl::Mutex > aGuard( maMutex );
868 Reference< XCloseable >::query(mxOriginal)->close();
869 }
870
871 //--------------------------------------------------------------------------
872 // XResultSetMetaDataSupplier methods.
873 //--------------------------------------------------------------------------
874
getMetaData()875 Reference< XResultSetMetaData > SAL_CALL SortedResultSet::getMetaData()
876 throw( SQLException, RuntimeException )
877 {
878 osl::Guard< osl::Mutex > aGuard( maMutex );
879 return Reference< XResultSetMetaDataSupplier >::query(mxOriginal)->getMetaData();
880 }
881
882
883 //--------------------------------------------------------------------------
884 // XPropertySet methods.
885 //--------------------------------------------------------------------------
886
887 Reference< XPropertySetInfo > SAL_CALL
getPropertySetInfo()888 SortedResultSet::getPropertySetInfo() throw( RuntimeException )
889 {
890 osl::Guard< osl::Mutex > aGuard( maMutex );
891
892 if ( !mpPropSetInfo )
893 {
894 mpPropSetInfo = new SRSPropertySetInfo();
895 mpPropSetInfo->acquire();
896 }
897
898 return Reference< XPropertySetInfo >( mpPropSetInfo );
899 }
900
901 //--------------------------------------------------------------------------
setPropertyValue(const OUString & PropertyName,const Any &)902 void SAL_CALL SortedResultSet::setPropertyValue(
903 const OUString& PropertyName,
904 const Any& )
905 throw( UnknownPropertyException,
906 PropertyVetoException,
907 IllegalArgumentException,
908 WrappedTargetException,
909 RuntimeException )
910 {
911 osl::Guard< osl::Mutex > aGuard( maMutex );
912
913 if ( ( PropertyName.compareToAscii( "RowCount" ) == 0 ) ||
914 ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 ) )
915 throw IllegalArgumentException();
916 else
917 throw UnknownPropertyException();
918 }
919
920 //--------------------------------------------------------------------------
getPropertyValue(const OUString & PropertyName)921 Any SAL_CALL SortedResultSet::getPropertyValue( const OUString& PropertyName )
922 throw( UnknownPropertyException,
923 WrappedTargetException,
924 RuntimeException )
925 {
926 osl::Guard< osl::Mutex > aGuard( maMutex );
927
928 Any aRet;
929
930 if ( PropertyName.compareToAscii( "RowCount" ) == 0 )
931 {
932 aRet <<= maS2O.Count();
933 }
934 else if ( PropertyName.compareToAscii( "IsRowCountFinal" ) == 0 )
935 {
936 sal_uInt32 nOrgCount = 0;
937 sal_Bool bOrgFinal = false;
938 Any aOrgRet;
939
940 aRet <<= (sal_Bool) sal_False;
941
942 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
943 getPropertyValue( PropertyName );
944 aOrgRet >>= bOrgFinal;
945
946 if ( bOrgFinal )
947 {
948 aOrgRet = Reference< XPropertySet >::query(mxOriginal)->
949 getPropertyValue( OUString::createFromAscii( "RowCount" ) );
950 aOrgRet >>= nOrgCount;
951 if ( nOrgCount == maS2O.Count() )
952 aRet <<= (sal_Bool) sal_True;
953 }
954 }
955 else
956 throw UnknownPropertyException();
957
958 return aRet;
959 }
960
961 //--------------------------------------------------------------------------
addPropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & Listener)962 void SAL_CALL SortedResultSet::addPropertyChangeListener(
963 const OUString& PropertyName,
964 const Reference< XPropertyChangeListener >& Listener )
965 throw( UnknownPropertyException,
966 WrappedTargetException,
967 RuntimeException )
968 {
969 osl::Guard< osl::Mutex > aGuard( maMutex );
970
971 if ( !mpPropChangeListeners )
972 mpPropChangeListeners =
973 new PropertyChangeListeners_Impl();
974
975 mpPropChangeListeners->addInterface( PropertyName, Listener );
976 }
977
978 //--------------------------------------------------------------------------
removePropertyChangeListener(const OUString & PropertyName,const Reference<XPropertyChangeListener> & Listener)979 void SAL_CALL SortedResultSet::removePropertyChangeListener(
980 const OUString& PropertyName,
981 const Reference< XPropertyChangeListener >& Listener )
982 throw( UnknownPropertyException,
983 WrappedTargetException,
984 RuntimeException )
985 {
986 osl::Guard< osl::Mutex > aGuard( maMutex );
987
988 if ( mpPropChangeListeners )
989 mpPropChangeListeners->removeInterface( PropertyName, Listener );
990 }
991
992 //--------------------------------------------------------------------------
addVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & Listener)993 void SAL_CALL SortedResultSet::addVetoableChangeListener(
994 const OUString& PropertyName,
995 const Reference< XVetoableChangeListener >& Listener )
996 throw( UnknownPropertyException,
997 WrappedTargetException,
998 RuntimeException )
999 {
1000 osl::Guard< osl::Mutex > aGuard( maMutex );
1001
1002 if ( !mpVetoChangeListeners )
1003 mpVetoChangeListeners =
1004 new PropertyChangeListeners_Impl();
1005
1006 mpVetoChangeListeners->addInterface( PropertyName, Listener );
1007 }
1008
1009 //--------------------------------------------------------------------------
removeVetoableChangeListener(const OUString & PropertyName,const Reference<XVetoableChangeListener> & Listener)1010 void SAL_CALL SortedResultSet::removeVetoableChangeListener(
1011 const OUString& PropertyName,
1012 const Reference< XVetoableChangeListener >& Listener )
1013 throw( UnknownPropertyException,
1014 WrappedTargetException,
1015 RuntimeException )
1016 {
1017 osl::Guard< osl::Mutex > aGuard( maMutex );
1018
1019 if ( mpVetoChangeListeners )
1020 mpVetoChangeListeners->removeInterface( PropertyName, Listener );
1021 }
1022
1023 //--------------------------------------------------------------------------
1024 // private methods
1025 //--------------------------------------------------------------------------
CompareImpl(Reference<XResultSet> xResultOne,Reference<XResultSet> xResultTwo,long nIndexOne,long nIndexTwo,SortInfo * pSortInfo)1026 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1027 Reference < XResultSet > xResultTwo,
1028 long nIndexOne, long nIndexTwo,
1029 SortInfo* pSortInfo )
1030
1031 throw( SQLException, RuntimeException )
1032 {
1033 Reference < XRow > xRowOne = Reference< XRow >::query( xResultOne );
1034 Reference < XRow > xRowTwo = Reference< XRow >::query( xResultTwo );
1035
1036 long nCompare = 0;
1037 long nColumn = pSortInfo->mnColumn;
1038
1039 switch ( pSortInfo->mnType )
1040 {
1041 case DataType::BIT :
1042 case DataType::TINYINT :
1043 case DataType::SMALLINT :
1044 case DataType::INTEGER :
1045 {
1046 sal_Int32 aOne = 0;
1047 sal_Int32 aTwo = 0;
1048
1049 if ( xResultOne->absolute( nIndexOne ) )
1050 aOne = xRowOne->getInt( nColumn );
1051 if ( xResultTwo->absolute( nIndexTwo ) )
1052 aTwo = xRowTwo->getInt( nColumn );
1053
1054 if ( aOne < aTwo )
1055 nCompare = -1;
1056 else if ( aOne == aTwo )
1057 nCompare = 0;
1058 else
1059 nCompare = 1;
1060
1061 break;
1062 }
1063 case DataType::BIGINT :
1064 {
1065 sal_Int64 aOne = 0;
1066 sal_Int64 aTwo = 0;
1067
1068 if ( xResultOne->absolute( nIndexOne ) )
1069 aOne = xRowOne->getLong( nColumn );
1070 if ( xResultTwo->absolute( nIndexTwo ) )
1071 aTwo = xRowTwo->getLong( nColumn );
1072
1073 if ( aOne < aTwo )
1074 nCompare = -1;
1075 else if ( aOne == aTwo )
1076 nCompare = 0;
1077 else
1078 nCompare = 1;
1079
1080 break;
1081 }
1082 case DataType::CHAR :
1083 case DataType::VARCHAR :
1084 case DataType::LONGVARCHAR :
1085 {
1086 OUString aOne, aTwo;
1087
1088 if ( xResultOne->absolute( nIndexOne ) )
1089 aOne = xRowOne->getString( nColumn );
1090 if ( xResultTwo->absolute( nIndexTwo ) )
1091 aTwo = xRowTwo->getString( nColumn );
1092
1093 if ( ! pSortInfo->mbCaseSensitive )
1094 {
1095 aOne = aOne.toAsciiLowerCase();
1096 aTwo = aTwo.toAsciiLowerCase();
1097 }
1098
1099 nCompare = aOne.compareTo( aTwo );
1100 break;
1101 }
1102 case DataType::DATE :
1103 {
1104 Date aOne, aTwo;
1105 sal_Int32 nTmp;
1106
1107 if ( xResultOne->absolute( nIndexOne ) )
1108 aOne = xRowOne->getDate( nColumn );
1109 if ( xResultTwo->absolute( nIndexTwo ) )
1110 aTwo = xRowTwo->getDate( nColumn );
1111
1112 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1113 if ( !nTmp ) {
1114 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1115 if ( !nTmp )
1116 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1117 }
1118
1119 if ( nTmp < 0 )
1120 nCompare = -1;
1121 else if ( nTmp == 0 )
1122 nCompare = 0;
1123 else
1124 nCompare = 1;
1125
1126 break;
1127 }
1128 case DataType::TIME :
1129 {
1130 Time aOne, aTwo;
1131 sal_Int32 nTmp;
1132
1133 if ( xResultOne->absolute( nIndexOne ) )
1134 aOne = xRowOne->getTime( nColumn );
1135 if ( xResultTwo->absolute( nIndexTwo ) )
1136 aTwo = xRowTwo->getTime( nColumn );
1137
1138 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1139 if ( !nTmp ) {
1140 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1141 if ( !nTmp ) {
1142 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1143 if ( !nTmp )
1144 nTmp = (sal_Int32) aTwo.HundredthSeconds
1145 - (sal_Int32) aOne.HundredthSeconds;
1146 }}
1147
1148 if ( nTmp < 0 )
1149 nCompare = -1;
1150 else if ( nTmp == 0 )
1151 nCompare = 0;
1152 else
1153 nCompare = 1;
1154
1155 break;
1156 }
1157 case DataType::TIMESTAMP :
1158 {
1159 DateTime aOne, aTwo;
1160 sal_Int32 nTmp;
1161
1162 if ( xResultOne->absolute( nIndexOne ) )
1163 aOne = xRowOne->getTimestamp( nColumn );
1164 if ( xResultTwo->absolute( nIndexTwo ) )
1165 aTwo = xRowTwo->getTimestamp( nColumn );
1166
1167 nTmp = (sal_Int32) aTwo.Year - (sal_Int32) aOne.Year;
1168 if ( !nTmp ) {
1169 nTmp = (sal_Int32) aTwo.Month - (sal_Int32) aOne.Month;
1170 if ( !nTmp ) {
1171 nTmp = (sal_Int32) aTwo.Day - (sal_Int32) aOne.Day;
1172 if ( !nTmp ) {
1173 nTmp = (sal_Int32) aTwo.Hours - (sal_Int32) aOne.Hours;
1174 if ( !nTmp ) {
1175 nTmp = (sal_Int32) aTwo.Minutes - (sal_Int32) aOne.Minutes;
1176 if ( !nTmp ) {
1177 nTmp = (sal_Int32) aTwo.Seconds - (sal_Int32) aOne.Seconds;
1178 if ( !nTmp )
1179 nTmp = (sal_Int32) aTwo.HundredthSeconds
1180 - (sal_Int32) aOne.HundredthSeconds;
1181 }}}}}
1182
1183 if ( nTmp < 0 )
1184 nCompare = -1;
1185 else if ( nTmp == 0 )
1186 nCompare = 0;
1187 else
1188 nCompare = 1;
1189
1190 break;
1191 }
1192 case DataType::REAL :
1193 {
1194 float aOne = 0;
1195 float aTwo = 0;
1196
1197 if ( xResultOne->absolute( nIndexOne ) )
1198 aOne = xRowOne->getFloat( nColumn );
1199 if ( xResultTwo->absolute( nIndexTwo ) )
1200 aTwo = xRowTwo->getFloat( nColumn );
1201
1202 if ( aOne < aTwo )
1203 nCompare = -1;
1204 else if ( aOne == aTwo )
1205 nCompare = 0;
1206 else
1207 nCompare = 1;
1208
1209 break;
1210 }
1211 case DataType::FLOAT :
1212 case DataType::DOUBLE :
1213 {
1214 double aOne = 0;
1215 double aTwo = 0;
1216
1217 if ( xResultOne->absolute( nIndexOne ) )
1218 aOne = xRowOne->getDouble( nColumn );
1219 if ( xResultTwo->absolute( nIndexTwo ) )
1220 aTwo = xRowTwo->getDouble( nColumn );
1221
1222 if ( aOne < aTwo )
1223 nCompare = -1;
1224 else if ( aOne == aTwo )
1225 nCompare = 0;
1226 else
1227 nCompare = 1;
1228
1229 break;
1230 }
1231 default:
1232 {
1233 OSL_ENSURE( sal_False, "DataType not supported for compare!" );
1234 }
1235 }
1236
1237 return nCompare;
1238 }
1239
1240 //--------------------------------------------------------------------------
CompareImpl(Reference<XResultSet> xResultOne,Reference<XResultSet> xResultTwo,long nIndexOne,long nIndexTwo)1241 long SortedResultSet::CompareImpl( Reference < XResultSet > xResultOne,
1242 Reference < XResultSet > xResultTwo,
1243 long nIndexOne, long nIndexTwo )
1244 throw( SQLException, RuntimeException )
1245 {
1246 long nCompare = 0;
1247 SortInfo* pInfo = mpSortInfo;
1248
1249 while ( !nCompare && pInfo )
1250 {
1251 if ( pInfo->mbUseOwnCompare )
1252 {
1253 nCompare = CompareImpl( xResultOne, xResultTwo,
1254 nIndexOne, nIndexTwo, pInfo );
1255 }
1256 else
1257 {
1258 Any aOne, aTwo;
1259
1260 Reference < XRow > xRowOne =
1261 Reference< XRow >::query( xResultOne );
1262 Reference < XRow > xRowTwo =
1263 Reference< XRow >::query( xResultTwo );
1264
1265 if ( xResultOne->absolute( nIndexOne ) )
1266 aOne = xRowOne->getObject( pInfo->mnColumn, NULL );
1267 if ( xResultTwo->absolute( nIndexTwo ) )
1268 aTwo = xRowTwo->getObject( pInfo->mnColumn, NULL );
1269
1270 nCompare = pInfo->mxCompareFunction->compare( aOne, aTwo );
1271 }
1272
1273 if ( ! pInfo->mbAscending )
1274 nCompare = - nCompare;
1275
1276 pInfo = pInfo->mpNext;
1277 }
1278
1279 return nCompare;
1280 }
1281
1282 //--------------------------------------------------------------------------
Compare(SortListData * pOne,SortListData * pTwo)1283 long SortedResultSet::Compare( SortListData *pOne,
1284 SortListData *pTwo )
1285 throw( SQLException, RuntimeException )
1286 {
1287 long nIndexOne;
1288 long nIndexTwo;
1289
1290 Reference < XResultSet > xResultOne;
1291 Reference < XResultSet > xResultTwo;
1292
1293 if ( pOne->mbModified )
1294 {
1295 xResultOne = mxOther;
1296 nIndexOne = pOne->mnOldPos;
1297 }
1298 else
1299 {
1300 xResultOne = mxOriginal;
1301 nIndexOne = pOne->mnCurPos;
1302 }
1303
1304 if ( pTwo->mbModified )
1305 {
1306 xResultTwo = mxOther;
1307 nIndexTwo = pTwo->mnOldPos;
1308 }
1309 else
1310 {
1311 xResultTwo = mxOriginal;
1312 nIndexTwo = pTwo->mnCurPos;
1313 }
1314
1315 long nCompare;
1316 nCompare = CompareImpl( xResultOne, xResultTwo,
1317 nIndexOne, nIndexTwo );
1318 return nCompare;
1319 }
1320
1321 //--------------------------------------------------------------------------
FindPos(SortListData * pEntry,long _nStart,long _nEnd)1322 long SortedResultSet::FindPos( SortListData *pEntry,
1323 long _nStart, long _nEnd )
1324 throw( SQLException, RuntimeException )
1325 {
1326 if ( _nStart > _nEnd )
1327 return _nStart + 1;
1328
1329 long nStart = _nStart;
1330 long nEnd = _nEnd;
1331 long nMid = 0, nCompare = 0;
1332
1333 SortListData *pMid;
1334
1335 while ( nStart <= nEnd )
1336 {
1337 nMid = ( nEnd - nStart ) / 2 + nStart;
1338 pMid = maS2O.GetData( nMid );
1339 nCompare = Compare( pEntry, pMid );
1340
1341 if ( !nCompare )
1342 nCompare = ((long) pEntry ) - ( (long) pMid );
1343
1344 if ( nCompare < 0 ) // pEntry < pMid
1345 nEnd = nMid - 1;
1346 else
1347 nStart = nMid + 1;
1348 }
1349
1350 if ( nCompare < 0 ) // pEntry < pMid
1351 return nMid;
1352 else
1353 return nMid+1;
1354 }
1355
1356 //--------------------------------------------------------------------------
PropertyChanged(const PropertyChangeEvent & rEvt)1357 void SortedResultSet::PropertyChanged( const PropertyChangeEvent& rEvt )
1358 {
1359 osl::Guard< osl::Mutex > aGuard( maMutex );
1360
1361 if ( !mpPropChangeListeners )
1362 return;
1363
1364 // Notify listeners interested especially in the changed property.
1365 OInterfaceContainerHelper* pPropsContainer =
1366 mpPropChangeListeners->getContainer( rEvt.PropertyName );
1367 if ( pPropsContainer )
1368 {
1369 OInterfaceIteratorHelper aIter( *pPropsContainer );
1370 while ( aIter.hasMoreElements() )
1371 {
1372 Reference< XPropertyChangeListener > xListener(
1373 aIter.next(), UNO_QUERY );
1374 if ( xListener.is() )
1375 xListener->propertyChange( rEvt );
1376 }
1377 }
1378
1379 // Notify listeners interested in all properties.
1380 pPropsContainer = mpPropChangeListeners->getContainer( OUString() );
1381 if ( pPropsContainer )
1382 {
1383 OInterfaceIteratorHelper aIter( *pPropsContainer );
1384 while ( aIter.hasMoreElements() )
1385 {
1386 Reference< XPropertyChangeListener > xListener(
1387 aIter.next(), UNO_QUERY );
1388 if ( xListener.is() )
1389 xListener->propertyChange( rEvt );
1390 }
1391 }
1392 }
1393
1394 //-------------------------------------------------------------------------
1395
1396 //--------------------------------------------------------------------------
1397 // public methods
1398 //--------------------------------------------------------------------------
1399
CopyData(SortedResultSet * pSource)1400 void SortedResultSet::CopyData( SortedResultSet *pSource )
1401 {
1402 const SortedEntryList *pSrcS2O = pSource->GetS2OList();
1403 const SimpleList *pSrcO2S = pSource->GetO2SList();
1404
1405 long i, nCount;
1406
1407 maS2O.Clear();
1408 maO2S.Clear();
1409 maModList.Clear();
1410
1411 maS2O.Insert( NULL, 0 );
1412 maO2S.Insert( 0, (sal_uInt32) 0 ); // value, pos
1413
1414 nCount = pSrcS2O->Count();
1415
1416 for ( i=1; i<nCount; i++ )
1417 {
1418 maS2O.Insert( new SortListData( (*pSrcS2O)[ i ] ), i );
1419 maO2S.Insert( pSrcO2S->GetObject( i ), (sal_uInt32) i );
1420 }
1421
1422 mnLastSort = maS2O.Count();
1423 mxOther = pSource->GetResultSet();
1424
1425 if ( !mpSortInfo )
1426 {
1427 mpSortInfo = pSource->GetSortInfo();
1428 mbIsCopy = sal_True;
1429 }
1430 }
1431
1432 //--------------------------------------------------------------------------
Initialize(const Sequence<NumberedSortingInfo> & xSortInfo,const Reference<XAnyCompareFactory> & xCompFactory)1433 void SortedResultSet::Initialize(
1434 const Sequence < NumberedSortingInfo > &xSortInfo,
1435 const Reference< XAnyCompareFactory > &xCompFactory )
1436 {
1437 BuildSortInfo( mxOriginal, xSortInfo, xCompFactory );
1438 // Insert dummy at pos 0
1439 SortListData *pData = new SortListData( 0 );
1440 maS2O.Insert( pData, 0 );
1441
1442 long nIndex = 1;
1443
1444 // now fetch all the elements from the original result set,
1445 // get there new position in the sorted result set and insert
1446 // an entry in the sorted to original mapping list
1447 try {
1448 while ( mxOriginal->absolute( nIndex ) )
1449 {
1450 pData = new SortListData( nIndex );
1451 long nPos = FindPos( pData, 1, nIndex-1 );
1452
1453 maS2O.Insert( pData, nPos );
1454
1455 nIndex++;
1456 }
1457 }
1458 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::Initialize() : Got unexpected SQLException" ); }
1459
1460 // when we have fetched all the elements, we can create the
1461 // original to sorted mapping list from the s2o list
1462 maO2S.Clear();
1463 maO2S.Insert( NULL, (sal_uInt32) 0 );
1464
1465 // insert some dummy entries first and replace then
1466 // the entries with the right ones
1467 sal_uInt32 i;
1468
1469 for ( i=1; i<maS2O.Count(); i++ )
1470 maO2S.Insert( (void*) 0, i ); // Insert( data, pos )
1471 for ( i=1; i<maS2O.Count(); i++ )
1472 maO2S.Replace( (void*) i, maS2O[ i ] ); // Insert( data, pos )
1473
1474 mnCount = maS2O.Count() - 1;
1475 }
1476
1477 //--------------------------------------------------------------------------
CheckProperties(long nOldCount,sal_Bool bWasFinal)1478 void SortedResultSet::CheckProperties( long nOldCount, sal_Bool bWasFinal )
1479 {
1480 osl::Guard< osl::Mutex > aGuard( maMutex );
1481
1482 if ( !mpPropChangeListeners )
1483 return;
1484
1485 try {
1486 // check for propertyChangeEvents
1487 if ( nOldCount != GetCount() )
1488 {
1489 sal_Bool bIsFinal = sal_False;
1490 PropertyChangeEvent aEvt;
1491
1492 aEvt.PropertyName = OUString::createFromAscii( "RowCount" );
1493 aEvt.Further = sal_False;
1494 aEvt.PropertyHandle = -1;
1495 aEvt.OldValue <<= nOldCount;
1496 aEvt.NewValue <<= GetCount();
1497
1498 PropertyChanged( aEvt );
1499
1500 OUString aName = OUString::createFromAscii( "IsRowCountFinal" );
1501 Any aRet = getPropertyValue( aName );
1502 if ( (aRet >>= bIsFinal) && bIsFinal != bWasFinal )
1503 {
1504 aEvt.PropertyName = aName;
1505 aEvt.Further = sal_False;
1506 aEvt.PropertyHandle = -1;
1507 aEvt.OldValue <<= (sal_Bool) bWasFinal;
1508 aEvt.NewValue <<= (sal_Bool) bIsFinal;
1509 PropertyChanged( aEvt );
1510 }
1511 }
1512 }
1513 catch ( UnknownPropertyException ) {}
1514 catch ( WrappedTargetException ) {}
1515 }
1516
1517 //-------------------------------------------------------------------------
InsertNew(long nPos,long nCount)1518 void SortedResultSet::InsertNew( long nPos, long nCount )
1519 {
1520 // in der maS2O Liste alle Eintr�ge, die >= nPos sind, um nCount
1521 // erh�hen
1522 SortListData *pData;
1523 long i, nEnd;
1524
1525 nEnd = maS2O.Count();
1526 for ( i=1; i<=nEnd; i++ )
1527 {
1528 pData = maS2O.GetData( i );
1529 if ( pData->mnCurPos >= nPos )
1530 {
1531 pData->mnCurPos += nCount;
1532 }
1533 }
1534
1535 // und die neuen eintr�ge hinten an die maS2O Liste anh�ngen bzw
1536 // an der Position nPos in der maO2S Liste einf�gen
1537 for ( i=0; i<nCount; i++ )
1538 {
1539 nEnd += 1;
1540 pData = new SortListData( nEnd );
1541
1542 maS2O.Insert( pData, nEnd ); // Insert( Wert, Position )
1543 maO2S.Insert( (void*)nEnd, (sal_uInt32)(nPos+i) ); // Insert( Wert, Position )
1544 }
1545
1546 mnCount += nCount;
1547 }
1548
1549 //-------------------------------------------------------------------------
Remove(long nPos,long nCount,EventList * pEvents)1550 void SortedResultSet::Remove( long nPos, long nCount, EventList *pEvents )
1551 {
1552 sal_uInt32 i, j;
1553 long nOldLastSort;
1554
1555 // correct mnLastSort first
1556 nOldLastSort = mnLastSort;
1557 if ( nPos <= mnLastSort )
1558 {
1559 if ( nPos + nCount - 1 <= mnLastSort )
1560 mnLastSort -= nCount;
1561 else
1562 mnLastSort = nPos - 1;
1563 }
1564
1565 // remove the entries from the lists and correct the positions
1566 // in the original2sorted list
1567 for ( i=0; i < (sal_uInt32) nCount; i++ )
1568 {
1569 long nSortPos = (long) maO2S.GetObject( nPos );
1570 maO2S.Remove( (sal_uInt32) nPos );
1571
1572 for ( j=1; j<=maO2S.Count(); j++ )
1573 {
1574 long nVal = (long) maO2S.GetObject( j );
1575 if ( nVal > nSortPos )
1576 {
1577 --nVal;
1578 maO2S.Replace( (void*) nVal, j );
1579 }
1580 }
1581
1582 SortListData *pData = maS2O.Remove( nSortPos );
1583 if ( pData->mbModified )
1584 maModList.Remove( (void*) pData );
1585 delete pData;
1586
1587 // generate remove Event, but not for new entries
1588 if ( nSortPos <= nOldLastSort )
1589 pEvents->AddEvent( ListActionType::REMOVED, nSortPos, 1 );
1590 }
1591
1592 // correct the positions in the sorted list
1593 for ( i=1; i<= maS2O.Count(); i++ )
1594 {
1595 SortListData *pData = maS2O.GetData( i );
1596 if ( pData->mnCurPos > nPos )
1597 pData->mnCurPos -= nCount;
1598 }
1599
1600 mnCount -= nCount;
1601 }
1602
1603 //-------------------------------------------------------------------------
Move(long nPos,long nCount,long nOffset)1604 void SortedResultSet::Move( long nPos, long nCount, long nOffset )
1605 {
1606 if ( !nOffset )
1607 return;
1608
1609 long i, nSortPos, nTo;
1610 SortListData *pData;
1611
1612 for ( i=0; i<nCount; i++ )
1613 {
1614 nSortPos = (long) maO2S.GetObject( nPos+i );
1615 pData = maS2O.GetData( nSortPos );
1616 pData->mnCurPos += nOffset;
1617 }
1618
1619 if ( nOffset < 0 )
1620 {
1621 for ( i=nPos+nOffset; i<nPos; i++ )
1622 {
1623 nSortPos = (long) maO2S.GetObject( i );
1624 pData = maS2O.GetData( nSortPos );
1625 pData->mnCurPos += nCount;
1626 }
1627 }
1628 else
1629 {
1630 long nStart = nPos + nCount;
1631 long nEnd = nStart + nOffset;
1632 for ( i=nStart; i<nEnd; i++ )
1633 {
1634 nSortPos = (long) maO2S.GetObject( i );
1635 pData = maS2O.GetData( nSortPos );
1636 pData->mnCurPos -= nCount;
1637 }
1638 }
1639
1640 // remember the to be moved entries
1641 long *pTmpArr = new long[ nCount ];
1642 for ( i=0; i<nCount; i++ )
1643 pTmpArr[i] = (long)maO2S.GetObject( (sal_uInt32)( nPos+i ) );
1644
1645 // now move the entries, which are in the way
1646 if ( nOffset < 0 )
1647 {
1648 // be carefully here, because nOffset is negative here, so an
1649 // addition is a subtraction
1650 long nFrom = nPos - 1;
1651 nTo = nPos + nCount - 1;
1652
1653 // same for i here
1654 for ( i=0; i>nOffset; i-- )
1655 {
1656 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nFrom+i ) );
1657 maO2S.Replace( (void*) nVal, (sal_uInt32)( nTo+i ) );
1658 }
1659
1660 }
1661 else
1662 {
1663 long nStart = nPos + nCount;
1664 for ( i=0; i<nOffset; i++ )
1665 {
1666 long nVal = (long) maO2S.GetObject( (sal_uInt32)( nStart+i ) );
1667 maO2S.Replace( (void*) nVal, (sal_uInt32)( nPos+i ) );
1668 }
1669 }
1670
1671 // finally put the remembered entries at there new location
1672 nTo = nPos + nOffset;
1673 for ( i=0; i<nCount; i++ )
1674 {
1675 maO2S.Replace( (void*)pTmpArr[ i ], (sal_uInt32)( nTo+i ) );
1676 }
1677
1678 delete [] pTmpArr;
1679 }
1680
1681 //--------------------------------------------------------------------------
BuildSortInfo(Reference<XResultSet> aResult,const Sequence<NumberedSortingInfo> & xSortInfo,const Reference<XAnyCompareFactory> & xCompFactory)1682 void SortedResultSet::BuildSortInfo(
1683 Reference< XResultSet > aResult,
1684 const Sequence < NumberedSortingInfo > &xSortInfo,
1685 const Reference< XAnyCompareFactory > &xCompFactory )
1686 {
1687 Reference < XResultSetMetaDataSupplier > xMeta ( aResult, UNO_QUERY );
1688
1689 if ( ! xMeta.is() )
1690 {
1691 OSL_ENSURE( sal_False, "No MetaData, No Sorting!" );
1692 return;
1693 }
1694
1695 Reference < XResultSetMetaData > xData = xMeta->getMetaData();
1696 const NumberedSortingInfo *pSortInfo = xSortInfo.getConstArray();
1697
1698 sal_Int32 nColumn;
1699 OUString aPropName;
1700 SortInfo *pInfo;
1701
1702 for ( long i=xSortInfo.getLength(); i > 0; )
1703 {
1704 --i;
1705 nColumn = pSortInfo[ i ].ColumnIndex;
1706 aPropName = xData->getColumnName( nColumn );
1707 pInfo = new SortInfo;
1708
1709 if ( xCompFactory.is() )
1710 pInfo->mxCompareFunction = xCompFactory->createAnyCompareByName(
1711 aPropName );
1712
1713 if ( pInfo->mxCompareFunction.is() )
1714 {
1715 pInfo->mbUseOwnCompare = sal_False;
1716 pInfo->mnType = 0;
1717 }
1718 else
1719 {
1720 pInfo->mbUseOwnCompare = sal_True;
1721 pInfo->mnType = xData->getColumnType( nColumn );
1722 }
1723
1724 pInfo->mnColumn = nColumn;
1725 pInfo->mbAscending = pSortInfo[ i ].Ascending;
1726 pInfo->mbCaseSensitive = xData->isCaseSensitive( nColumn );
1727 pInfo->mpNext = mpSortInfo;
1728 mpSortInfo = pInfo;
1729 }
1730 }
1731
1732 //-------------------------------------------------------------------------
SetChanged(long nPos,long nCount)1733 void SortedResultSet::SetChanged( long nPos, long nCount )
1734 {
1735 for ( long i=0; i<nCount; i++ )
1736 {
1737 long nSortPos = (long) maO2S.GetObject( nPos );
1738 if ( nSortPos < mnLastSort )
1739 {
1740 SortListData *pData = maS2O.GetData( nSortPos );
1741 if ( ! pData->mbModified )
1742 {
1743 pData->mbModified = sal_True;
1744 maModList.Append( pData );
1745 }
1746 }
1747 nPos += 1;
1748 }
1749 }
1750
1751 //-------------------------------------------------------------------------
ResortModified(EventList * pList)1752 void SortedResultSet::ResortModified( EventList* pList )
1753 {
1754 sal_uInt32 i, j;
1755 long nCompare, nCurPos, nNewPos;
1756 long nStart, nEnd, nOffset, nVal;
1757 SortListData *pData;
1758 ListAction *pAction;
1759
1760 try {
1761 for ( i=0; i<maModList.Count(); i++ )
1762 {
1763 pData = (SortListData*) maModList.GetObject( i );
1764 nCompare = CompareImpl( mxOther, mxOriginal,
1765 pData->mnOldPos, pData->mnCurPos );
1766 pData->mbModified = sal_False;
1767 if ( nCompare != 0 )
1768 {
1769 nCurPos = (long) maO2S.GetObject( (sal_uInt32) pData->mnCurPos );
1770 if ( nCompare < 0 )
1771 {
1772 nNewPos = FindPos( pData, 1, nCurPos-1 );
1773 nStart = nNewPos;
1774 nEnd = nCurPos;
1775 nOffset = 1;
1776 }
1777 else
1778 {
1779 nNewPos = FindPos( pData, nCurPos+1, mnLastSort );
1780 nStart = nCurPos;
1781 nEnd = mnLastSort;
1782 nOffset = -1;
1783 }
1784
1785 if ( nNewPos != nCurPos )
1786 {
1787 // correct the lists!
1788 maS2O.Remove( (sal_uInt32) nCurPos );
1789 maS2O.Insert( pData, nNewPos );
1790 for ( j=1; j<maO2S.Count(); j++ )
1791 {
1792 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1793 if ( ( nStart <= nVal ) && ( nVal <= nEnd ) )
1794 {
1795 nVal += nOffset;
1796 maO2S.Replace( (void*) (nVal), (sal_uInt32)( j ) );
1797 }
1798 }
1799
1800 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1801
1802 pAction = new ListAction;
1803 pAction->Position = nCurPos;
1804 pAction->Count = 1;
1805 pAction->ListActionType = ListActionType::MOVED;
1806 pAction->ActionInfo <<= nNewPos-nCurPos;
1807 pList->Insert( pAction );
1808 }
1809 pList->AddEvent( ListActionType::PROPERTIES_CHANGED,
1810 nNewPos, 1 );
1811 }
1812 }
1813 }
1814 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortModified() : Got unexpected SQLException" ); }
1815
1816 maModList.Clear();
1817 }
1818
1819 //-------------------------------------------------------------------------
ResortNew(EventList * pList)1820 void SortedResultSet::ResortNew( EventList* pList )
1821 {
1822 long i, j, nNewPos, nVal;
1823 SortListData *pData;
1824
1825 try {
1826 for ( i = mnLastSort; i<(long)maS2O.Count(); i++ )
1827 {
1828 pData = (SortListData*) maModList.GetObject( i );
1829 nNewPos = FindPos( pData, 1, mnLastSort );
1830 if ( nNewPos != i )
1831 {
1832 maS2O.Remove( (sal_uInt32) i );
1833 maS2O.Insert( pData, nNewPos );
1834 // maO2S liste korigieren
1835 for ( j=1; j<(long)maO2S.Count(); j++ )
1836 {
1837 nVal = (long) maO2S.GetObject( (sal_uInt32)( j ) );
1838 if ( nVal >= nNewPos )
1839 maO2S.Replace( (void*) (nVal+1), (sal_uInt32)( j ) );
1840 }
1841 maO2S.Replace( (void*) nNewPos, (sal_uInt32) pData->mnCurPos );
1842 }
1843 mnLastSort++;
1844 pList->AddEvent( ListActionType::INSERTED, nNewPos, 1 );
1845 }
1846 }
1847 catch ( SQLException ) { OSL_ENSURE( sal_False, "SortedResultSet::ResortNew() : Got unexpected SQLException" ); }
1848 }
1849
1850 //-------------------------------------------------------------------------
1851 //
1852 // SortListData
1853 //
1854 //-------------------------------------------------------------------------
SortListData(long nPos,sal_Bool bModified)1855 SortListData::SortListData( long nPos, sal_Bool bModified )
1856 {
1857 mbModified = bModified;
1858 mnCurPos = nPos;
1859 mnOldPos = nPos;
1860 };
1861
1862
1863 //=========================================================================
Clear()1864 void SortedEntryList::Clear()
1865 {
1866 for ( std::deque< LISTACTION* >::size_type i = 0;
1867 i < maData.size(); ++i )
1868 {
1869 delete maData[i];
1870 }
1871
1872 maData.clear();
1873 }
1874
1875 //-------------------------------------------------------------------------
Insert(SortListData * pEntry,long nPos)1876 void SortedEntryList::Insert( SortListData *pEntry, long nPos )
1877 {
1878 if ( nPos < (long) maData.size() )
1879 maData.insert( maData.begin() + nPos, pEntry );
1880 else
1881 maData.push_back( pEntry );
1882 }
1883
1884 //-------------------------------------------------------------------------
Remove(long nPos)1885 SortListData* SortedEntryList::Remove( long nPos )
1886 {
1887 SortListData *pData;
1888
1889 if ( nPos < (long) maData.size() )
1890 {
1891 pData = maData[ nPos ];
1892 maData.erase( maData.begin() + nPos );
1893 }
1894 else
1895 pData = NULL;
1896
1897 return pData;
1898 }
1899
1900 //-------------------------------------------------------------------------
GetData(long nPos)1901 SortListData* SortedEntryList::GetData( long nPos )
1902 {
1903 SortListData *pData;
1904
1905 if ( nPos < (long) maData.size() )
1906 pData = maData[ nPos ];
1907 else
1908 pData = NULL;
1909
1910 return pData;
1911 }
1912
1913 //-------------------------------------------------------------------------
operator [](long nPos) const1914 long SortedEntryList::operator [] ( long nPos ) const
1915 {
1916 SortListData *pData;
1917
1918 if ( nPos < (long) maData.size() )
1919 pData = maData[ nPos ];
1920 else
1921 pData = NULL;
1922
1923 if ( pData )
1924 if ( ! pData->mbModified )
1925 return pData->mnCurPos;
1926 else
1927 {
1928 OSL_ENSURE( sal_False, "SortedEntryList: Can't get value for modified entry!");
1929 return 0;
1930 }
1931 else
1932 {
1933 OSL_ENSURE( sal_False, "SortedEntryList: invalid pos!");
1934 return 0;
1935 }
1936 }
1937
1938 //-------------------------------------------------------------------------
1939 //-------------------------------------------------------------------------
1940 //-------------------------------------------------------------------------
Remove(sal_uInt32 nPos)1941 void SimpleList::Remove( sal_uInt32 nPos )
1942 {
1943 if ( nPos < (sal_uInt32) maData.size() )
1944 {
1945 maData.erase( maData.begin() + nPos );
1946 }
1947 }
1948
1949 //-------------------------------------------------------------------------
Remove(void * pData)1950 void SimpleList::Remove( void* pData )
1951 {
1952 sal_Bool bFound = sal_False;
1953 sal_uInt32 i;
1954
1955 for ( i = 0; i < (sal_uInt32) maData.size(); i++ )
1956 {
1957 if ( maData[ i ] == pData )
1958 {
1959 bFound = sal_True;
1960 break;
1961 }
1962 }
1963
1964 if ( bFound )
1965 maData.erase( maData.begin() + i );
1966 }
1967
1968 //-------------------------------------------------------------------------
Insert(void * pData,sal_uInt32 nPos)1969 void SimpleList::Insert( void* pData, sal_uInt32 nPos )
1970 {
1971 if ( nPos < (sal_uInt32) maData.size() )
1972 maData.insert( maData.begin() + nPos, pData );
1973 else
1974 maData.push_back( pData );
1975 }
1976
1977 //-------------------------------------------------------------------------
GetObject(sal_uInt32 nPos) const1978 void* SimpleList::GetObject( sal_uInt32 nPos ) const
1979 {
1980 if ( nPos < (sal_uInt32) maData.size() )
1981 return maData[ nPos ];
1982 else
1983 return NULL;
1984 }
1985
1986 //-------------------------------------------------------------------------
Replace(void * pData,sal_uInt32 nPos)1987 void SimpleList::Replace( void* pData, sal_uInt32 nPos )
1988 {
1989 if ( nPos < (sal_uInt32) maData.size() )
1990 maData[ nPos ] = pData;
1991 }
1992
1993 //-------------------------------------------------------------------------
1994 //
1995 // class SRSPropertySetInfo.
1996 //
1997 //-------------------------------------------------------------------------
1998
SRSPropertySetInfo()1999 SRSPropertySetInfo::SRSPropertySetInfo()
2000 {
2001 maProps[0].Name = OUString::createFromAscii( "RowCount" );
2002 maProps[0].Handle = -1;
2003 maProps[0].Type = ::getCppuType( (const OUString*) NULL );
2004 maProps[0].Attributes = -1;
2005
2006 maProps[1].Name = OUString::createFromAscii( "IsRowCountFinal" );
2007 maProps[1].Handle = -1;
2008 maProps[1].Type = ::getBooleanCppuType();
2009 maProps[1].Attributes = -1;
2010 }
2011
2012 //-------------------------------------------------------------------------
~SRSPropertySetInfo()2013 SRSPropertySetInfo::~SRSPropertySetInfo()
2014 {}
2015
2016 //-------------------------------------------------------------------------
2017 // XInterface methods.
2018 //-------------------------------------------------------------------------
2019
2020 XINTERFACE_IMPL_2( SRSPropertySetInfo,
2021 XTypeProvider,
2022 XPropertySetInfo );
2023
2024 //-------------------------------------------------------------------------
2025 // XTypeProvider methods.
2026 //-------------------------------------------------------------------------
2027
2028 XTYPEPROVIDER_IMPL_2( SRSPropertySetInfo,
2029 XTypeProvider,
2030 XPropertySetInfo );
2031
2032 //-------------------------------------------------------------------------
2033 // XPropertySetInfo methods.
2034 //-------------------------------------------------------------------------
2035 Sequence< Property > SAL_CALL
getProperties()2036 SRSPropertySetInfo::getProperties() throw( RuntimeException )
2037 {
2038 return Sequence < Property > ( maProps, 2 );
2039 }
2040
2041 //-------------------------------------------------------------------------
2042 Property SAL_CALL
getPropertyByName(const OUString & Name)2043 SRSPropertySetInfo::getPropertyByName( const OUString& Name )
2044 throw( UnknownPropertyException, RuntimeException )
2045 {
2046 if ( Name.compareToAscii( "RowCount" ) == 0 )
2047 return maProps[0];
2048 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2049 return maProps[1];
2050 else
2051 throw UnknownPropertyException();
2052 }
2053
2054 //-------------------------------------------------------------------------
2055 sal_Bool SAL_CALL
hasPropertyByName(const OUString & Name)2056 SRSPropertySetInfo::hasPropertyByName( const OUString& Name )
2057 throw( RuntimeException )
2058 {
2059 if ( Name.compareToAscii( "RowCount" ) == 0 )
2060 return sal_True;
2061 else if ( Name.compareToAscii( "IsRowCountFinal" ) == 0 )
2062 return sal_True;
2063 else
2064 return sal_False;
2065 }
2066
2067