nss: upgrade to release 3.73
[LibreOffice.git] / ucbhelper / source / provider / resultset.cxx
blob6d6fd5ee09b3956d6b29af81693bd8d65000c0c9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 /**************************************************************************
22 TODO
23 **************************************************************************
25 *************************************************************************/
26 #include <memory>
27 #include <cppuhelper/interfacecontainer.hxx>
28 #include <cppuhelper/queryinterface.hxx>
29 #include <com/sun/star/beans/PropertyAttribute.hpp>
30 #include <com/sun/star/sdbc/SQLException.hpp>
31 #include <ucbhelper/resultset.hxx>
32 #include <ucbhelper/resultsetmetadata.hxx>
33 #include <ucbhelper/macros.hxx>
35 using namespace com::sun::star;
38 namespace ucbhelper_impl
41 namespace {
43 struct PropertyInfo
45 const char* pName;
46 sal_Int32 nHandle;
47 sal_Int16 nAttributes;
48 const uno::Type& (*pGetCppuType)();
53 static const uno::Type& sal_Int32_getCppuType()
55 return cppu::UnoType<sal_Int32>::get();
58 static const uno::Type& sal_Bool_getCppuType()
60 return cppu::UnoType<bool>::get();
63 const PropertyInfo aPropertyTable[] =
65 { "IsRowCountFinal",
66 1000,
67 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY,
68 &sal_Bool_getCppuType
70 { "RowCount",
71 1001,
72 beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY,
73 &sal_Int32_getCppuType
75 { nullptr,
78 nullptr
82 #define RESULTSET_PROPERTY_COUNT 2
86 namespace {
88 class PropertySetInfo :
89 public cppu::OWeakObject,
90 public lang::XTypeProvider,
91 public beans::XPropertySetInfo
93 std::unique_ptr<uno::Sequence< beans::Property >> m_pProps;
95 private:
96 bool queryProperty(
97 const OUString& aName, beans::Property& rProp ) const;
99 public:
100 PropertySetInfo(
101 const PropertyInfo* pProps,
102 sal_Int32 nProps );
104 // XInterface
105 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type & rType ) override;
106 virtual void SAL_CALL acquire()
107 throw() override;
108 virtual void SAL_CALL release()
109 throw() override;
111 // XTypeProvider
112 virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
113 virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override;
115 // XPropertySetInfo
116 virtual uno::Sequence< beans::Property > SAL_CALL getProperties() override;
117 virtual beans::Property SAL_CALL getPropertyByName(
118 const OUString& aName ) override;
119 virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
124 typedef cppu::OMultiTypeInterfaceContainerHelperVar<OUString>
125 PropertyChangeListenerContainer;
127 namespace {
129 class PropertyChangeListeners : public PropertyChangeListenerContainer
131 public:
132 explicit PropertyChangeListeners( osl::Mutex& rMtx )
133 : PropertyChangeListenerContainer( rMtx ) {}
138 } // namespace ucbhelper_impl
140 using namespace ucbhelper_impl;
142 namespace ucbhelper
146 // struct ResultSet_Impl.
149 struct ResultSet_Impl
151 uno::Reference< uno::XComponentContext > m_xContext;
152 uno::Reference< css::ucb::XCommandEnvironment > m_xEnv;
153 uno::Reference< beans::XPropertySetInfo > m_xPropSetInfo;
154 uno::Reference< sdbc::XResultSetMetaData > m_xMetaData;
155 uno::Sequence< beans::Property > m_aProperties;
156 rtl::Reference< ResultSetDataSupplier > m_xDataSupplier;
157 osl::Mutex m_aMutex;
158 std::unique_ptr<cppu::OInterfaceContainerHelper> m_pDisposeEventListeners;
159 std::unique_ptr<PropertyChangeListeners> m_pPropertyChangeListeners;
160 sal_Int32 m_nPos;
161 bool m_bWasNull;
162 bool m_bAfterLast;
164 inline ResultSet_Impl(
165 const uno::Reference< uno::XComponentContext >& rxContext,
166 const uno::Sequence< beans::Property >& rProperties,
167 const rtl::Reference< ResultSetDataSupplier >& rDataSupplier,
168 const uno::Reference< css::ucb::XCommandEnvironment >& rxEnv );
171 inline ResultSet_Impl::ResultSet_Impl(
172 const uno::Reference< uno::XComponentContext >& rxContext,
173 const uno::Sequence< beans::Property >& rProperties,
174 const rtl::Reference< ResultSetDataSupplier >& rDataSupplier,
175 const uno::Reference< css::ucb::XCommandEnvironment >& rxEnv )
176 : m_xContext( rxContext ),
177 m_xEnv( rxEnv ),
178 m_aProperties( rProperties ),
179 m_xDataSupplier( rDataSupplier ),
180 m_nPos( 0 ), // Position is one-based. Zero means: before first element.
181 m_bWasNull( false ),
182 m_bAfterLast( false )
187 // ResultSet Implementation.
190 ResultSet::ResultSet(
191 const uno::Reference< uno::XComponentContext >& rxContext,
192 const uno::Sequence< beans::Property >& rProperties,
193 const rtl::Reference< ResultSetDataSupplier >& rDataSupplier )
194 : m_pImpl( new ResultSet_Impl(
195 rxContext,
196 rProperties,
197 rDataSupplier,
198 uno::Reference< css::ucb::XCommandEnvironment >() ) )
200 rDataSupplier->m_pResultSet = this;
204 ResultSet::ResultSet(
205 const uno::Reference< uno::XComponentContext >& rxContext,
206 const uno::Sequence< beans::Property >& rProperties,
207 const rtl::Reference< ResultSetDataSupplier >& rDataSupplier,
208 const uno::Reference< css::ucb::XCommandEnvironment >& rxEnv )
209 : m_pImpl( new ResultSet_Impl( rxContext, rProperties, rDataSupplier, rxEnv ) )
211 rDataSupplier->m_pResultSet = this;
215 // virtual
216 ResultSet::~ResultSet()
221 // XServiceInfo methods.
223 OUString SAL_CALL ResultSet::getImplementationName()
225 return "ResultSet";
228 sal_Bool SAL_CALL ResultSet::supportsService( const OUString& ServiceName )
230 return cppu::supportsService( this, ServiceName );
233 css::uno::Sequence< OUString > SAL_CALL ResultSet::getSupportedServiceNames()
235 return { RESULTSET_SERVICE_NAME };
239 // XComponent methods.
242 // virtual
243 void SAL_CALL ResultSet::dispose()
245 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
247 if ( m_pImpl->m_pDisposeEventListeners &&
248 m_pImpl->m_pDisposeEventListeners->getLength() )
250 lang::EventObject aEvt;
251 aEvt.Source = static_cast< lang::XComponent * >( this );
252 m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt );
255 if ( m_pImpl->m_pPropertyChangeListeners )
257 lang::EventObject aEvt;
258 aEvt.Source = static_cast< beans::XPropertySet * >( this );
259 m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt );
262 m_pImpl->m_xDataSupplier->close();
266 // virtual
267 void SAL_CALL ResultSet::addEventListener(
268 const uno::Reference< lang::XEventListener >& Listener )
270 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
272 if ( !m_pImpl->m_pDisposeEventListeners )
273 m_pImpl->m_pDisposeEventListeners.reset(
274 new cppu::OInterfaceContainerHelper( m_pImpl->m_aMutex ));
276 m_pImpl->m_pDisposeEventListeners->addInterface( Listener );
280 // virtual
281 void SAL_CALL ResultSet::removeEventListener(
282 const uno::Reference< lang::XEventListener >& Listener )
284 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
286 if ( m_pImpl->m_pDisposeEventListeners )
287 m_pImpl->m_pDisposeEventListeners->removeInterface( Listener );
291 // XResultSetMetaDataSupplier methods.
294 // virtual
295 uno::Reference< sdbc::XResultSetMetaData > SAL_CALL ResultSet::getMetaData()
297 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
299 if ( !m_pImpl->m_xMetaData.is() )
300 m_pImpl->m_xMetaData = new ResultSetMetaData( m_pImpl->m_xContext,
301 m_pImpl->m_aProperties );
303 return m_pImpl->m_xMetaData;
307 // XResultSet methods.
310 // virtual
311 sal_Bool SAL_CALL ResultSet::next()
313 // Note: Cursor is initially positioned before the first row.
314 // First call to 'next()' moves it to first row.
316 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
318 if ( m_pImpl->m_bAfterLast )
320 m_pImpl->m_xDataSupplier->validate();
321 return false;
324 // getResult works zero-based!
325 if ( !m_pImpl->m_xDataSupplier->getResult( m_pImpl->m_nPos ) )
327 m_pImpl->m_bAfterLast = true;
328 m_pImpl->m_xDataSupplier->validate();
329 return false;
332 m_pImpl->m_nPos++;
333 m_pImpl->m_xDataSupplier->validate();
334 return true;
338 // virtual
339 sal_Bool SAL_CALL ResultSet::isBeforeFirst()
341 if ( m_pImpl->m_bAfterLast )
343 m_pImpl->m_xDataSupplier->validate();
344 return false;
347 // getResult works zero-based!
348 if ( !m_pImpl->m_xDataSupplier->getResult( 0 ) )
350 m_pImpl->m_xDataSupplier->validate();
351 return false;
354 m_pImpl->m_xDataSupplier->validate();
355 return ( m_pImpl->m_nPos == 0 );
359 // virtual
360 sal_Bool SAL_CALL ResultSet::isAfterLast()
362 m_pImpl->m_xDataSupplier->validate();
363 return m_pImpl->m_bAfterLast;
367 // virtual
368 sal_Bool SAL_CALL ResultSet::isFirst()
370 if ( m_pImpl->m_bAfterLast )
372 m_pImpl->m_xDataSupplier->validate();
373 return false;
376 m_pImpl->m_xDataSupplier->validate();
377 return ( m_pImpl->m_nPos == 1 );
381 // virtual
382 sal_Bool SAL_CALL ResultSet::isLast()
384 if ( m_pImpl->m_bAfterLast )
386 m_pImpl->m_xDataSupplier->validate();
387 return false;
390 sal_Int32 nCount = m_pImpl->m_xDataSupplier->totalCount();
391 if ( !nCount )
393 m_pImpl->m_xDataSupplier->validate();
394 return false;
397 m_pImpl->m_xDataSupplier->validate();
398 return ( m_pImpl->m_nPos == nCount );
402 // virtual
403 void SAL_CALL ResultSet::beforeFirst()
405 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
406 m_pImpl->m_bAfterLast = false;
407 m_pImpl->m_nPos = 0;
408 m_pImpl->m_xDataSupplier->validate();
412 // virtual
413 void SAL_CALL ResultSet::afterLast()
415 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
416 m_pImpl->m_bAfterLast = true;
417 m_pImpl->m_xDataSupplier->validate();
421 // virtual
422 sal_Bool SAL_CALL ResultSet::first()
424 // getResult works zero-based!
425 if ( m_pImpl->m_xDataSupplier->getResult( 0 ) )
427 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
428 m_pImpl->m_bAfterLast = false;
429 m_pImpl->m_nPos = 1;
430 m_pImpl->m_xDataSupplier->validate();
431 return true;
434 m_pImpl->m_xDataSupplier->validate();
435 return false;
439 // virtual
440 sal_Bool SAL_CALL ResultSet::last()
442 sal_Int32 nCount = m_pImpl->m_xDataSupplier->totalCount();
443 if ( nCount )
445 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
446 m_pImpl->m_bAfterLast = false;
447 m_pImpl->m_nPos = nCount;
448 m_pImpl->m_xDataSupplier->validate();
449 return true;
452 m_pImpl->m_xDataSupplier->validate();
453 return false;
457 // virtual
458 sal_Int32 SAL_CALL ResultSet::getRow()
460 if ( m_pImpl->m_bAfterLast )
462 m_pImpl->m_xDataSupplier->validate();
463 return 0;
466 m_pImpl->m_xDataSupplier->validate();
467 return m_pImpl->m_nPos;
471 // virtual
472 sal_Bool SAL_CALL ResultSet::absolute( sal_Int32 row )
475 If the row number is positive, the cursor moves to the given row number
476 with respect to the beginning of the result set. The first row is row 1,
477 the second is row 2, and so on.
479 If the given row number is negative, the cursor moves to an absolute row
480 position with respect to the end of the result set. For example, calling
481 absolute( -1 ) positions the cursor on the last row, absolute( -2 )
482 indicates the next-to-last row, and so on.
484 An attempt to position the cursor beyond the first/last row in the result
485 set leaves the cursor before/after the first/last row, respectively.
487 Calling absolute( 1 ) is the same as calling first().
489 Calling absolute( -1 ) is the same as calling last().
491 if ( row < 0 )
493 sal_Int32 nCount = m_pImpl->m_xDataSupplier->totalCount();
495 if ( ( row * -1 ) > nCount )
497 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
498 m_pImpl->m_bAfterLast = false;
499 m_pImpl->m_nPos = 0;
500 m_pImpl->m_xDataSupplier->validate();
501 return false;
503 else // |row| <= nCount
505 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
506 m_pImpl->m_bAfterLast = false;
507 m_pImpl->m_nPos = ( nCount + row + 1 );
508 m_pImpl->m_xDataSupplier->validate();
509 return true;
512 else if ( row == 0 )
514 // @throws SQLException
515 // ... if row is 0 ...
516 throw sdbc::SQLException();
518 else // row > 0
520 sal_Int32 nCount = m_pImpl->m_xDataSupplier->totalCount();
522 if ( row <= nCount )
524 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
525 m_pImpl->m_bAfterLast = false;
526 m_pImpl->m_nPos = row;
527 m_pImpl->m_xDataSupplier->validate();
528 return true;
530 else // row > nCount
532 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
533 m_pImpl->m_bAfterLast = true;
534 m_pImpl->m_xDataSupplier->validate();
535 return false;
539 // unreachable...
543 // virtual
544 sal_Bool SAL_CALL ResultSet::relative( sal_Int32 rows )
547 Attempting to move beyond the first/last row in the result set
548 positions the cursor before/after the first/last row.
550 Calling relative( 0 ) is valid, but does not change the cursor position.
552 Calling relative( 1 ) is different from calling next() because it makes
553 sense to call next() when there is no current row, for example, when
554 the cursor is positioned before the first row or after the last row of
555 the result set.
557 if ( m_pImpl->m_bAfterLast || ( m_pImpl->m_nPos == 0 ) )
559 // "No current row".
560 throw sdbc::SQLException();
563 if ( rows < 0 )
565 if ( ( m_pImpl->m_nPos + rows ) > 0 )
567 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
568 m_pImpl->m_bAfterLast = false;
569 m_pImpl->m_nPos = ( m_pImpl->m_nPos + rows );
570 m_pImpl->m_xDataSupplier->validate();
571 return true;
573 else
575 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
576 m_pImpl->m_bAfterLast = false;
577 m_pImpl->m_nPos = 0;
578 m_pImpl->m_xDataSupplier->validate();
579 return false;
582 else if ( rows == 0 )
584 // nop.
585 m_pImpl->m_xDataSupplier->validate();
586 return true;
588 else // rows > 0
590 sal_Int32 nCount = m_pImpl->m_xDataSupplier->totalCount();
591 if ( ( m_pImpl->m_nPos + rows ) <= nCount )
593 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
594 m_pImpl->m_bAfterLast = false;
595 m_pImpl->m_nPos = ( m_pImpl->m_nPos + rows );
596 m_pImpl->m_xDataSupplier->validate();
597 return true;
599 else
601 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
602 m_pImpl->m_bAfterLast = true;
603 m_pImpl->m_xDataSupplier->validate();
604 return false;
608 // unreachable...
612 // virtual
613 sal_Bool SAL_CALL ResultSet::previous()
616 previous() is not the same as relative( -1 ) because it makes sense
617 to call previous() when there is no current row.
619 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
621 if ( m_pImpl->m_bAfterLast )
623 m_pImpl->m_bAfterLast = false;
624 sal_Int32 nCount = m_pImpl->m_xDataSupplier->totalCount();
625 m_pImpl->m_nPos = nCount;
627 else if ( m_pImpl->m_nPos )
628 m_pImpl->m_nPos--;
630 if ( m_pImpl->m_nPos )
632 m_pImpl->m_xDataSupplier->validate();
633 return true;
636 m_pImpl->m_xDataSupplier->validate();
637 return false;
641 // virtual
642 void SAL_CALL ResultSet::refreshRow()
644 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
645 if ( m_pImpl->m_bAfterLast || ( m_pImpl->m_nPos == 0 ) )
646 return;
648 m_pImpl->m_xDataSupplier->releasePropertyValues( m_pImpl->m_nPos );
649 m_pImpl->m_xDataSupplier->validate();
653 // virtual
654 sal_Bool SAL_CALL ResultSet::rowUpdated()
656 m_pImpl->m_xDataSupplier->validate();
657 return false;
661 // virtual
662 sal_Bool SAL_CALL ResultSet::rowInserted()
664 m_pImpl->m_xDataSupplier->validate();
665 return false;
669 // virtual
670 sal_Bool SAL_CALL ResultSet::rowDeleted()
672 m_pImpl->m_xDataSupplier->validate();
673 return false;
677 // virtual
678 uno::Reference< uno::XInterface > SAL_CALL ResultSet::getStatement()
681 returns the Statement that produced this ResultSet object. If the
682 result set was generated some other way, ... this method returns null.
684 m_pImpl->m_xDataSupplier->validate();
685 return uno::Reference< uno::XInterface >();
689 // XRow methods.
692 // virtual
693 sal_Bool SAL_CALL ResultSet::wasNull()
695 // This method can not be implemented correctly!!! Imagine different
696 // threads doing a getXYZ - wasNull calling sequence on the same
697 // implementation object...
699 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
701 uno::Reference< sdbc::XRow > xValues
702 = m_pImpl->m_xDataSupplier->queryPropertyValues(
703 m_pImpl->m_nPos - 1 );
704 if ( xValues.is() )
706 m_pImpl->m_xDataSupplier->validate();
707 return xValues->wasNull();
711 m_pImpl->m_xDataSupplier->validate();
712 return m_pImpl->m_bWasNull;
716 // virtual
717 OUString SAL_CALL ResultSet::getString( sal_Int32 columnIndex )
719 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
721 uno::Reference< sdbc::XRow > xValues
722 = m_pImpl->m_xDataSupplier->queryPropertyValues(
723 m_pImpl->m_nPos - 1 );
724 if ( xValues.is() )
726 m_pImpl->m_bWasNull = false;
727 m_pImpl->m_xDataSupplier->validate();
728 return xValues->getString( columnIndex );
732 m_pImpl->m_bWasNull = true;
733 m_pImpl->m_xDataSupplier->validate();
734 return OUString();
738 // virtual
739 sal_Bool SAL_CALL ResultSet::getBoolean( sal_Int32 columnIndex )
741 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
743 uno::Reference< sdbc::XRow > xValues
744 = m_pImpl->m_xDataSupplier->queryPropertyValues(
745 m_pImpl->m_nPos - 1 );
746 if ( xValues.is() )
748 m_pImpl->m_bWasNull = false;
749 m_pImpl->m_xDataSupplier->validate();
750 return xValues->getBoolean( columnIndex );
754 m_pImpl->m_bWasNull = true;
755 m_pImpl->m_xDataSupplier->validate();
756 return false;
760 // virtual
761 sal_Int8 SAL_CALL ResultSet::getByte( sal_Int32 columnIndex )
763 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
765 uno::Reference< sdbc::XRow > xValues
766 = m_pImpl->m_xDataSupplier->queryPropertyValues(
767 m_pImpl->m_nPos - 1 );
768 if ( xValues.is() )
770 m_pImpl->m_bWasNull = false;
771 m_pImpl->m_xDataSupplier->validate();
772 return xValues->getByte( columnIndex );
776 m_pImpl->m_bWasNull = true;
777 m_pImpl->m_xDataSupplier->validate();
778 return 0;
782 // virtual
783 sal_Int16 SAL_CALL ResultSet::getShort( sal_Int32 columnIndex )
785 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
787 uno::Reference< sdbc::XRow > xValues
788 = m_pImpl->m_xDataSupplier->queryPropertyValues(
789 m_pImpl->m_nPos - 1 );
790 if ( xValues.is() )
792 m_pImpl->m_bWasNull = false;
793 m_pImpl->m_xDataSupplier->validate();
794 return xValues->getShort( columnIndex );
798 m_pImpl->m_bWasNull = true;
799 m_pImpl->m_xDataSupplier->validate();
800 return 0;
804 // virtual
805 sal_Int32 SAL_CALL ResultSet::getInt( sal_Int32 columnIndex )
807 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
809 uno::Reference< sdbc::XRow > xValues
810 = m_pImpl->m_xDataSupplier->queryPropertyValues(
811 m_pImpl->m_nPos - 1 );
812 if ( xValues.is() )
814 m_pImpl->m_bWasNull = false;
815 m_pImpl->m_xDataSupplier->validate();
816 return xValues->getInt( columnIndex );
820 m_pImpl->m_bWasNull = true;
821 m_pImpl->m_xDataSupplier->validate();
822 return 0;
826 // virtual
827 sal_Int64 SAL_CALL ResultSet::getLong( sal_Int32 columnIndex )
829 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
831 uno::Reference< sdbc::XRow > xValues
832 = m_pImpl->m_xDataSupplier->queryPropertyValues(
833 m_pImpl->m_nPos - 1 );
834 if ( xValues.is() )
836 m_pImpl->m_bWasNull = false;
837 m_pImpl->m_xDataSupplier->validate();
838 return xValues->getLong( columnIndex );
842 m_pImpl->m_bWasNull = true;
843 m_pImpl->m_xDataSupplier->validate();
844 return 0;
848 // virtual
849 float SAL_CALL ResultSet::getFloat( sal_Int32 columnIndex )
851 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
853 uno::Reference< sdbc::XRow > xValues
854 = m_pImpl->m_xDataSupplier->queryPropertyValues(
855 m_pImpl->m_nPos - 1 );
856 if ( xValues.is() )
858 m_pImpl->m_bWasNull = false;
859 m_pImpl->m_xDataSupplier->validate();
860 return xValues->getFloat( columnIndex );
864 m_pImpl->m_bWasNull = true;
865 m_pImpl->m_xDataSupplier->validate();
866 return 0;
870 // virtual
871 double SAL_CALL ResultSet::getDouble( sal_Int32 columnIndex )
873 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
875 uno::Reference< sdbc::XRow > xValues
876 = m_pImpl->m_xDataSupplier->queryPropertyValues(
877 m_pImpl->m_nPos - 1 );
878 if ( xValues.is() )
880 m_pImpl->m_bWasNull = false;
881 m_pImpl->m_xDataSupplier->validate();
882 return xValues->getDouble( columnIndex );
886 m_pImpl->m_bWasNull = true;
887 m_pImpl->m_xDataSupplier->validate();
888 return 0;
892 // virtual
893 uno::Sequence< sal_Int8 > SAL_CALL
894 ResultSet::getBytes( sal_Int32 columnIndex )
896 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
898 uno::Reference< sdbc::XRow > xValues
899 = m_pImpl->m_xDataSupplier->queryPropertyValues(
900 m_pImpl->m_nPos - 1 );
901 if ( xValues.is() )
903 m_pImpl->m_bWasNull = false;
904 m_pImpl->m_xDataSupplier->validate();
905 return xValues->getBytes( columnIndex );
909 m_pImpl->m_bWasNull = true;
910 m_pImpl->m_xDataSupplier->validate();
911 return uno::Sequence< sal_Int8 >();
915 // virtual
916 util::Date SAL_CALL ResultSet::getDate( sal_Int32 columnIndex )
918 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
920 uno::Reference< sdbc::XRow > xValues
921 = m_pImpl->m_xDataSupplier->queryPropertyValues(
922 m_pImpl->m_nPos - 1 );
923 if ( xValues.is() )
925 m_pImpl->m_bWasNull = false;
926 m_pImpl->m_xDataSupplier->validate();
927 return xValues->getDate( columnIndex );
931 m_pImpl->m_bWasNull = true;
932 m_pImpl->m_xDataSupplier->validate();
933 return util::Date();
937 // virtual
938 util::Time SAL_CALL ResultSet::getTime( sal_Int32 columnIndex )
940 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
942 uno::Reference< sdbc::XRow > xValues
943 = m_pImpl->m_xDataSupplier->queryPropertyValues(
944 m_pImpl->m_nPos - 1 );
945 if ( xValues.is() )
947 m_pImpl->m_bWasNull = false;
948 m_pImpl->m_xDataSupplier->validate();
949 return xValues->getTime( columnIndex );
953 m_pImpl->m_bWasNull = true;
954 m_pImpl->m_xDataSupplier->validate();
955 return util::Time();
959 // virtual
960 util::DateTime SAL_CALL
961 ResultSet::getTimestamp( sal_Int32 columnIndex )
963 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
965 uno::Reference< sdbc::XRow > xValues
966 = m_pImpl->m_xDataSupplier->queryPropertyValues(
967 m_pImpl->m_nPos - 1 );
968 if ( xValues.is() )
970 m_pImpl->m_bWasNull = false;
971 m_pImpl->m_xDataSupplier->validate();
972 return xValues->getTimestamp( columnIndex );
976 m_pImpl->m_bWasNull = true;
977 m_pImpl->m_xDataSupplier->validate();
978 return util::DateTime();
982 // virtual
983 uno::Reference< io::XInputStream > SAL_CALL
984 ResultSet::getBinaryStream( sal_Int32 columnIndex )
986 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
988 uno::Reference< sdbc::XRow > xValues
989 = m_pImpl->m_xDataSupplier->queryPropertyValues(
990 m_pImpl->m_nPos - 1 );
991 if ( xValues.is() )
993 m_pImpl->m_bWasNull = false;
994 m_pImpl->m_xDataSupplier->validate();
995 return xValues->getBinaryStream( columnIndex );
999 m_pImpl->m_bWasNull = true;
1000 m_pImpl->m_xDataSupplier->validate();
1001 return uno::Reference< io::XInputStream >();
1005 // virtual
1006 uno::Reference< io::XInputStream > SAL_CALL
1007 ResultSet::getCharacterStream( sal_Int32 columnIndex )
1009 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1011 uno::Reference< sdbc::XRow > xValues
1012 = m_pImpl->m_xDataSupplier->queryPropertyValues(
1013 m_pImpl->m_nPos - 1 );
1014 if ( xValues.is() )
1016 m_pImpl->m_bWasNull = false;
1017 m_pImpl->m_xDataSupplier->validate();
1018 return xValues->getCharacterStream( columnIndex );
1022 m_pImpl->m_bWasNull = true;
1023 m_pImpl->m_xDataSupplier->validate();
1024 return uno::Reference< io::XInputStream >();
1028 // virtual
1029 uno::Any SAL_CALL ResultSet::getObject(
1030 sal_Int32 columnIndex,
1031 const uno::Reference< container::XNameAccess >& typeMap )
1033 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1035 uno::Reference< sdbc::XRow > xValues
1036 = m_pImpl->m_xDataSupplier->queryPropertyValues(
1037 m_pImpl->m_nPos - 1 );
1038 if ( xValues.is() )
1040 m_pImpl->m_bWasNull = false;
1041 m_pImpl->m_xDataSupplier->validate();
1042 return xValues->getObject( columnIndex, typeMap );
1046 m_pImpl->m_bWasNull = true;
1047 m_pImpl->m_xDataSupplier->validate();
1048 return uno::Any();
1052 // virtual
1053 uno::Reference< sdbc::XRef > SAL_CALL
1054 ResultSet::getRef( sal_Int32 columnIndex )
1056 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1058 uno::Reference< sdbc::XRow > xValues
1059 = m_pImpl->m_xDataSupplier->queryPropertyValues(
1060 m_pImpl->m_nPos - 1 );
1061 if ( xValues.is() )
1063 m_pImpl->m_bWasNull = false;
1064 m_pImpl->m_xDataSupplier->validate();
1065 return xValues->getRef( columnIndex );
1069 m_pImpl->m_bWasNull = true;
1070 m_pImpl->m_xDataSupplier->validate();
1071 return uno::Reference< sdbc::XRef >();
1075 // virtual
1076 uno::Reference< sdbc::XBlob > SAL_CALL
1077 ResultSet::getBlob( sal_Int32 columnIndex )
1079 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1081 uno::Reference< sdbc::XRow > xValues
1082 = m_pImpl->m_xDataSupplier->queryPropertyValues(
1083 m_pImpl->m_nPos - 1 );
1084 if ( xValues.is() )
1086 m_pImpl->m_bWasNull = false;
1087 m_pImpl->m_xDataSupplier->validate();
1088 return xValues->getBlob( columnIndex );
1092 m_pImpl->m_bWasNull = true;
1093 m_pImpl->m_xDataSupplier->validate();
1094 return uno::Reference< sdbc::XBlob >();
1098 // virtual
1099 uno::Reference< sdbc::XClob > SAL_CALL
1100 ResultSet::getClob( sal_Int32 columnIndex )
1102 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1104 uno::Reference< sdbc::XRow > xValues
1105 = m_pImpl->m_xDataSupplier->queryPropertyValues(
1106 m_pImpl->m_nPos - 1 );
1107 if ( xValues.is() )
1109 m_pImpl->m_bWasNull = false;
1110 m_pImpl->m_xDataSupplier->validate();
1111 return xValues->getClob( columnIndex );
1115 m_pImpl->m_bWasNull = true;
1116 m_pImpl->m_xDataSupplier->validate();
1117 return uno::Reference< sdbc::XClob >();
1121 // virtual
1122 uno::Reference< sdbc::XArray > SAL_CALL
1123 ResultSet::getArray( sal_Int32 columnIndex )
1125 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1127 uno::Reference< sdbc::XRow > xValues
1128 = m_pImpl->m_xDataSupplier->queryPropertyValues(
1129 m_pImpl->m_nPos - 1 );
1130 if ( xValues.is() )
1132 m_pImpl->m_bWasNull = false;
1133 m_pImpl->m_xDataSupplier->validate();
1134 return xValues->getArray( columnIndex );
1138 m_pImpl->m_bWasNull = true;
1139 m_pImpl->m_xDataSupplier->validate();
1140 return uno::Reference< sdbc::XArray >();
1144 // XCloseable methods.
1147 // virtual
1148 void SAL_CALL ResultSet::close()
1150 m_pImpl->m_xDataSupplier->close();
1151 m_pImpl->m_xDataSupplier->validate();
1155 // XContentAccess methods.
1158 // virtual
1159 OUString SAL_CALL ResultSet::queryContentIdentifierString()
1161 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1162 return m_pImpl->m_xDataSupplier->queryContentIdentifierString(
1163 m_pImpl->m_nPos - 1 );
1165 return OUString();
1169 // virtual
1170 uno::Reference< css::ucb::XContentIdentifier > SAL_CALL
1171 ResultSet::queryContentIdentifier()
1173 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1174 return m_pImpl->m_xDataSupplier->queryContentIdentifier(
1175 m_pImpl->m_nPos - 1 );
1177 return uno::Reference< css::ucb::XContentIdentifier >();
1181 // virtual
1182 uno::Reference< css::ucb::XContent > SAL_CALL
1183 ResultSet::queryContent()
1185 if ( m_pImpl->m_nPos && !m_pImpl->m_bAfterLast )
1186 return m_pImpl->m_xDataSupplier->queryContent( m_pImpl->m_nPos - 1 );
1188 return uno::Reference< css::ucb::XContent >();
1192 // XPropertySet methods.
1195 // virtual
1196 uno::Reference< beans::XPropertySetInfo > SAL_CALL
1197 ResultSet::getPropertySetInfo()
1199 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
1201 if ( !m_pImpl->m_xPropSetInfo.is() )
1202 m_pImpl->m_xPropSetInfo
1203 = new PropertySetInfo( aPropertyTable,
1204 RESULTSET_PROPERTY_COUNT );
1205 return m_pImpl->m_xPropSetInfo;
1209 // virtual
1210 void SAL_CALL ResultSet::setPropertyValue( const OUString& aPropertyName,
1211 const uno::Any& )
1213 if ( aPropertyName == "RowCount" )
1215 // property is read-only.
1216 throw lang::IllegalArgumentException();
1218 else if ( aPropertyName == "IsRowCountFinal" )
1220 // property is read-only.
1221 throw lang::IllegalArgumentException();
1223 else
1225 throw beans::UnknownPropertyException(aPropertyName);
1230 // virtual
1231 uno::Any SAL_CALL ResultSet::getPropertyValue(
1232 const OUString& PropertyName )
1234 uno::Any aValue;
1236 if ( PropertyName == "RowCount" )
1238 aValue <<= m_pImpl->m_xDataSupplier->currentCount();
1240 else if ( PropertyName == "IsRowCountFinal" )
1242 aValue <<= m_pImpl->m_xDataSupplier->isCountFinal();
1244 else
1246 throw beans::UnknownPropertyException(PropertyName);
1249 return aValue;
1253 // virtual
1254 void SAL_CALL ResultSet::addPropertyChangeListener(
1255 const OUString& aPropertyName,
1256 const uno::Reference< beans::XPropertyChangeListener >& xListener )
1258 // Note: An empty property name means a listener for "all" properties.
1260 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
1262 if ( !aPropertyName.isEmpty() &&
1263 aPropertyName != "RowCount" &&
1264 aPropertyName != "IsRowCountFinal" )
1265 throw beans::UnknownPropertyException(aPropertyName);
1267 if ( !m_pImpl->m_pPropertyChangeListeners )
1268 m_pImpl->m_pPropertyChangeListeners.reset(
1269 new PropertyChangeListeners( m_pImpl->m_aMutex ));
1271 m_pImpl->m_pPropertyChangeListeners->addInterface(
1272 aPropertyName, xListener );
1276 // virtual
1277 void SAL_CALL ResultSet::removePropertyChangeListener(
1278 const OUString& aPropertyName,
1279 const uno::Reference< beans::XPropertyChangeListener >& xListener )
1281 osl::MutexGuard aGuard( m_pImpl->m_aMutex );
1283 if ( !aPropertyName.isEmpty() &&
1284 aPropertyName != "RowCount" &&
1285 aPropertyName != "IsRowCountFinal" )
1286 throw beans::UnknownPropertyException(aPropertyName);
1288 if ( m_pImpl->m_pPropertyChangeListeners )
1289 m_pImpl->m_pPropertyChangeListeners->removeInterface(
1290 aPropertyName, xListener );
1295 // virtual
1296 void SAL_CALL ResultSet::addVetoableChangeListener(
1297 const OUString&,
1298 const uno::Reference< beans::XVetoableChangeListener >& )
1300 // No constrained props, at the moment.
1304 // virtual
1305 void SAL_CALL ResultSet::removeVetoableChangeListener(
1306 const OUString&,
1307 const uno::Reference< beans::XVetoableChangeListener >& )
1309 // No constrained props, at the moment.
1313 // Non-interface methods.
1316 void ResultSet::propertyChanged( const beans::PropertyChangeEvent& rEvt ) const
1318 if ( !m_pImpl->m_pPropertyChangeListeners )
1319 return;
1321 // Notify listeners interested especially in the changed property.
1322 cppu::OInterfaceContainerHelper* pPropsContainer
1323 = m_pImpl->m_pPropertyChangeListeners->getContainer(
1324 rEvt.PropertyName );
1325 if ( pPropsContainer )
1327 pPropsContainer->notifyEach(&beans::XPropertyChangeListener::propertyChange, rEvt);
1330 // Notify listeners interested in all properties.
1331 pPropsContainer
1332 = m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() );
1333 if ( pPropsContainer )
1335 cppu::OInterfaceIteratorHelper aIter( *pPropsContainer );
1336 while ( aIter.hasMoreElements() )
1338 uno::Reference< beans::XPropertyChangeListener > xListener(
1339 aIter.next(), uno::UNO_QUERY );
1340 if ( xListener.is() )
1341 xListener->propertyChange( rEvt );
1347 void ResultSet::rowCountChanged( sal_uInt32 nOld, sal_uInt32 nNew )
1349 OSL_ENSURE( nOld < nNew, "ResultSet::rowCountChanged - nOld >= nNew!" );
1351 if ( !m_pImpl->m_pPropertyChangeListeners )
1352 return;
1354 propertyChanged(
1355 beans::PropertyChangeEvent(
1356 static_cast< cppu::OWeakObject * >( this ),
1357 "RowCount",
1358 false,
1359 1001,
1360 uno::makeAny( nOld ), // old value
1361 uno::makeAny( nNew ) ) ); // new value
1365 void ResultSet::rowCountFinal()
1367 if ( !m_pImpl->m_pPropertyChangeListeners )
1368 return;
1370 propertyChanged(
1371 beans::PropertyChangeEvent(
1372 static_cast< cppu::OWeakObject * >( this ),
1373 "IsRowCountFinal",
1374 false,
1375 1000,
1376 uno:: makeAny( false ), // old value
1377 uno::makeAny( true ) ) ); // new value
1381 const uno::Sequence< beans::Property >& ResultSet::getProperties() const
1383 return m_pImpl->m_aProperties;
1387 const uno::Reference< css::ucb::XCommandEnvironment >&
1388 ResultSet::getEnvironment() const
1390 return m_pImpl->m_xEnv;
1393 } // namespace ucbhelper
1395 namespace ucbhelper_impl {
1398 // PropertySetInfo Implementation.
1401 PropertySetInfo::PropertySetInfo(
1402 const PropertyInfo* pProps,
1403 sal_Int32 nProps )
1404 : m_pProps( new uno::Sequence< beans::Property >( nProps ) )
1407 if ( !nProps )
1408 return;
1410 const PropertyInfo* pEntry = pProps;
1411 beans::Property* pProperties = m_pProps->getArray();
1413 for ( sal_Int32 n = 0; n < nProps; ++n )
1415 beans::Property& rProp = pProperties[ n ];
1417 rProp.Name = OUString::createFromAscii( pEntry->pName );
1418 rProp.Handle = pEntry->nHandle;
1419 rProp.Type = pEntry->pGetCppuType();
1420 rProp.Attributes = pEntry->nAttributes;
1422 pEntry++;
1428 // XInterface methods.
1429 void SAL_CALL PropertySetInfo::acquire()
1430 throw()
1432 OWeakObject::acquire();
1435 void SAL_CALL PropertySetInfo::release()
1436 throw()
1438 OWeakObject::release();
1441 css::uno::Any SAL_CALL PropertySetInfo::queryInterface(
1442 const css::uno::Type & rType )
1444 css::uno::Any aRet = cppu::queryInterface( rType,
1445 static_cast< lang::XTypeProvider* >(this),
1446 static_cast< beans::XPropertySetInfo* >(this)
1448 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
1451 // XTypeProvider methods.
1454 XTYPEPROVIDER_IMPL_2( PropertySetInfo,
1455 lang::XTypeProvider,
1456 beans::XPropertySetInfo );
1459 // XPropertySetInfo methods.
1462 // virtual
1463 uno::Sequence< beans::Property > SAL_CALL PropertySetInfo::getProperties()
1465 return *m_pProps;
1469 // virtual
1470 beans::Property SAL_CALL PropertySetInfo::getPropertyByName(
1471 const OUString& aName )
1473 beans::Property aProp;
1474 if ( queryProperty( aName, aProp ) )
1475 return aProp;
1477 throw beans::UnknownPropertyException(aName);
1481 // virtual
1482 sal_Bool SAL_CALL PropertySetInfo::hasPropertyByName(
1483 const OUString& Name )
1485 beans::Property aProp;
1486 return queryProperty( Name, aProp );
1490 bool PropertySetInfo::queryProperty(
1491 const OUString& aName, beans::Property& rProp ) const
1493 sal_Int32 nCount = m_pProps->getLength();
1494 const beans::Property* pProps = m_pProps->getConstArray();
1495 for ( sal_Int32 n = 0; n < nCount; ++n )
1497 const beans::Property& rCurr = pProps[ n ];
1498 if ( rCurr.Name == aName )
1500 rProp = rCurr;
1501 return true;
1505 return false;
1508 } // namespace ucbhelper_impl
1510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */