Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "connectivity/parameters.hxx"
21 : :
22 : : #include <com/sun/star/form/DatabaseParameterEvent.hpp>
23 : : #include <com/sun/star/sdbc/XParameters.hpp>
24 : : #include <com/sun/star/container/XChild.hpp>
25 : : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
26 : : #include <com/sun/star/container/XEnumerationAccess.hpp>
27 : : #include <com/sun/star/sdb/XParametersSupplier.hpp>
28 : : #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
29 : : #include <com/sun/star/sdb/ParametersRequest.hpp>
30 : :
31 : : #include <connectivity/dbtools.hxx>
32 : : #include "connectivity/filtermanager.hxx"
33 : : #include "TConnection.hxx"
34 : :
35 : : #include <tools/debug.hxx>
36 : : #include <tools/diagnose_ex.h>
37 : :
38 : : #include <comphelper/uno3.hxx>
39 : : #include <comphelper/proparrhlp.hxx>
40 : : #include <comphelper/broadcasthelper.hxx>
41 : : #include "connectivity/ParameterCont.hxx"
42 : : #include <rtl/ustrbuf.hxx>
43 : :
44 : : //........................................................................
45 : : namespace dbtools
46 : : {
47 : : //........................................................................
48 : :
49 : : using namespace ::com::sun::star::uno;
50 : : using namespace ::com::sun::star::sdb;
51 : : using namespace ::com::sun::star::sdbc;
52 : : using namespace ::com::sun::star::sdbcx;
53 : : using namespace ::com::sun::star::lang;
54 : : using namespace ::com::sun::star::beans;
55 : : using namespace ::com::sun::star::task;
56 : : using namespace ::com::sun::star::form;
57 : : using namespace ::com::sun::star::container;
58 : :
59 : : using namespace ::comphelper;
60 : : using namespace ::connectivity;
61 : :
62 : : //====================================================================
63 : : //= ParameterManager
64 : : //====================================================================
65 : : //--------------------------------------------------------------------
66 : 278 : ParameterManager::ParameterManager( ::osl::Mutex& _rMutex, const Reference< XMultiServiceFactory >& _rxORB )
67 : : :m_rMutex ( _rMutex )
68 : : ,m_aParameterListeners( _rMutex )
69 : : ,m_xORB ( _rxORB )
70 : : ,m_pOuterParameters ( NULL )
71 : : ,m_nInnerCount ( 0 )
72 [ + - ][ + - ]: 278 : ,m_bUpToDate ( false )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
73 : : {
74 : : OSL_ENSURE( m_xORB.is(), "ParameterManager::ParameterManager: no service factory!" );
75 : 278 : }
76 : :
77 : : //--------------------------------------------------------------------
78 : 278 : void ParameterManager::initialize( const Reference< XPropertySet >& _rxComponent, const Reference< XAggregation >& _rxComponentAggregate )
79 : : {
80 : : OSL_ENSURE( !m_xComponent.get().is(), "ParameterManager::initialize: already initialized!" );
81 : :
82 : 278 : m_xComponent = _rxComponent;
83 : 278 : m_xAggregatedRowSet = _rxComponentAggregate;
84 [ + - ]: 278 : if ( m_xAggregatedRowSet.is() )
85 [ + - ]: 278 : m_xAggregatedRowSet->queryAggregation( ::getCppuType( &m_xInnerParamUpdate ) ) >>= m_xInnerParamUpdate;
86 : : OSL_ENSURE( m_xComponent.get().is() && m_xInnerParamUpdate.is(), "ParameterManager::initialize: invalid arguments!" );
87 [ + - ][ + - ]: 278 : if ( !m_xComponent.get().is() || !m_xInnerParamUpdate.is() )
[ - + ][ + - ]
[ - + # # ]
88 : 278 : return;
89 : : }
90 : :
91 : : //--------------------------------------------------------------------
92 : 274 : void ParameterManager::dispose( )
93 : : {
94 : 274 : clearAllParameterInformation();
95 : :
96 : 274 : m_xComposer.clear();
97 : 274 : m_xParentComposer.clear();
98 : : //m_xComponent.clear();
99 : 274 : m_xInnerParamUpdate.clear();
100 : 274 : m_xAggregatedRowSet.clear();
101 : 274 : }
102 : :
103 : : //--------------------------------------------------------------------
104 : 715 : void ParameterManager::clearAllParameterInformation()
105 : : {
106 : 715 : m_xInnerParamColumns.clear();
107 [ - + ]: 715 : if ( m_pOuterParameters.is() )
108 [ # # ]: 0 : m_pOuterParameters->dispose();
109 [ + - ]: 715 : m_pOuterParameters = NULL;
110 : 715 : m_nInnerCount = 0;
111 [ + - ]: 715 : ParameterInformation aEmptyInfo;
112 [ + - ]: 715 : m_aParameterInformation.swap( aEmptyInfo );
113 [ + - ]: 715 : m_aMasterFields.realloc( 0 );
114 [ + - ]: 715 : m_aDetailFields.realloc( 0 );
115 : 715 : m_sIdentifierQuoteString = ::rtl::OUString();
116 [ + - ]: 715 : ::std::vector< bool > aEmptyArray;
117 [ + - ]: 715 : m_aParametersVisited.swap( aEmptyArray );
118 : 715 : m_bUpToDate = false;
119 : 715 : }
120 : :
121 : : //--------------------------------------------------------------------
122 : 274 : void ParameterManager::disposing( const EventObject& /*_rDisposingEvent*/ )
123 : : {
124 : 274 : }
125 : :
126 : : //--------------------------------------------------------------------
127 : 0 : void ParameterManager::setAllParametersNull() SAL_THROW( ( SQLException, RuntimeException ) )
128 : : {
129 : : OSL_PRECOND( isAlive(), "ParameterManager::setAllParametersNull: not initialized, or already disposed!" );
130 [ # # ]: 0 : if ( !isAlive() )
131 : 0 : return;
132 : :
133 [ # # ]: 0 : for ( sal_Int32 i = 1; i <= m_nInnerCount; ++i )
134 : 0 : m_xInnerParamUpdate->setNull( i, DataType::VARCHAR );
135 : : }
136 : :
137 : : //--------------------------------------------------------------------
138 : 24 : bool ParameterManager::initializeComposerByComponent( const Reference< XPropertySet >& _rxComponent )
139 : : {
140 : : OSL_PRECOND( _rxComponent.is(), "ParameterManager::initializeComposerByComponent: invalid !" );
141 : :
142 : 24 : m_xComposer.clear();
143 : 24 : m_xInnerParamColumns.clear();
144 : 24 : m_nInnerCount = 0;
145 : :
146 : : // create and fill a composer
147 : : try
148 : : {
149 : : // get a query composer for the 's settings
150 [ + - ][ + - ]: 24 : m_xComposer.reset( getCurrentSettingsComposer( _rxComponent, m_xORB ), SharedQueryComposer::TakeOwnership );
151 : :
152 : : // see if the composer found parameters
153 [ + - ]: 24 : Reference< XParametersSupplier > xParamSupp( m_xComposer, UNO_QUERY );
154 [ + - ]: 24 : if ( xParamSupp.is() )
155 [ + - ][ + - ]: 24 : m_xInnerParamColumns = xParamSupp->getParameters();
[ + - ]
156 : :
157 [ + - ]: 24 : if ( m_xInnerParamColumns.is() )
158 [ + - ][ + - ]: 24 : m_nInnerCount = m_xInnerParamColumns->getCount();
[ # # ]
159 : : }
160 : 0 : catch( const SQLException& )
161 : : {
162 : : }
163 : :
164 : 24 : return m_xInnerParamColumns.is();
165 : : }
166 : :
167 : : //--------------------------------------------------------------------
168 : 24 : void ParameterManager::collectInnerParameters( bool _bSecondRun )
169 : : {
170 : : OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::collectInnerParameters: missing some internal data!" );
171 [ + - ]: 24 : if ( !m_xInnerParamColumns.is() )
172 : 24 : return;
173 : :
174 : : // strip previous index informations
175 [ - + ]: 24 : if ( _bSecondRun )
176 : : {
177 [ # # ]: 0 : for ( ParameterInformation::iterator aParamInfo = m_aParameterInformation.begin();
178 : 0 : aParamInfo != m_aParameterInformation.end();
179 : : ++aParamInfo
180 : : )
181 : : {
182 : 0 : aParamInfo->second.aInnerIndexes.clear();
183 : : }
184 : : }
185 : :
186 : : // we need to map the parameter names (which is all we get from the 's
187 : : // MasterFields property) to indicies, which are needed by the XParameters
188 : : // interface of the row set)
189 : 24 : Reference<XPropertySet> xParam;
190 [ - + ]: 24 : for ( sal_Int32 i = 0; i < m_nInnerCount; ++i )
191 : : {
192 : : try
193 : : {
194 : 0 : xParam.clear();
195 [ # # ][ # # ]: 0 : m_xInnerParamColumns->getByIndex( i ) >>= xParam;
[ # # ]
196 : :
197 : 0 : ::rtl::OUString sName;
198 [ # # ][ # # ]: 0 : xParam->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
[ # # ][ # # ]
199 : :
200 : : // only append additonal parameters when they are not already in the list
201 [ # # ]: 0 : ParameterInformation::iterator aExistentPos = m_aParameterInformation.find( sName );
202 : : OSL_ENSURE( !_bSecondRun || ( aExistentPos != m_aParameterInformation.end() ),
203 : : "ParameterManager::collectInnerParameters: the parameter information should already exist in the second run!" );
204 : :
205 [ # # ]: 0 : if ( aExistentPos == m_aParameterInformation.end() )
206 : : {
207 : : aExistentPos = m_aParameterInformation.insert( ParameterInformation::value_type(
208 [ # # ][ # # ]: 0 : sName, xParam ) ).first;
[ # # ]
209 : : }
210 : : else
211 [ # # ]: 0 : aExistentPos->second.xComposerColumn = xParam;
212 : :
213 [ # # ][ # # ]: 0 : aExistentPos->second.aInnerIndexes.push_back( i );
214 : : }
215 [ # # ]: 0 : catch( const Exception& )
216 : : {
217 : : OSL_FAIL( "ParameterManager::collectInnerParameters: caught an exception!" );
218 : : }
219 : 24 : }
220 : : }
221 : :
222 : : //--------------------------------------------------------------------
223 : 0 : ::rtl::OUString ParameterManager::createFilterConditionFromColumnLink(
224 : : const ::rtl::OUString& _rMasterColumn, const ::rtl::OUString& _rDetailLink, ::rtl::OUString& _rNewParamName )
225 : : {
226 : 0 : ::rtl::OUString sFilter;
227 : :
228 : : // format is:
229 : : // <detail_column> = :<new_param_name>
230 [ # # ]: 0 : sFilter = quoteName( m_sIdentifierQuoteString, _rDetailLink );
231 [ # # ]: 0 : sFilter += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( " = :" ));
232 : :
233 : : // generate a parameter name which is not already used
234 [ # # ]: 0 : _rNewParamName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "link_from_" ) );
235 [ # # ]: 0 : _rNewParamName += convertName2SQLName( _rMasterColumn, m_sSpecialCharacters );
236 [ # # ][ # # ]: 0 : while ( m_aParameterInformation.find( _rNewParamName ) != m_aParameterInformation.end() )
237 : : {
238 [ # # ]: 0 : _rNewParamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_" ) );
239 : : }
240 : :
241 : 0 : return sFilter += _rNewParamName;
242 : : }
243 : :
244 : : //--------------------------------------------------------------------
245 : 0 : void ParameterManager::classifyLinks( const Reference< XNameAccess >& _rxParentColumns,
246 : : const Reference< XNameAccess >& _rxColumns, ::std::vector< ::rtl::OUString >& _out_rAdditionalFilterComponents ) SAL_THROW(( Exception ))
247 : : {
248 : : OSL_PRECOND( m_aMasterFields.getLength() == m_aDetailFields.getLength(),
249 : : "ParameterManager::classifyLinks: master and detail fields should have the same length!" );
250 : : OSL_ENSURE( _rxColumns.is(), "ParameterManager::classifyLinks: invalid columns!" );
251 : :
252 [ # # ]: 0 : if ( !_rxColumns.is() )
253 : 0 : return;
254 : :
255 : : // we may need to strip any links which are invalid, so here go the containers
256 : : // for temporarirly holding the new pairs
257 [ # # ]: 0 : ::std::vector< ::rtl::OUString > aStrippedMasterFields;
258 [ # # ]: 0 : ::std::vector< ::rtl::OUString > aStrippedDetailFields;
259 : :
260 : 0 : bool bNeedExchangeLinks = false;
261 : :
262 : : // classify the links
263 : 0 : const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
264 : 0 : const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
265 : 0 : const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
266 [ # # ]: 0 : for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
267 : : {
268 [ # # ][ # # ]: 0 : if ( pMasterFields->isEmpty() || pDetailFields->isEmpty() )
[ # # ]
269 : 0 : continue;
270 : :
271 : : // if not even the master part of the relationship exists in the parent , the
272 : : // link is invalid as a whole
273 : : // #i63674# / 2006-03-28 / frank.schoenheit@sun.com
274 [ # # ][ # # ]: 0 : if ( !_rxParentColumns->hasByName( *pMasterFields ) )
[ # # ]
275 : : {
276 : 0 : bNeedExchangeLinks = true;
277 : 0 : continue;
278 : : }
279 : :
280 : 0 : bool bValidLink = true;
281 : :
282 : : // is there an inner parameter with this name? That is, a parameter which is already part of
283 : : // the very original statement (not the one we create ourselve, with the additional parameters)
284 [ # # ]: 0 : ParameterInformation::iterator aPos = m_aParameterInformation.find( *pDetailFields );
285 [ # # ]: 0 : if ( aPos != m_aParameterInformation.end() )
286 : : { // there is an inner parameter with this name
287 : 0 : aPos->second.eType = eLinkedByParamName;
288 [ # # ]: 0 : aStrippedDetailFields.push_back( *pDetailFields );
289 : : }
290 : : else
291 : : {
292 : : // does the detail name denote a column?
293 [ # # ][ # # ]: 0 : if ( _rxColumns->hasByName( *pDetailFields ) )
[ # # ]
294 : : {
295 : 0 : ::rtl::OUString sNewParamName;
296 [ # # ]: 0 : const ::rtl::OUString sFilterCondition = createFilterConditionFromColumnLink( *pMasterFields, *pDetailFields, sNewParamName );
297 : : OSL_PRECOND( !sNewParamName.isEmpty(), "ParameterManager::classifyLinks: createFilterConditionFromColumnLink returned nonsense!" );
298 : :
299 : : // remember meta information about this new parameter
300 : : ::std::pair< ParameterInformation::iterator, bool > aInsertionPos =
301 : : m_aParameterInformation.insert(
302 : : ParameterInformation::value_type( sNewParamName, ParameterMetaData( NULL ) )
303 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
[ # # ][ # # ]
304 : : OSL_ENSURE( aInsertionPos.second, "ParameterManager::classifyLinks: there already was a parameter with this name!" );
305 : 0 : aInsertionPos.first->second.eType = eLinkedByColumnName;
306 : :
307 : : // remember the filter component
308 [ # # ]: 0 : _out_rAdditionalFilterComponents.push_back( sFilterCondition );
309 : :
310 : : // remember the new "detail field" for this link
311 [ # # ]: 0 : aStrippedDetailFields.push_back( sNewParamName );
312 : 0 : bNeedExchangeLinks = true;
313 : : }
314 : : else
315 : : {
316 : : // the detail field neither denotes a column name, nor a parameter name
317 : 0 : bValidLink = false;
318 : 0 : bNeedExchangeLinks = true;
319 : : }
320 : : }
321 : :
322 [ # # ]: 0 : if ( bValidLink )
323 [ # # ]: 0 : aStrippedMasterFields.push_back( *pMasterFields );
324 : : }
325 : : OSL_POSTCOND( aStrippedMasterFields.size() == aStrippedDetailFields.size(),
326 : : "ParameterManager::classifyLinks: inconsistency in new link pairs!" );
327 : :
328 [ # # ]: 0 : if ( bNeedExchangeLinks )
329 : : {
330 [ # # ]: 0 : ::rtl::OUString *pFields = aStrippedMasterFields.empty() ? 0 : &aStrippedMasterFields[0];
331 [ # # ][ # # ]: 0 : m_aMasterFields = Sequence< ::rtl::OUString >( pFields, aStrippedMasterFields.size() );
[ # # ]
332 [ # # ]: 0 : pFields = aStrippedDetailFields.empty() ? 0 : &aStrippedDetailFields[0];
333 [ # # ][ # # ]: 0 : m_aDetailFields = Sequence< ::rtl::OUString >( pFields, aStrippedDetailFields.size() );
[ # # ]
334 : 0 : }
335 : : }
336 : :
337 : : //--------------------------------------------------------------------
338 : 24 : void ParameterManager::analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails )
339 : : {
340 : : OSL_PRECOND( isAlive(), "ParameterManager::analyzeFieldLinks: not initialized, or already disposed!" );
341 [ - + ]: 24 : if ( !isAlive() )
342 : 0 : return;
343 : :
344 : 24 : _rColumnsInLinkDetails = false;
345 : : try
346 : : {
347 : : // the links as determined by the properties
348 [ + - ]: 24 : Reference< XPropertySet > xProp = m_xComponent;
349 : : OSL_ENSURE(xProp.is(),"Some already released my component!");
350 [ + - ]: 24 : if ( xProp.is() )
351 : : {
352 [ + - ][ + - ]: 24 : xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MASTERFIELDS) ) >>= m_aMasterFields;
[ + - ][ + - ]
[ + - ]
353 [ + - ][ + - ]: 24 : xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DETAILFIELDS) ) >>= m_aDetailFields;
[ + - ][ + - ]
[ + - ]
354 : : }
355 : :
356 : : {
357 : : // normalize to equal length
358 : 24 : sal_Int32 nMasterLength = m_aMasterFields.getLength();
359 : 24 : sal_Int32 nDetailLength = m_aDetailFields.getLength();
360 : :
361 [ - + ]: 24 : if ( nMasterLength > nDetailLength )
362 [ # # ]: 0 : m_aMasterFields.realloc( nDetailLength );
363 [ - + ]: 24 : else if ( nDetailLength > nMasterLength )
364 [ # # ]: 0 : m_aDetailFields.realloc( nMasterLength );
365 : : }
366 : :
367 : 24 : Reference< XNameAccess > xColumns;
368 [ - + ][ + - ]: 24 : if ( !getColumns( xColumns, true ) )
369 : : // already asserted in getColumns
370 : : return;
371 : :
372 : 24 : Reference< XNameAccess > xParentColumns;
373 [ + - ][ + - ]: 24 : if ( !getParentColumns( xParentColumns, true ) )
374 : : return;
375 : :
376 : : // classify the links - depending on what the detail fields in each link pair denotes
377 [ # # ]: 0 : ::std::vector< ::rtl::OUString > aAdditionalFilterComponents;
378 [ # # ]: 0 : classifyLinks( xParentColumns, xColumns, aAdditionalFilterComponents );
379 : :
380 : : // did we find links where the detail field refers to a detail column (instead of a parameter name)?
381 [ # # ]: 0 : if ( !aAdditionalFilterComponents.empty() )
382 : : {
383 [ # # ][ # # ]: 0 : const static ::rtl::OUString s_sAnd( RTL_CONSTASCII_USTRINGPARAM( " AND " ) );
[ # # ][ # # ]
384 : : // build a conjunction of all the filter components
385 : 0 : ::rtl::OUStringBuffer sAdditionalFilter;
386 [ # # ][ # # ]: 0 : for ( ::std::vector< ::rtl::OUString >::const_iterator aComponent = aAdditionalFilterComponents.begin();
[ # # ]
387 : 0 : aComponent != aAdditionalFilterComponents.end();
388 : : ++aComponent
389 : : )
390 : : {
391 [ # # ]: 0 : if ( sAdditionalFilter.getLength() )
392 [ # # ]: 0 : sAdditionalFilter.append(s_sAnd);
393 : :
394 [ # # ]: 0 : sAdditionalFilter.appendAscii("( ",((sal_Int32)(sizeof("( ")-1)));
395 [ # # ]: 0 : sAdditionalFilter.append(*aComponent);
396 [ # # ]: 0 : sAdditionalFilter.appendAscii(" )",((sal_Int32)(sizeof(" )")-1)));
397 : : }
398 : :
399 : : // now set this filter at the 's filter manager
400 [ # # ][ # # ]: 0 : _rFilterManager.setFilterComponent( FilterManager::fcLinkFilter, sAdditionalFilter.makeStringAndClear() );
401 : :
402 : 0 : _rColumnsInLinkDetails = true;
403 [ + - ][ + - ]: 24 : }
[ - + ][ # # ]
404 : : }
405 : 0 : catch( const Exception& )
406 : : {
407 : : OSL_FAIL( "ParameterManager::analyzeFieldLinks: caught an exception!" );
408 : : }
409 : : }
410 : :
411 : : //--------------------------------------------------------------------
412 : 0 : void ParameterManager::createOuterParameters()
413 : : {
414 : : OSL_PRECOND( !m_pOuterParameters.is(), "ParameterManager::createOuterParameters: outer parameters not initialized!" );
415 : : OSL_PRECOND( m_xInnerParamUpdate.is(), "ParameterManager::createOuterParameters: no write access to the inner parameters!" );
416 [ # # ]: 0 : if ( !m_xInnerParamUpdate.is() )
417 : 0 : return;
418 : :
419 [ # # ][ # # ]: 0 : m_pOuterParameters = new param::ParameterWrapperContainer;
420 : :
421 : : #if OSL_DEBUG_LEVEL > 0
422 : : sal_Int32 nSmallestIndexLinkedByColumnName = -1;
423 : : sal_Int32 nLargestIndexNotLinkedByColumnName = -1;
424 : : #endif
425 : 0 : ::rtl::OUString sName;
426 [ # # ]: 0 : for ( ParameterInformation::iterator aParam = m_aParameterInformation.begin();
427 : 0 : aParam != m_aParameterInformation.end();
428 : : ++aParam
429 : : )
430 : : {
431 : : #if OSL_DEBUG_LEVEL > 0
432 : : if ( aParam->second.aInnerIndexes.size() )
433 : : {
434 : : if ( aParam->second.eType == eLinkedByColumnName )
435 : : {
436 : : if ( nSmallestIndexLinkedByColumnName == -1 )
437 : : nSmallestIndexLinkedByColumnName = aParam->second.aInnerIndexes[ 0 ];
438 : : }
439 : : else
440 : : {
441 : : nLargestIndexNotLinkedByColumnName = aParam->second.aInnerIndexes[ aParam->second.aInnerIndexes.size() - 1 ];
442 : : }
443 : : }
444 : : #endif
445 [ # # ]: 0 : if ( aParam->second.eType != eFilledExternally )
446 : 0 : continue;
447 : :
448 : : // check which of the parameters have already been visited (e.g. filled via XParameters)
449 : 0 : size_t nAlreadyVisited = 0;
450 [ # # # # ]: 0 : for ( ::std::vector< sal_Int32 >::iterator aIndex = aParam->second.aInnerIndexes.begin();
[ # # ]
451 : 0 : aIndex != aParam->second.aInnerIndexes.end();
452 : : ++aIndex
453 : : )
454 : : {
455 [ # # ][ # # ]: 0 : if ( ( m_aParametersVisited.size() > (size_t)*aIndex ) && m_aParametersVisited[ *aIndex ] )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
456 : : { // exclude this index
457 [ # # ]: 0 : *aIndex = -1;
458 : 0 : ++nAlreadyVisited;
459 : : }
460 : : }
461 [ # # ]: 0 : if ( nAlreadyVisited == aParam->second.aInnerIndexes.size() )
462 : 0 : continue;
463 : :
464 : : // need a wrapper for this .... the "inner parameters" as supplied by a result set don't have a "Value"
465 : : // property, but the parameter listeners expect such a property. So we need an object "aggregating"
466 : : // xParam and supplying an additional property ("Value")
467 : : // (it's no real aggregation of course ...)
468 [ # # ][ # # ]: 0 : m_pOuterParameters->push_back( new param::ParameterWrapper( aParam->second.xComposerColumn, m_xInnerParamUpdate, aParam->second.aInnerIndexes ) );
469 : 0 : }
470 : :
471 : : #if OSL_DEBUG_LEVEL > 0
472 : : OSL_ENSURE( ( nSmallestIndexLinkedByColumnName == -1 ) || ( nLargestIndexNotLinkedByColumnName == -1 ) ||
473 : : ( nSmallestIndexLinkedByColumnName > nLargestIndexNotLinkedByColumnName ),
474 : : "ParameterManager::createOuterParameters: inconsistency!" );
475 : :
476 : : // for the master-detail links, where the detail field denoted a column name, we created an addtional ("artificial")
477 : : // filter, and *appended* it to all other (potentially) existing filters of the row set. This means that the indexes
478 : : // for the parameters resulting from the artifical filter should be larger than any other parameter index, and this
479 : : // is what the assertion checks.
480 : : // If the assertion fails, then we would need another handling for the "parameters visited" flags, since they're based
481 : : // on parameter indexes *without* the artificial filter (because this filter is not visible from the outside).
482 : : #endif
483 : : }
484 : :
485 : : //--------------------------------------------------------------------
486 : 24 : void ParameterManager::updateParameterInfo( FilterManager& _rFilterManager )
487 : : {
488 : : OSL_PRECOND( isAlive(), "ParameterManager::updateParameterInfo: not initialized, or already disposed!" );
489 [ + - ][ + - ]: 24 : if ( !isAlive() )
490 : : return;
491 : :
492 [ + - ]: 24 : clearAllParameterInformation();
493 [ + - ]: 24 : cacheConnectionInfo();
494 : :
495 : : // check whether the is based on a statement/query which requires parameters
496 [ + - ]: 24 : Reference< XPropertySet > xProp = m_xComponent;
497 : : OSL_ENSURE(xProp.is(),"Some already released my component!");
498 [ + - ]: 24 : if ( xProp.is() )
499 : : {
500 [ + - ][ - + ]: 24 : if ( !initializeComposerByComponent( xProp ) )
501 : : { // okay, nothing to do
502 : 0 : m_bUpToDate = true;
503 : : return;
504 : : } // if ( !initializeComposerByComponent( m_xComponent ) )
505 : : }
506 : : OSL_POSTCOND( m_xInnerParamColumns.is(), "ParameterManager::updateParameterInfo: initializeComposerByComponent did nonsense (1)!" );
507 : :
508 : : // collect all parameters which are defined by the "inner parameters"
509 [ + - ]: 24 : collectInnerParameters( false );
510 : :
511 : : // analyze the master-detail relationships
512 : 24 : bool bColumnsInLinkDetails = false;
513 [ + - ]: 24 : analyzeFieldLinks( _rFilterManager, bColumnsInLinkDetails );
514 : :
515 [ - + ]: 24 : if ( bColumnsInLinkDetails )
516 : : {
517 : : // okay, in this case, analyzeFieldLinks modified the "real" filter at the RowSet, to contain
518 : : // an additional restriction (which we created ourself)
519 : : // So we need to update all information about our inner parameter columns
520 : 0 : Reference< XPropertySet > xDirectRowSetProps;
521 [ # # ][ # # ]: 0 : m_xAggregatedRowSet->queryAggregation( ::getCppuType( &xDirectRowSetProps ) ) >>= xDirectRowSetProps;
[ # # ][ # # ]
522 [ # # ]: 0 : OSL_VERIFY( initializeComposerByComponent( xDirectRowSetProps ) );
523 [ # # ]: 0 : collectInnerParameters( true );
524 : : }
525 : :
526 [ + - ]: 24 : if ( !m_nInnerCount )
527 : : { // no parameters at all
528 : 24 : m_bUpToDate = true;
529 : : return;
530 : : }
531 : :
532 : : // for what now remains as outer parameters, create the wrappers for the single
533 : : // parameter columns
534 [ # # ]: 0 : createOuterParameters();
535 : :
536 [ - + ]: 24 : m_bUpToDate = true;
537 : : }
538 : :
539 : : //--------------------------------------------------------------------
540 : 0 : void ParameterManager::fillLinkedParameters( const Reference< XNameAccess >& _rxParentColumns )
541 : : {
542 : : OSL_PRECOND( isAlive(), "ParameterManager::fillLinkedParameters: not initialized, or already disposed!" );
543 [ # # ]: 0 : if ( !isAlive() )
544 : 0 : return;
545 : : OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::fillLinkedParameters: no inner parameters found!" );
546 : : OSL_ENSURE ( _rxParentColumns.is(), "ParameterManager::fillLinkedParameters: invalid parent columns!" );
547 : :
548 : : try
549 : : {
550 : : // the master and detail field( name)s of the
551 : 0 : const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
552 : 0 : const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
553 : :
554 : 0 : sal_Int32 nMasterLen = m_aMasterFields.getLength();
555 : 0 : Any aParamType, aScale, aValue;
556 : :
557 : : // loop through all master fields. For each of them, get the respective column from the
558 : : // parent , and forward it's current value as paramter value to the (inner) row set
559 [ # # ]: 0 : for ( sal_Int32 i = 0; i < nMasterLen; ++i, ++pMasterFields, ++pDetailFields )
560 : : {
561 : : // does the name denote a valid column in the parent?
562 [ # # ][ # # ]: 0 : if ( !_rxParentColumns->hasByName( *pMasterFields ) )
[ # # ]
563 : : {
564 : : OSL_FAIL( "ParameterManager::fillLinkedParameters: invalid master names should have been stripped long before!" );
565 : 0 : continue;
566 : : }
567 : :
568 : : // do we, for this name, know where to place the values?
569 [ # # ]: 0 : ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
570 [ # # ][ # # ]: 0 : if ( ( aParamInfo == m_aParameterInformation.end() )
[ # # ]
[ # # # # ]
571 : 0 : || ( aParamInfo->second.aInnerIndexes.empty() )
572 : : )
573 : : {
574 : : OSL_FAIL( "ParameterManager::fillLinkedParameters: nothing known about this detail field!" );
575 : 0 : continue;
576 : : }
577 : :
578 : : // the concrete master field
579 [ # # ][ # # ]: 0 : Reference< XPropertySet > xMasterField(_rxParentColumns->getByName( *pMasterFields ),UNO_QUERY);
[ # # ]
580 : :
581 : : // the positions where we have to fill in values for the current parameter name
582 [ # # # # ]: 0 : for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
[ # # ]
583 : 0 : aPosition != aParamInfo->second.aInnerIndexes.end();
584 : : ++aPosition
585 : : )
586 : : {
587 : : // the concrete detail field
588 [ # # ][ # # ]: 0 : Reference< XPropertySet > xDetailField(m_xInnerParamColumns->getByIndex( *aPosition ),UNO_QUERY);
[ # # ][ # # ]
589 : : OSL_ENSURE( xDetailField.is(), "ParameterManager::fillLinkedParameters: invalid detail field!" );
590 [ # # ]: 0 : if ( !xDetailField.is() )
591 : 0 : continue;
592 : :
593 : : // type and scale of the parameter field
594 : 0 : sal_Int32 nParamType = DataType::VARCHAR;
595 [ # # ][ # # ]: 0 : OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE) ) >>= nParamType );
[ # # ][ # # ]
596 : :
597 : 0 : sal_Int32 nScale = 0;
598 [ # # ][ # # ]: 0 : if ( xDetailField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
599 [ # # ][ # # ]: 0 : OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) >>= nScale );
[ # # ][ # # ]
600 : :
601 : : // transfer the param value
602 : : try
603 : : {
604 [ # # ]: 0 : m_xInnerParamUpdate->setObjectWithInfo(
605 [ # # ]: 0 : *aPosition + 1, // parameters are based at 1
606 [ # # ][ # # ]: 0 : xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ),
607 : : nParamType,
608 : : nScale
609 [ # # ][ # # ]: 0 : );
[ # # ][ # # ]
610 : : }
611 [ # # ]: 0 : catch( const Exception& )
612 : : {
613 : : OSL_FAIL( ( ::rtl::OString( "ParameterManager::fillLinkedParameters: master-detail parameter number " )
614 : : += ::rtl::OString::valueOf( sal_Int32( *aPosition + 1 ) )
615 : : += ::rtl::OString( " could not be filled!" ) ).getStr() );
616 : : }
617 [ # # ]: 0 : }
618 [ # # ]: 0 : }
619 : : }
620 : 0 : catch( const Exception& )
621 : : {
622 : : DBG_UNHANDLED_EXCEPTION();
623 : : }
624 : : }
625 : :
626 : : //--------------------------------------------------------------------
627 : 0 : bool ParameterManager::completeParameters( const Reference< XInteractionHandler >& _rxCompletionHandler, const Reference< XConnection > _rxConnection )
628 : : {
629 : : OSL_PRECOND( isAlive(), "ParameterManager::completeParameters: not initialized, or already disposed!" );
630 : : OSL_ENSURE ( _rxCompletionHandler.is(), "ParameterManager::completeParameters: invalid interaction handler!" );
631 : :
632 : : // two continuations (Ok and Cancel)
633 [ # # ]: 0 : OInteractionAbort* pAbort = new OInteractionAbort;
634 [ # # ]: 0 : OParameterContinuation* pParams = new OParameterContinuation;
635 : :
636 : : // the request
637 [ # # ]: 0 : ParametersRequest aRequest;
638 [ # # ][ # # ]: 0 : aRequest.Parameters = m_pOuterParameters.get();
639 [ # # ]: 0 : aRequest.Connection = _rxConnection;
640 [ # # ][ # # ]: 0 : OInteractionRequest* pRequest = new OInteractionRequest( makeAny( aRequest ) );
641 [ # # ][ # # ]: 0 : Reference< XInteractionRequest > xRequest( pRequest );
642 : :
643 : : // some knittings
644 [ # # ][ # # ]: 0 : pRequest->addContinuation( pAbort );
[ # # ]
645 [ # # ][ # # ]: 0 : pRequest->addContinuation( pParams );
[ # # ][ # # ]
646 : :
647 : : // execute the request
648 : : try
649 : : {
650 [ # # ][ # # ]: 0 : _rxCompletionHandler->handle( xRequest );
651 : : }
652 [ # # ]: 0 : catch( const Exception& )
653 : : {
654 : : OSL_FAIL( "ParameterManager::completeParameters: caught an exception while calling the handler!" );
655 : : }
656 : :
657 [ # # ]: 0 : if ( !pParams->wasSelected() )
658 : : // canceled by the user (i.e. (s)he canceled the dialog)
659 : 0 : return false;
660 : :
661 : : try
662 : : {
663 : : // transfer the values from the continuation object to the parameter columns
664 [ # # ]: 0 : Sequence< PropertyValue > aFinalValues = pParams->getValues();
665 : 0 : const PropertyValue* pFinalValues = aFinalValues.getConstArray();
666 [ # # ]: 0 : for ( sal_Int32 i = 0; i < aFinalValues.getLength(); ++i, ++pFinalValues )
667 : : {
668 [ # # ][ # # ]: 0 : Reference< XPropertySet > xParamColumn(aRequest.Parameters->getByIndex( i ),UNO_QUERY);
[ # # ]
669 [ # # ]: 0 : if ( xParamColumn.is() )
670 : : {
671 : : #ifdef DBG_UTIL
672 : : ::rtl::OUString sName;
673 : : xParamColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
674 : : OSL_ENSURE( sName == pFinalValues->Name, "ParameterManager::completeParameters: inconsistent parameter names!" );
675 : : #endif
676 [ # # ][ # # ]: 0 : xParamColumn->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), pFinalValues->Value );
[ # # ][ # # ]
677 : : // the property sets are wrapper classes, translating the Value property into a call to
678 : : // the appropriate XParameters interface
679 : : }
680 [ # # ][ # # ]: 0 : }
681 : : }
682 [ # # ]: 0 : catch( const Exception& )
683 : : {
684 : : OSL_FAIL( "ParameterManager::completeParameters: caught an exception while propagating the values!" );
685 : : }
686 [ # # ]: 0 : return true;
687 : : }
688 : :
689 : : //--------------------------------------------------------------------
690 : 0 : bool ParameterManager::consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies )
691 : : {
692 : 0 : bool bCanceled = false;
693 : :
694 : 0 : sal_Int32 nParamsLeft = m_pOuterParameters->getParameters().size();
695 : : // TODO: shouldn't we subtract all the parameters which were already visited?
696 [ # # ]: 0 : if ( nParamsLeft )
697 : : {
698 [ # # ]: 0 : ::cppu::OInterfaceIteratorHelper aIter( m_aParameterListeners );
699 [ # # ]: 0 : Reference< XPropertySet > xProp = m_xComponent;
700 : : OSL_ENSURE(xProp.is(),"Some already released my component!");
701 [ # # ][ # # ]: 0 : DatabaseParameterEvent aEvent( xProp.get(), m_pOuterParameters.get() );
[ # # ][ # # ]
[ # # ]
702 : :
703 [ # # ]: 0 : _rClearForNotifies.clear();
704 [ # # ][ # # ]: 0 : while ( aIter.hasMoreElements() && !bCanceled )
[ # # ]
705 [ # # ][ # # ]: 0 : bCanceled = !static_cast< XDatabaseParameterListener* >( aIter.next() )->approveParameter( aEvent );
706 [ # # ][ # # ]: 0 : _rClearForNotifies.reset();
[ # # ]
707 : : }
708 : :
709 : 0 : return !bCanceled;
710 : : }
711 : :
712 : : //--------------------------------------------------------------------
713 : 24 : bool ParameterManager::fillParameterValues( const Reference< XInteractionHandler >& _rxCompletionHandler, ::osl::ResettableMutexGuard& _rClearForNotifies )
714 : : {
715 : : OSL_PRECOND( isAlive(), "ParameterManager::fillParameterValues: not initialized, or already disposed!" );
716 [ + - ][ - + ]: 24 : if ( !isAlive() )
717 : 0 : return true;
718 : :
719 [ + - ]: 24 : if ( m_nInnerCount == 0 )
720 : : // no parameters at all
721 : 24 : return true;
722 : :
723 : : // fill the parameters from the master-detail relationship
724 : 0 : Reference< XNameAccess > xParentColumns;
725 [ # # ][ # # ]: 0 : if ( getParentColumns( xParentColumns, false ) && xParentColumns->hasElements() && m_aMasterFields.getLength() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
726 [ # # ]: 0 : fillLinkedParameters( xParentColumns );
727 : :
728 : : // let the user (via the interaction handler) fill all remaining parameters
729 : 0 : Reference< XConnection > xConnection;
730 [ # # ]: 0 : getConnection( xConnection );
731 : :
732 [ # # ]: 0 : if ( _rxCompletionHandler.is() )
733 [ # # ]: 0 : return completeParameters( _rxCompletionHandler, xConnection );
734 : :
735 [ # # ]: 24 : return consultParameterListeners( _rClearForNotifies );
736 : : }
737 : :
738 : : //--------------------------------------------------------------------
739 : 24 : bool ParameterManager::getConnection( Reference< XConnection >& /* [out] */ _rxConnection )
740 : : {
741 : : OSL_PRECOND( isAlive(), "ParameterManager::getConnection: not initialized, or already disposed!" );
742 [ - + ]: 24 : if ( !isAlive() )
743 : 0 : return false;
744 : :
745 : 24 : _rxConnection.clear();
746 : : try
747 : : {
748 [ + - ]: 24 : Reference< XPropertySet > xProp = m_xComponent;
749 : : OSL_ENSURE(xProp.is(),"Some already released my component!");
750 [ + - ]: 24 : if ( xProp.is() )
751 [ + - ][ + - ]: 24 : xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ACTIVE_CONNECTION) ) >>= _rxConnection;
[ + - ][ + - ]
[ + - ][ # # ]
752 : : }
753 : 0 : catch( const Exception& )
754 : : {
755 : : OSL_FAIL( "ParameterManager::getConnection: could not retrieve the connection of the !" );
756 : : }
757 : 24 : return _rxConnection.is();
758 : : }
759 : :
760 : : //--------------------------------------------------------------------
761 : 24 : void ParameterManager::cacheConnectionInfo() SAL_THROW(( ))
762 : : {
763 : : try
764 : : {
765 : 24 : Reference< XConnection > xConnection;
766 [ + - ]: 24 : getConnection( xConnection );
767 : 24 : Reference< XDatabaseMetaData > xMeta;
768 [ + - ]: 24 : if ( xConnection.is() )
769 [ + - ][ + - ]: 24 : xMeta = xConnection->getMetaData();
[ + - ]
770 [ + - ]: 24 : if ( xMeta.is() )
771 : : {
772 [ + - ][ + - ]: 24 : m_sIdentifierQuoteString = xMeta->getIdentifierQuoteString();
773 [ + - ][ + - ]: 24 : m_sSpecialCharacters = xMeta->getExtraNameCharacters();
774 [ # # ]: 24 : }
775 : : }
776 : 0 : catch( const Exception& )
777 : : {
778 : : OSL_FAIL( "ParameterManager::cacheConnectionInfo: caught an exception!" );
779 : : }
780 : 24 : }
781 : :
782 : : //--------------------------------------------------------------------
783 : 24 : bool ParameterManager::getColumns( Reference< XNameAccess >& /* [out] */ _rxColumns, bool _bFromComposer ) SAL_THROW(( Exception ))
784 : : {
785 : 24 : _rxColumns.clear();
786 : :
787 : 24 : Reference< XColumnsSupplier > xColumnSupp;
788 [ + - ]: 24 : if ( _bFromComposer )
789 [ + - ][ + - ]: 24 : xColumnSupp = xColumnSupp.query( m_xComposer );
790 : : else
791 [ # # ][ # # ]: 0 : xColumnSupp.set( m_xComponent.get(),UNO_QUERY);
792 [ + - ]: 24 : if ( xColumnSupp.is() )
793 [ + - ][ + - ]: 24 : _rxColumns = xColumnSupp->getColumns();
[ + - ]
794 : : OSL_ENSURE( _rxColumns.is(), "ParameterManager::getColumns: could not retrieve the columns for the detail !" );
795 : :
796 : 24 : return _rxColumns.is();
797 : : }
798 : :
799 : : //--------------------------------------------------------------------
800 : 24 : bool ParameterManager::getParentColumns( Reference< XNameAccess >& /* [out] */ _out_rxParentColumns, bool _bFromComposer )
801 : : {
802 : : OSL_PRECOND( isAlive(), "ParameterManager::getParentColumns: not initialized, or already disposed!" );
803 : :
804 : 24 : _out_rxParentColumns.clear();
805 : : try
806 : : {
807 : : // get the parent of the component we're working for
808 [ + - ][ + - ]: 24 : Reference< XChild > xAsChild( m_xComponent.get(), UNO_QUERY_THROW );
809 [ + - ][ + - ]: 24 : Reference< XPropertySet > xParent( xAsChild->getParent(), UNO_QUERY );
[ + - ]
810 [ + - ]: 24 : if ( !xParent.is() )
811 : 24 : return false;
812 : :
813 : : // the columns supplier: either from a composer, or directly from the
814 : 0 : Reference< XColumnsSupplier > xParentColSupp;
815 [ # # ]: 0 : if ( _bFromComposer )
816 : : {
817 : : // re-create the parent composer all the time. Else, we'd have to bother with
818 : : // being a listener at its properties, its loaded state, and event the parent-relationship.
819 : : m_xParentComposer.reset(
820 : : getCurrentSettingsComposer( xParent, m_xORB ),
821 : : SharedQueryComposer::TakeOwnership
822 [ # # ][ # # ]: 0 : );
823 [ # # ][ # # ]: 0 : xParentColSupp = xParentColSupp.query( m_xParentComposer );
824 : : }
825 : : else
826 [ # # ][ # # ]: 0 : xParentColSupp = xParentColSupp.query( xParent );
827 : :
828 : : // get the columns of the parent
829 [ # # ]: 0 : if ( xParentColSupp.is() )
830 [ # # ][ # # ]: 24 : _out_rxParentColumns = xParentColSupp->getColumns();
[ # # ][ + - ]
[ - + ][ # # ]
831 : : }
832 : 0 : catch( const Exception& )
833 : : {
834 : : OSL_FAIL( "ParameterManager::getParentColumns: caught an exception!" );
835 : : }
836 : 24 : return _out_rxParentColumns.is();
837 : : }
838 : :
839 : : //--------------------------------------------------------------------
840 : 22 : void ParameterManager::addParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
841 : : {
842 [ + - ]: 22 : if ( _rxListener.is() )
843 : 22 : m_aParameterListeners.addInterface( _rxListener );
844 : 22 : }
845 : :
846 : : //--------------------------------------------------------------------
847 : 19 : void ParameterManager::removeParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
848 : : {
849 : 19 : m_aParameterListeners.removeInterface( _rxListener );
850 : 19 : }
851 : :
852 : : //--------------------------------------------------------------------
853 : 0 : void ParameterManager::resetParameterValues( ) SAL_THROW(())
854 : : {
855 : : OSL_PRECOND( isAlive(), "ParameterManager::resetParameterValues: not initialized, or already disposed!" );
856 [ # # ]: 0 : if ( !isAlive() )
857 : 0 : return;
858 : :
859 [ # # ]: 0 : if ( !m_nInnerCount )
860 : : // no parameters at all
861 : 0 : return;
862 : :
863 : : try
864 : : {
865 : 0 : Reference< XNameAccess > xColumns;
866 [ # # ][ # # ]: 0 : if ( !getColumns( xColumns, false ) )
867 : : // already asserted in getColumns
868 : : return;
869 : :
870 : 0 : Reference< XNameAccess > xParentColumns;
871 [ # # ][ # # ]: 0 : if ( !getParentColumns( xParentColumns, false ) )
872 : : return;
873 : :
874 : : // loop through all links pairs
875 : 0 : const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
876 : 0 : const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
877 : :
878 : 0 : Reference< XPropertySet > xMasterField;
879 : 0 : Reference< XPropertySet > xDetailField;
880 : :
881 : : // now really ....
882 : 0 : const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
883 [ # # ]: 0 : for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
884 : : {
885 [ # # ][ # # ]: 0 : if ( !xParentColumns->hasByName( *pMasterFields ) )
[ # # ]
886 : : {
887 : : // if this name is unknown in the parent columns, then we don't have a source
888 : : // for copying the value to the detail columns
889 : : OSL_FAIL( "ParameterManager::resetParameterValues: this should have been stripped long before!" );
890 : 0 : continue;
891 : : }
892 : :
893 : : // for all inner parameters which are bound to the name as specified by the
894 : : // slave element of the link, propagate the value from the master column to this
895 : : // parameter column
896 [ # # ]: 0 : ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
897 [ # # ][ # # ]: 0 : if ( ( aParamInfo == m_aParameterInformation.end() )
[ # # ]
[ # # # # ]
898 : 0 : || ( aParamInfo->second.aInnerIndexes.empty() )
899 : : )
900 : : {
901 : : OSL_FAIL( "ParameterManager::resetParameterValues: nothing known about this detail field!" );
902 : 0 : continue;
903 : : }
904 : :
905 [ # # ][ # # ]: 0 : xParentColumns->getByName( *pMasterFields ) >>= xMasterField;
[ # # ]
906 [ # # ]: 0 : if ( !xMasterField.is() )
907 : 0 : continue;
908 : :
909 [ # # # # ]: 0 : for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
[ # # ]
910 : 0 : aPosition != aParamInfo->second.aInnerIndexes.end();
911 : : ++aPosition
912 : : )
913 : : {
914 : 0 : Reference< XPropertySet > xInnerParameter;
915 [ # # ][ # # ]: 0 : m_xInnerParamColumns->getByIndex( *aPosition ) >>= xInnerParameter;
[ # # ][ # # ]
916 [ # # ]: 0 : if ( !xInnerParameter.is() )
917 : 0 : continue;
918 : :
919 : 0 : ::rtl::OUString sParamColumnRealName;
920 [ # # ][ # # ]: 0 : xInnerParameter->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME) ) >>= sParamColumnRealName;
[ # # ][ # # ]
921 [ # # ][ # # ]: 0 : if ( xColumns->hasByName( sParamColumnRealName ) )
[ # # ]
922 : : { // our own columns have a column which's name equals the real name of the param column
923 : : // -> transfer the value property
924 [ # # ][ # # ]: 0 : xColumns->getByName( sParamColumnRealName ) >>= xDetailField;
[ # # ]
925 [ # # ]: 0 : if ( xDetailField.is() )
926 [ # # ][ # # ]: 0 : xDetailField->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
927 : : }
928 [ # # ]: 0 : }
929 [ # # ][ # # ]: 0 : }
[ # # ]
930 : : }
931 : 0 : catch( const Exception& )
932 : : {
933 : : OSL_FAIL( "ParameterManager::resetParameterValues: caught an exception!" );
934 : : }
935 : :
936 : : }
937 : :
938 : : //--------------------------------------------------------------------
939 : 0 : void ParameterManager::externalParameterVisited( sal_Int32 _nIndex )
940 : : {
941 [ # # ]: 0 : if ( m_aParametersVisited.size() < (size_t)_nIndex )
942 : : {
943 : 0 : m_aParametersVisited.reserve( _nIndex );
944 [ # # ]: 0 : for ( sal_Int32 i = m_aParametersVisited.size(); i < _nIndex; ++i )
945 : 0 : m_aParametersVisited.push_back( false );
946 : : }
947 : 0 : m_aParametersVisited[ _nIndex - 1 ] = true;
948 : 0 : }
949 : :
950 : : #define VISIT_PARAMETER( method ) \
951 : : ::osl::MutexGuard aGuard( m_rMutex ); \
952 : : OSL_ENSURE( m_xInnerParamUpdate.is(), "ParameterManager::XParameters::setXXX: no XParameters access to the RowSet!" ); \
953 : : if ( !m_xInnerParamUpdate.is() ) \
954 : : return; \
955 : : m_xInnerParamUpdate->method; \
956 : : externalParameterVisited( _nIndex ) \
957 : :
958 : : //--------------------------------------------------------------------
959 : 0 : void ParameterManager::setNull( sal_Int32 _nIndex, sal_Int32 sqlType )
960 : : {
961 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setNull( _nIndex, sqlType ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
962 : : }
963 : :
964 : : //--------------------------------------------------------------------
965 : 0 : void ParameterManager::setObjectNull( sal_Int32 _nIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName )
966 : : {
967 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setObjectNull( _nIndex, sqlType, typeName ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
968 : : }
969 : :
970 : : //--------------------------------------------------------------------
971 : 0 : void ParameterManager::setBoolean( sal_Int32 _nIndex, sal_Bool x )
972 : : {
973 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setBoolean( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
974 : : }
975 : :
976 : : //--------------------------------------------------------------------
977 : 0 : void ParameterManager::setByte( sal_Int32 _nIndex, sal_Int8 x )
978 : : {
979 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setByte( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
980 : : }
981 : :
982 : : //--------------------------------------------------------------------
983 : 0 : void ParameterManager::setShort( sal_Int32 _nIndex, sal_Int16 x )
984 : : {
985 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setShort( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
986 : : }
987 : :
988 : : //--------------------------------------------------------------------
989 : 0 : void ParameterManager::setInt( sal_Int32 _nIndex, sal_Int32 x )
990 : : {
991 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setInt( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
992 : : }
993 : :
994 : : //--------------------------------------------------------------------
995 : 0 : void ParameterManager::setLong( sal_Int32 _nIndex, sal_Int64 x )
996 : : {
997 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setLong( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
998 : : }
999 : :
1000 : : //--------------------------------------------------------------------
1001 : 0 : void ParameterManager::setFloat( sal_Int32 _nIndex, float x )
1002 : : {
1003 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setFloat( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1004 : : }
1005 : :
1006 : : //--------------------------------------------------------------------
1007 : 0 : void ParameterManager::setDouble( sal_Int32 _nIndex, double x )
1008 : : {
1009 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setDouble( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1010 : : }
1011 : :
1012 : : //--------------------------------------------------------------------
1013 : 0 : void ParameterManager::setString( sal_Int32 _nIndex, const ::rtl::OUString& x )
1014 : : {
1015 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setString( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1016 : : }
1017 : :
1018 : : //--------------------------------------------------------------------
1019 : 0 : void ParameterManager::setBytes( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x )
1020 : : {
1021 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setBytes( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1022 : : }
1023 : :
1024 : : //--------------------------------------------------------------------
1025 : 0 : void ParameterManager::setDate( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x )
1026 : : {
1027 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setDate( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1028 : : }
1029 : :
1030 : : //--------------------------------------------------------------------
1031 : 0 : void ParameterManager::setTime( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x )
1032 : : {
1033 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setTime( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1034 : : }
1035 : :
1036 : : //--------------------------------------------------------------------
1037 : 0 : void ParameterManager::setTimestamp( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x )
1038 : : {
1039 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setTimestamp( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1040 : : }
1041 : :
1042 : : //--------------------------------------------------------------------
1043 : 0 : void ParameterManager::setBinaryStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
1044 : : {
1045 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setBinaryStream( _nIndex, x, length ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1046 : : }
1047 : :
1048 : : //--------------------------------------------------------------------
1049 : 0 : void ParameterManager::setCharacterStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
1050 : : {
1051 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setCharacterStream( _nIndex, x, length ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1052 : : }
1053 : :
1054 : : //--------------------------------------------------------------------
1055 : 0 : void ParameterManager::setObject( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x )
1056 : : {
1057 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setObject( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1058 : : }
1059 : :
1060 : : //--------------------------------------------------------------------
1061 : 0 : void ParameterManager::setObjectWithInfo( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale )
1062 : : {
1063 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setObjectWithInfo( _nIndex, x, targetSqlType, scale ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1064 : : }
1065 : :
1066 : : //--------------------------------------------------------------------
1067 : 0 : void ParameterManager::setRef( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x )
1068 : : {
1069 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setRef( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1070 : : }
1071 : :
1072 : : //--------------------------------------------------------------------
1073 : 0 : void ParameterManager::setBlob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x )
1074 : : {
1075 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setBlob( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1076 : : }
1077 : :
1078 : : //--------------------------------------------------------------------
1079 : 0 : void ParameterManager::setClob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x )
1080 : : {
1081 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setClob( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1082 : : }
1083 : :
1084 : : //--------------------------------------------------------------------
1085 : 0 : void ParameterManager::setArray( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x )
1086 : : {
1087 [ # # ][ # # ]: 0 : VISIT_PARAMETER( setArray( _nIndex, x ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1088 : : }
1089 : :
1090 : : //--------------------------------------------------------------------
1091 : 0 : void ParameterManager::clearParameters( )
1092 : : {
1093 [ # # ]: 0 : if ( m_xInnerParamUpdate.is() )
1094 : 0 : m_xInnerParamUpdate->clearParameters( );
1095 : 0 : }
1096 : :
1097 : : //====================================================================
1098 : : //= OParameterContinuation
1099 : : //====================================================================
1100 : : //--------------------------------------------------------------------
1101 : 2 : void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw( RuntimeException )
1102 : : {
1103 : 2 : m_aValues = _rValues;
1104 : 2 : }
1105 : :
1106 : : //........................................................................
1107 : : } // namespace frm
1108 : : //........................................................................
1109 : :
1110 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|