1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
19 #include <connectivity/paramwrapper.hxx>
21 #include <com/sun/star/beans/PropertyAttribute.hpp>
22 #include <com/sun/star/sdbc/DataType.hpp>
23 #include <com/sun/star/sdbc/SQLException.hpp>
24 #include <com/sun/star/sdbc/XParameters.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <com/sun/star/lang/WrappedTargetException.hpp>
27 #include <com/sun/star/sdb/XParametersSupplier.hpp>
28 #include <com/sun/star/lang/DisposedException.hpp>
30 #include <tools/diagnose_ex.h>
31 #include <comphelper/enumhelper.hxx>
33 #define PROPERTY_ID_VALUE 1000
42 using ::com::sun::star::uno::Reference
;
43 using ::com::sun::star::sdbc::XParameters
;
44 using ::com::sun::star::uno::Sequence
;
45 using ::com::sun::star::uno::Type
;
46 using ::com::sun::star::uno::RuntimeException
;
47 using ::com::sun::star::uno::XWeak
;
48 using ::com::sun::star::beans::XPropertySet
;
49 using ::com::sun::star::beans::XFastPropertySet
;
50 using ::com::sun::star::beans::XMultiPropertySet
;
51 using ::com::sun::star::beans::XPropertySetInfo
;
52 using ::com::sun::star::beans::Property
;
53 using ::com::sun::star::uno::Exception
;
54 using ::com::sun::star::uno::UNO_QUERY_THROW
;
55 using ::com::sun::star::uno::Any
;
56 using ::com::sun::star::sdbc::SQLException
;
57 using ::com::sun::star::lang::WrappedTargetException
;
58 using ::com::sun::star::lang::IndexOutOfBoundsException
;
59 using ::com::sun::star::container::XEnumeration
;
60 using ::com::sun::star::sdb::XSingleSelectQueryAnalyzer
;
61 using ::com::sun::star::sdb::XParametersSupplier
;
62 using ::com::sun::star::lang::DisposedException
;
64 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
65 namespace DataType
= ::com::sun::star::sdbc::DataType
;
67 ParameterWrapper::ParameterWrapper( const Reference
< XPropertySet
>& _rxColumn
)
68 :PropertyBase( m_aBHelper
)
69 ,m_xDelegator( _rxColumn
)
71 if ( m_xDelegator
.is() )
72 m_xDelegatorPSI
= m_xDelegator
->getPropertySetInfo();
73 if ( !m_xDelegatorPSI
.is() )
74 throw RuntimeException();
78 ParameterWrapper::ParameterWrapper( const Reference
< XPropertySet
>& _rxColumn
,
79 const Reference
< XParameters
>& _rxAllParameters
, const std::vector
< sal_Int32
>& _rIndexes
)
80 :PropertyBase( m_aBHelper
)
81 ,m_aIndexes( _rIndexes
)
82 ,m_xDelegator( _rxColumn
)
83 ,m_xValueDestination( _rxAllParameters
)
85 if ( m_xDelegator
.is() )
86 m_xDelegatorPSI
= m_xDelegator
->getPropertySetInfo();
87 if ( !m_xDelegatorPSI
.is() )
88 throw RuntimeException();
90 OSL_ENSURE( !m_aIndexes
.empty(), "ParameterWrapper::ParameterWrapper: sure about the indexes?" );
94 ParameterWrapper::~ParameterWrapper()
99 IMPLEMENT_FORWARD_REFCOUNT( ParameterWrapper
, UnoBase
)
101 css::uno::Any
ParameterWrapper::queryInterface(css::uno::Type
const & aType
)
103 css::uno::Any
a(UnoBase::queryInterface(aType
));
105 a
= PropertyBase::queryInterface(aType
);
107 && aType
== cppu::UnoType
<css::lang::XTypeProvider
>::get())
109 a
<<= css::uno::Reference
<css::lang::XTypeProvider
>(this);
116 Sequence
< Type
> SAL_CALL
ParameterWrapper::getTypes( )
118 return Sequence
< Type
> {
119 cppu::UnoType
<XWeak
>::get(),
120 cppu::UnoType
<XTypeProvider
>::get(),
121 cppu::UnoType
<XPropertySet
>::get(),
122 cppu::UnoType
<XFastPropertySet
>::get(),
123 cppu::UnoType
<XMultiPropertySet
>::get()
128 IMPLEMENT_GET_IMPLEMENTATION_ID( ParameterWrapper
)
131 OUString
ParameterWrapper::impl_getPseudoAggregatePropertyName( sal_Int32 _nHandle
) const
133 Reference
< XPropertySetInfo
> xInfo
= const_cast<ParameterWrapper
*>( this )->getPropertySetInfo();
134 for ( const Property
& rProperty
: xInfo
->getProperties() )
136 if ( rProperty
.Handle
== _nHandle
)
137 return rProperty
.Name
;
140 OSL_FAIL( "ParameterWrapper::impl_getPseudoAggregatePropertyName: invalid argument!" );
145 Reference
< XPropertySetInfo
> ParameterWrapper::getPropertySetInfo()
147 return createPropertySetInfo( getInfoHelper() );
151 ::cppu::IPropertyArrayHelper
& ParameterWrapper::getInfoHelper()
155 Sequence
< Property
> aProperties
;
158 aProperties
= m_xDelegatorPSI
->getProperties();
159 sal_Int32
nProperties( aProperties
.getLength() );
160 aProperties
.realloc( nProperties
+ 1 );
161 aProperties
[ nProperties
] = Property(
164 ::cppu::UnoType
< Any
>::get(),
165 PropertyAttribute::TRANSIENT
| PropertyAttribute::MAYBEVOID
168 catch( const Exception
& )
170 DBG_UNHANDLED_EXCEPTION("connectivity.commontools");
173 m_pInfoHelper
.reset( new ::cppu::OPropertyArrayHelper( aProperties
, false ) );
175 return *m_pInfoHelper
;
179 sal_Bool
ParameterWrapper::convertFastPropertyValue(Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nHandle
, const Any
& rValue
)
181 OSL_ENSURE( PROPERTY_ID_VALUE
== nHandle
, "ParameterWrapper::convertFastPropertyValue: the only non-readonly prop should be our PROPERTY_VALUE!" );
183 // we're lazy here ...
184 rOldValue
= m_aValue
.makeAny();
185 rConvertedValue
= rValue
;
186 return true; // assume "modified" ...
190 void ParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
)
192 if ( nHandle
== PROPERTY_ID_VALUE
)
196 // TODO : aParamType & nScale can be obtained within the constructor ....
197 sal_Int32 nParamType
= DataType::VARCHAR
;
198 OSL_VERIFY( m_xDelegator
->getPropertyValue("Type") >>= nParamType
);
200 sal_Int32 nScale
= 0;
201 if ( m_xDelegatorPSI
->hasPropertyByName("Scale") )
202 OSL_VERIFY( m_xDelegator
->getPropertyValue("Scale") >>= nScale
);
204 if ( m_xValueDestination
.is() )
206 for ( const auto& rIndex
: m_aIndexes
)
208 m_xValueDestination
->setObjectWithInfo( rIndex
+ 1, rValue
, nParamType
, nScale
);
209 // (the index of the parameters is one-based)
215 catch( SQLException
& e
)
217 WrappedTargetException aExceptionWrapper
;
218 aExceptionWrapper
.Context
= e
.Context
;
219 aExceptionWrapper
.Message
= e
.Message
;
220 aExceptionWrapper
.TargetException
<<= e
;
221 throw aExceptionWrapper
;
226 OUString aName
= impl_getPseudoAggregatePropertyName( nHandle
);
227 m_xDelegator
->setPropertyValue( aName
, rValue
);
232 void ParameterWrapper::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
234 if ( nHandle
== PROPERTY_ID_VALUE
)
236 rValue
= m_aValue
.makeAny();
240 OUString aName
= impl_getPseudoAggregatePropertyName( nHandle
);
241 rValue
= m_xDelegator
->getPropertyValue( aName
);
246 void ParameterWrapper::dispose()
248 ::osl::MutexGuard
aGuard( m_aMutex
);
251 m_aIndexes
.resize(0);
252 m_xDelegator
.clear();
253 m_xDelegatorPSI
.clear();
254 m_xValueDestination
.clear();
256 m_aBHelper
.bDisposed
= true;
259 ParameterWrapperContainer::ParameterWrapperContainer()
260 :ParameterWrapperContainer_Base( m_aMutex
)
265 ParameterWrapperContainer::ParameterWrapperContainer( const Reference
< XSingleSelectQueryAnalyzer
>& _rxComposer
)
266 :ParameterWrapperContainer_Base( m_aMutex
)
268 Reference
< XParametersSupplier
> xSuppParams( _rxComposer
, UNO_QUERY_THROW
);
269 Reference
< XIndexAccess
> xParameters( xSuppParams
->getParameters(), css::uno::UNO_SET_THROW
);
270 sal_Int32
nParamCount( xParameters
->getCount() );
271 m_aParameters
.reserve( nParamCount
);
272 for ( sal_Int32 i
=0; i
<nParamCount
; ++i
)
274 m_aParameters
.push_back( new ParameterWrapper( Reference
< XPropertySet
>( xParameters
->getByIndex( i
), UNO_QUERY_THROW
) ) );
279 ParameterWrapperContainer::~ParameterWrapperContainer()
284 Type SAL_CALL
ParameterWrapperContainer::getElementType()
286 ::osl::MutexGuard
aGuard( m_aMutex
);
287 impl_checkDisposed_throw();
288 return cppu::UnoType
<XPropertySet
>::get();
292 sal_Bool SAL_CALL
ParameterWrapperContainer::hasElements()
294 ::osl::MutexGuard
aGuard( m_aMutex
);
295 impl_checkDisposed_throw();
296 return !m_aParameters
.empty();
300 sal_Int32 SAL_CALL
ParameterWrapperContainer::getCount()
302 ::osl::MutexGuard
aGuard( m_aMutex
);
303 impl_checkDisposed_throw();
304 return m_aParameters
.size();
308 Any SAL_CALL
ParameterWrapperContainer::getByIndex( sal_Int32 _nIndex
)
310 ::osl::MutexGuard
aGuard( m_aMutex
);
311 impl_checkDisposed_throw();
313 if ( ( _nIndex
< 0 ) || ( _nIndex
>= static_cast<sal_Int32
>(m_aParameters
.size()) ) )
314 throw IndexOutOfBoundsException();
316 return makeAny( Reference
< XPropertySet
>( m_aParameters
[ _nIndex
].get() ) );
320 Reference
< XEnumeration
> ParameterWrapperContainer::createEnumeration()
322 ::osl::MutexGuard
aGuard( m_aMutex
);
323 impl_checkDisposed_throw();
325 return new ::comphelper::OEnumerationByIndex( static_cast< XIndexAccess
* >( this ) );
329 void ParameterWrapperContainer::impl_checkDisposed_throw()
331 if ( rBHelper
.bDisposed
)
332 throw DisposedException( OUString(), *this );
336 void SAL_CALL
ParameterWrapperContainer::disposing()
338 ::osl::MutexGuard
aGuard( m_aMutex
);
339 impl_checkDisposed_throw();
341 for (const auto& rxParam
: m_aParameters
)
347 m_aParameters
.swap( aEmpty
);
351 } } // namespace dbtools::param
354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */