LibreOffice Module connectivity (master) 1
paramwrapper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
20
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/sdb/XSingleSelectQueryAnalyzer.hpp>
29#include <com/sun/star/lang/DisposedException.hpp>
30
31#include <o3tl/safeint.hxx>
34
35#define PROPERTY_ID_VALUE 1000
36
37
39{
40
41
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;
63
64 namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
65 namespace DataType = ::com::sun::star::sdbc::DataType;
66
67 ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn )
68 :PropertyBase( m_aBHelper )
69 ,m_xDelegator( _rxColumn )
70 {
71 if ( m_xDelegator.is() )
72 m_xDelegatorPSI = m_xDelegator->getPropertySetInfo();
73 if ( !m_xDelegatorPSI.is() )
74 throw RuntimeException();
75 }
76
77
78 ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn,
79 const Reference< XParameters >& _rxAllParameters, std::vector< sal_Int32 >&& _rIndexes )
80 :PropertyBase( m_aBHelper )
81 ,m_aIndexes( std::move(_rIndexes) )
82 ,m_xDelegator( _rxColumn )
83 ,m_xValueDestination( _rxAllParameters )
84 {
85 if ( m_xDelegator.is() )
86 m_xDelegatorPSI = m_xDelegator->getPropertySetInfo();
87 if ( !m_xDelegatorPSI.is() )
88 throw RuntimeException();
89
90 OSL_ENSURE( !m_aIndexes.empty(), "ParameterWrapper::ParameterWrapper: sure about the indexes?" );
91 }
92
93
95 {
96 }
97
98
100
101 css::uno::Any ParameterWrapper::queryInterface(css::uno::Type const & aType)
102 {
103 css::uno::Any a(UnoBase::queryInterface(aType));
104 if (!a.hasValue()) {
106 if (!a.hasValue()
108 {
109 a <<= css::uno::Reference<css::lang::XTypeProvider>(this);
110 }
111 }
112 return a;
113 }
114
115
116 Sequence< Type > SAL_CALL ParameterWrapper::getTypes( )
117 {
118 return Sequence< Type > {
124 };
125 }
126
127
129
130
131 OUString ParameterWrapper::impl_getPseudoAggregatePropertyName( sal_Int32 _nHandle ) const
132 {
133 Reference< XPropertySetInfo > xInfo = const_cast<ParameterWrapper*>( this )->getPropertySetInfo();
134 const css::uno::Sequence<Property> aProperties = xInfo->getProperties();
135 for ( const Property& rProperty : aProperties )
136 {
137 if ( rProperty.Handle == _nHandle )
138 return rProperty.Name;
139 }
140
141 OSL_FAIL( "ParameterWrapper::impl_getPseudoAggregatePropertyName: invalid argument!" );
142 return OUString();
143 }
144
145
146 Reference< XPropertySetInfo > ParameterWrapper::getPropertySetInfo()
147 {
149 }
150
151
153 {
154 if (!m_pInfoHelper)
155 {
156 Sequence< Property > aProperties;
157 try
158 {
159 aProperties = m_xDelegatorPSI->getProperties();
160 sal_Int32 nProperties( aProperties.getLength() );
161 aProperties.realloc( nProperties + 1 );
162 aProperties.getArray()[ nProperties ] = Property(
163 "Value",
166 PropertyAttribute::TRANSIENT | PropertyAttribute::MAYBEVOID
167 );
168 }
169 catch( const Exception& )
170 {
171 DBG_UNHANDLED_EXCEPTION("connectivity.commontools");
172 }
173
174 m_pInfoHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties, false ) );
175 }
176 return *m_pInfoHelper;
177 }
178
179
180 sal_Bool ParameterWrapper::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
181 {
182 OSL_ENSURE( PROPERTY_ID_VALUE == nHandle, "ParameterWrapper::convertFastPropertyValue: the only non-readonly prop should be our PROPERTY_VALUE!" );
183
184 // we're lazy here ...
185 rOldValue = m_aValue.makeAny();
186 rConvertedValue = rValue;
187 return true; // assume "modified" ...
188 }
189
190
191 void ParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue )
192 {
193 if ( nHandle == PROPERTY_ID_VALUE )
194 {
195 try
196 {
197 // TODO : aParamType & nScale can be obtained within the constructor...
198 sal_Int32 nParamType = DataType::VARCHAR;
199 OSL_VERIFY( m_xDelegator->getPropertyValue("Type") >>= nParamType );
200
201 sal_Int32 nScale = 0;
202 if ( m_xDelegatorPSI->hasPropertyByName("Scale") )
203 OSL_VERIFY( m_xDelegator->getPropertyValue("Scale") >>= nScale );
204
205 if ( m_xValueDestination.is() )
206 {
207 for ( const auto& rIndex : m_aIndexes )
208 {
209 m_xValueDestination->setObjectWithInfo( rIndex + 1, rValue, nParamType, nScale );
210 // (the index of the parameters is one-based)
211 }
212 }
213
214 m_aValue = rValue;
215 }
216 catch( SQLException& e )
217 {
218 WrappedTargetException aExceptionWrapper;
219 aExceptionWrapper.Context = e.Context;
220 aExceptionWrapper.Message = e.Message;
221 aExceptionWrapper.TargetException <<= e;
222 throw aExceptionWrapper;
223 }
224 }
225 else
226 {
228 m_xDelegator->setPropertyValue( aName, rValue );
229 }
230 }
231
232
233 void ParameterWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
234 {
235 if ( nHandle == PROPERTY_ID_VALUE )
236 {
237 rValue = m_aValue.makeAny();
238 }
239 else
240 {
242 rValue = m_xDelegator->getPropertyValue( aName );
243 }
244 }
245
246
248 {
249 ::osl::MutexGuard aGuard( m_aMutex );
250
252 m_aIndexes.resize(0);
253 m_xDelegator.clear();
254 m_xDelegatorPSI.clear();
255 m_xValueDestination.clear();
256
257 m_aBHelper.bDisposed = true;
258 }
259
261 {
262 }
263
264
265 ParameterWrapperContainer::ParameterWrapperContainer( const Reference< XSingleSelectQueryAnalyzer >& _rxComposer )
266 {
267 Reference< XParametersSupplier > xSuppParams( _rxComposer, UNO_QUERY_THROW );
268 Reference< XIndexAccess > xParameters( xSuppParams->getParameters(), css::uno::UNO_SET_THROW );
269 sal_Int32 nParamCount( xParameters->getCount() );
270 m_aParameters.reserve( nParamCount );
271 for ( sal_Int32 i=0; i<nParamCount; ++i )
272 {
273 m_aParameters.push_back( new ParameterWrapper( Reference< XPropertySet >( xParameters->getByIndex( i ), UNO_QUERY_THROW ) ) );
274 }
275 }
276
277
279 {
280 }
281
282
284 {
285 std::unique_lock aGuard( m_aMutex );
288 }
289
290
292 {
293 std::unique_lock aGuard( m_aMutex );
295 return !m_aParameters.empty();
296 }
297
298
300 {
301 std::unique_lock aGuard( m_aMutex );
303 return m_aParameters.size();
304 }
305
306
307 Any SAL_CALL ParameterWrapperContainer::getByIndex( sal_Int32 _nIndex )
308 {
309 std::unique_lock aGuard( m_aMutex );
311
312 if ( ( _nIndex < 0 ) || ( o3tl::make_unsigned(_nIndex) >= m_aParameters.size() ) )
313 throw IndexOutOfBoundsException();
314
315 return Any( Reference< XPropertySet >( m_aParameters[ _nIndex ] ) );
316 }
317
318
320 {
321 std::unique_lock aGuard( m_aMutex );
323
324 return new ::comphelper::OEnumerationByIndex( static_cast< XIndexAccess* >( this ) );
325 }
326
327
329 {
330 if ( m_bDisposed )
331 throw DisposedException( OUString(), *this );
332 }
333
334
335 void ParameterWrapperContainer::disposing(std::unique_lock<std::mutex>& /*rGuard*/)
336 {
337 for (const auto& rxParam : m_aParameters)
338 {
339 rxParam->dispose();
340 }
341
343 }
344
345
346} // namespace
347
348
349/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
::cppu::OBroadcastHelper m_aBHelper
css::uno::Any makeAny() const
Definition: FValue.cxx:837
static css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL createPropertySetInfo(IPropertyArrayHelper &rProperties)
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) SAL_OVERRIDE
css::uno::Type const & get()
virtual void disposing(std::unique_lock< std::mutex > &rGuard) override
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
ParameterWrapperContainer()
creates an empty container
virtual sal_Bool SAL_CALL hasElements() override
virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 _rIndex) override
virtual sal_Int32 SAL_CALL getCount() override
virtual css::uno::Type SAL_CALL getElementType() override
wraps a parameter column as got from an SQLQueryComposer, so that it has an additional property "Valu...
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &rConvertedValue, css::uno::Any &rOldValue, sal_Int32 nHandle, const css::uno::Any &rValue) override
OUString impl_getPseudoAggregatePropertyName(sal_Int32 _nHandle) const
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual void SAL_CALL getFastPropertyValue(css::uno::Any &rValue, sal_Int32 nHandle) const override
::std::unique_ptr< ::cppu::OPropertyArrayHelper > m_pInfoHelper
helper for implementing XPropertySetInfo
::std::vector< sal_Int32 > m_aIndexes
the positions (in our m_xValueDestination) at which the value should be set (0-based!...
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
::connectivity::ORowSetValue m_aValue
the most recently set value of the parameter
css::uno::Reference< css::sdbc::XParameters > m_xValueDestination
the component taking the value
virtual ~ParameterWrapper() override
css::uno::Reference< css::beans::XPropertySetInfo > m_xDelegatorPSI
the property set info for our delegator
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
ParameterWrapper(const css::uno::Reference< css::beans::XPropertySet > &_rxColumn)
css::uno::Reference< css::beans::XPropertySet > m_xDelegator
the "delegator" column to which standard property requests are forwarded
virtual ::cppu::IPropertyArrayHelper &SAL_CALL getInfoHelper() override
#define DBG_UNHANDLED_EXCEPTION(...)
OUString aName
uno_Any a
const Reference< form::runtime::XFormController > m_xDelegator
@ Exception
Type
::std::vector< ::rtl::Reference< ParameterWrapper > > Parameters
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
DataType
IMPLEMENT_GET_IMPLEMENTATION_ID(DrawController)
#define PROPERTY_ID_VALUE
sal_Int32 nHandle
unsigned char sal_Bool
sal_Int32 nProperties
#define IMPLEMENT_FORWARD_REFCOUNT(classname, refcountbase)