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 : : #ifndef CONNECTIVITY_PARAMETERS_HXX
20 : : #define CONNECTIVITY_PARAMETERS_HXX
21 : :
22 : : #include <map>
23 : : #include <vector>
24 : :
25 : : #include <com/sun/star/uno/XAggregation.hpp>
26 : : #include <com/sun/star/form/XDatabaseParameterListener.hpp>
27 : : #include <com/sun/star/sdbc/XConnection.hpp>
28 : : #include <com/sun/star/task/XInteractionHandler.hpp>
29 : : #include <com/sun/star/sdbc/XParameters.hpp>
30 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 : : #include <com/sun/star/container/XIndexAccess.hpp>
32 : : #include <com/sun/star/beans/XPropertySet.hpp>
33 : : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
34 : :
35 : : #include "connectivity/dbtoolsdllapi.hxx"
36 : : #include "connectivity/paramwrapper.hxx"
37 : : #include <unotools/sharedunocomponent.hxx>
38 : : #include <comphelper/implementationreference.hxx>
39 : : #include <cppuhelper/interfacecontainer.hxx>
40 : :
41 : : //........................................................................
42 : : namespace dbtools
43 : : {
44 : : //........................................................................
45 : :
46 : : typedef ::utl::SharedUNOComponent< ::com::sun::star::sdb::XSingleSelectQueryComposer, ::utl::DisposableComponent >
47 : : SharedQueryComposer;
48 : :
49 : : //====================================================================
50 : : //= ParameterManager
51 : : //====================================================================
52 : : class FilterManager;
53 [ + - ][ + - ]: 271 : class OOO_DLLPUBLIC_DBTOOLS ParameterManager
[ + - ][ + - ]
[ + - ]
54 : : {
55 : : public:
56 : : /// classifies the origin of the data to fill a parameter
57 : : enum ParameterClassification
58 : : {
59 : : /** parameters which are filled from the master-detail relationship, where the detail
60 : : name is an explicit parameter name
61 : : */
62 : : eLinkedByParamName,
63 : : /** parameters which are filled from the master-detail relationship, where the detail
64 : : name is a column name, so an implicit parameter had to be generated for it
65 : : */
66 : : eLinkedByColumnName,
67 : : /** parameters which are filled externally (i.e. by XParamaters::setXXX, or by the parameter listeners)
68 : : */
69 : : eFilledExternally
70 : : };
71 : : /** meta data about an inner parameter
72 : : */
73 : : private:
74 [ # # ]: 0 : struct ParameterMetaData
75 : : {
76 : : /// the type of the parameter
77 : : ParameterClassification eType;
78 : : /// the column object for this parameter, as returned by the query composer
79 : : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
80 : : xComposerColumn;
81 : : /// the indicies of inner parameters which need to be filled when this concrete parameter is set
82 : : ::std::vector< sal_Int32 > aInnerIndexes;
83 : :
84 : : /// default ctor
85 : : ParameterMetaData()
86 : : :eType( eFilledExternally )
87 : : {
88 : : }
89 : :
90 : : /// ctor with composer column
91 : 0 : ParameterMetaData( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxColumn )
92 : : :eType ( eFilledExternally )
93 [ # # ]: 0 : ,xComposerColumn ( _rxColumn )
94 : : {
95 : 0 : }
96 : : };
97 : :
98 : : typedef ::std::map< ::rtl::OUString, ParameterMetaData > ParameterInformation;
99 : :
100 : : private:
101 : : ::osl::Mutex& m_rMutex;
102 : : ::cppu::OInterfaceContainerHelper m_aParameterListeners;
103 : :
104 : : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
105 : : m_xORB;
106 : :
107 : : ::com::sun::star::uno::WeakReference< ::com::sun::star::beans::XPropertySet >
108 : : m_xComponent; // the database component whose parameters we're handling
109 : : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >
110 : : m_xAggregatedRowSet; // the aggregated row set - necessary for unwrapped access to some interfaces
111 : : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XParameters >
112 : : m_xInnerParamUpdate; // write access to the inner parameters
113 : : SharedQueryComposer m_xComposer; // query composer wrapping the statement which the *aggregate* is based on
114 : : SharedQueryComposer m_xParentComposer; // query composer wrapping the statement of our parent database component
115 : : ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >
116 : : m_xInnerParamColumns; // index access to the parameter columns, as got from the query composer
117 : :
118 : : ::dbtools::param::ParametersContainerRef
119 : : m_pOuterParameters; // the container of parameters which still need to be filled in by
120 : : // external instances
121 : : sal_Int32 m_nInnerCount; // overall number of parameters as required by the database component's aggregate
122 : :
123 : : ParameterInformation m_aParameterInformation;
124 : :
125 : : ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aMasterFields;
126 : : ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aDetailFields;
127 : :
128 : : ::rtl::OUString m_sIdentifierQuoteString;
129 : : ::rtl::OUString m_sSpecialCharacters;
130 : :
131 : : ::std::vector< bool > m_aParametersVisited;
132 : :
133 : : bool m_bUpToDate;
134 : :
135 : : public:
136 : : /** ctor
137 : : */
138 : : explicit ParameterManager(
139 : : ::osl::Mutex& _rMutex,
140 : : const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
141 : : );
142 : :
143 : : /// late ctor
144 : : void initialize(
145 : : const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxComponent,
146 : : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >& _rxComponentAggregate
147 : : );
148 : :
149 : : /// makes the object forgetting the references to the database component
150 : : void dispose( );
151 : :
152 : : /// clears the instance data
153 : : void clearAllParameterInformation();
154 : :
155 : : /// checks whether the parameter information are up-to-date
156 : 48 : inline bool isUpToDate() const { return m_bUpToDate; }
157 : :
158 : : /** updates all parameter information represented by the instance
159 : : */
160 : : void updateParameterInfo( FilterManager& _rFilterManager );
161 : :
162 : : /** fills parameter values, as extensive as possible
163 : :
164 : : <p>In particular, all values which can be filled from the master-detail relationship of
165 : : between our database component and it's parent are filled in.</p>
166 : :
167 : : @param _rxCompletionHandler
168 : : an interaction handler which should be used to fill all parameters which
169 : : cannot be filled by other means. May be <NULL/>
170 : : @param _rClearForNotifies
171 : : the mutex guard to be (temporarily) cleared for notifications
172 : :
173 : : @precond
174 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
175 : :
176 : : @return
177 : : <TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
178 : : */
179 : : bool fillParameterValues(
180 : : const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler,
181 : : ::osl::ResettableMutexGuard& _rClearForNotifies
182 : : );
183 : :
184 : : /** sets all parameter values to null (via <member>XParameters::setNull</member>)
185 : :
186 : : @precond
187 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
188 : : */
189 : : void setAllParametersNull() SAL_THROW( ( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException ) );
190 : :
191 : : /** resets all detail columns which are, via a parameter, linked to a master column, to
192 : : the value of this master column.
193 : :
194 : : For instance, if the database component is bound to a statement <code>SELECT * from invoice where inv_id = :cid</code>,
195 : : and there is <em>one</em> master-detail link from
196 : :
197 : : @precond
198 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
199 : : */
200 : : void resetParameterValues() SAL_THROW(());
201 : :
202 : : /** tells the object that it's database component is being disposed
203 : :
204 : : The object then fires the <member>XEventListener::disposing</member> notification to
205 : : the parameter listeners
206 : : */
207 : : void disposing( const ::com::sun::star::lang::EventObject& _rDisposingEvent );
208 : :
209 : : /** adds the given listener to the list of parameter listeners
210 : : */
211 : : void addParameterListener(
212 : : const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& _rxListener
213 : : );
214 : :
215 : : /** removes the given listener from the list of parameter listeners
216 : : */
217 : : void removeParameterListener(
218 : : const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& _rxListener
219 : : );
220 : :
221 : : // XParameters equivalents
222 : : void setNull ( sal_Int32 _nIndex, sal_Int32 sqlType);
223 : : void setObjectNull ( sal_Int32 _nIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName);
224 : : void setBoolean ( sal_Int32 _nIndex, sal_Bool x);
225 : : void setByte ( sal_Int32 _nIndex, sal_Int8 x);
226 : : void setShort ( sal_Int32 _nIndex, sal_Int16 x);
227 : : void setInt ( sal_Int32 _nIndex, sal_Int32 x);
228 : : void setLong ( sal_Int32 _nIndex, sal_Int64 x);
229 : : void setFloat ( sal_Int32 _nIndex, float x);
230 : : void setDouble ( sal_Int32 _nIndex, double x);
231 : : void setString ( sal_Int32 _nIndex, const ::rtl::OUString& x);
232 : : void setBytes ( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x);
233 : : void setDate ( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x);
234 : : void setTime ( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x);
235 : : void setTimestamp ( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x);
236 : : void setBinaryStream ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length);
237 : : void setCharacterStream ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length);
238 : : void setObject ( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x);
239 : : void setObjectWithInfo ( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale);
240 : : void setRef ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x);
241 : : void setBlob ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x);
242 : : void setClob ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x);
243 : : void setArray ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x);
244 : : void clearParameters();
245 : :
246 : : private:
247 : : /// checkes whether the object is already initialized, and not yet disposed
248 [ + - ][ + - ]: 96 : inline bool isAlive() const { return m_xComponent.get().is() && m_xInnerParamUpdate.is(); }
[ + - ][ + - ]
[ # # ]
249 : :
250 : : /** creates a filter expression from a master-detail link where the detail denotes a column name
251 : : */
252 : : ::rtl::OUString
253 : : createFilterConditionFromColumnLink(
254 : : const ::rtl::OUString& /* [in] */ _rMasterColumn,
255 : : const ::rtl::OUString& /* [in] */ _rDetailColumn,
256 : : ::rtl::OUString& /* [out] */ _rNewParamName
257 : : );
258 : :
259 : : /** initializes our query composer, and the collection of inner parameter columns
260 : :
261 : : @param _rxComponent
262 : : the database component to initialize from. Must not be <NULL/>
263 : : @return
264 : : <TRUE/> if and only if the initialization was successfull
265 : :
266 : : @postcond
267 : : if and only if <TRUE/> is returned, then <member>m_xInnerParamColumns</member> contains the collection of
268 : : inner parameters
269 : : */
270 : : bool initializeComposerByComponent(
271 : : const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxComponent
272 : : );
273 : :
274 : : /** collects initial meta information about inner parameters (i.e. it initially fills
275 : : <member>m_aParameterInformation</member>).
276 : :
277 : : @param _bSecondRun
278 : : if <TRUE/>, this is the second run, because we ourself previously extended the filter of
279 : : the RowSet
280 : :
281 : : @precond
282 : : <member>m_xInnerParamColumns</member> is not <NULL/>
283 : : */
284 : : void collectInnerParameters( bool _bSecondRun );
285 : :
286 : : /** analyzes the master-detail links for our database component, and initializes m_aMasterFields and m_aDetailFields
287 : :
288 : : @param _rFilterManager
289 : : the filter manager of the database component
290 : : @param _rColumnsInLinkDetails
291 : : will be set to <TRUE/> if and only if there were link pairs where the detail field denoted
292 : : a column name of our database component
293 : :
294 : : @precond
295 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
296 : : */
297 : : void analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails );
298 : :
299 : : /** classifies the link pairs
300 : :
301 : : @param _rxParentColumns
302 : : the columns of the parent database component
303 : :
304 : : @param _rxColumns
305 : : the columns of our own database component
306 : :
307 : : @param _out_rAdditionalFilterComponents
308 : : the additional filter components which are required for master-detail relationships where
309 : : the detail part denotes a column name. In such a case, an additional filter needs to be created,
310 : : containing a new parameter.
311 : :
312 : : @precond
313 : : <member>m_aMasterFields</member> and <member>m_aDetailFields</member> have the same length
314 : : */
315 : : void classifyLinks(
316 : : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentColumns,
317 : : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxColumns,
318 : : ::std::vector< ::rtl::OUString >& _out_rAdditionalFilterComponents
319 : : ) SAL_THROW(( ::com::sun::star::uno::Exception ));
320 : :
321 : : /** finalizes our <member>m_pOuterParameters</member> so that it can be used for
322 : : external parameter listeners
323 : :
324 : : @precond
325 : : <member>m_pOuterParameters</member> is <NULL/>
326 : : @precond
327 : : <member>m_xInnerParamUpdate</member> is not <NULL/>
328 : : */
329 : : void createOuterParameters();
330 : :
331 : : /** fills in the parameters values which result from the master-detail relationship
332 : : between the database component and it's parent
333 : :
334 : : @param _rxParentColumns
335 : : the columns of the parameter database component. Must not be <NULL/>
336 : : @precond
337 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
338 : : */
339 : : void fillLinkedParameters(
340 : : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentColumns
341 : : );
342 : :
343 : : /** completes all missing parameters via an interaction handler
344 : :
345 : : @precond
346 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
347 : :
348 : : @return
349 : : <TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
350 : : */
351 : : bool completeParameters(
352 : : const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler,
353 : : const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > _rxConnection
354 : : );
355 : :
356 : : /** asks the parameter listeners to fill in final values
357 : :
358 : : @precond
359 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
360 : :
361 : : @return
362 : : <TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
363 : : */
364 : : bool consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies );
365 : :
366 : : /** mark an externally filled parameter asvisited
367 : : */
368 : : void externalParameterVisited( sal_Int32 _nIndex );
369 : :
370 : : private:
371 : : /** retrieves the columns of the parent database component
372 : :
373 : : @precond
374 : : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
375 : : @return
376 : : <TRUE/> if and only if the columns could be successfully retrieved
377 : : */
378 : : bool getParentColumns(
379 : : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /* [out] */ _out_rxParentColumns,
380 : : bool _bFromComposer
381 : : );
382 : :
383 : : /** retrieves the columns of our database component
384 : :
385 : : @param _bFromComposer
386 : : if <TRUE/>, the columns are obtained from the composer, else from the living database component itself
387 : : @return
388 : : <TRUE/> if and only if the columns could be successfully retrieved
389 : : */
390 : : bool getColumns(
391 : : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /* [out] */ _rxColumns,
392 : : bool _bFromComposer
393 : : ) SAL_THROW(( ::com::sun::star::uno::Exception ));
394 : :
395 : : /** retrieves the active connection of the database component
396 : : */
397 : : bool getConnection(
398 : : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& /* [out] */ _rxConnection
399 : : );
400 : :
401 : : /** caches some info about the connection of our database component
402 : : */
403 : : void cacheConnectionInfo() SAL_THROW(( ));
404 : :
405 : : private:
406 : : ParameterManager(); // never implemented
407 : : ParameterManager( const ParameterManager& ); // never implemented
408 : : ParameterManager& operator=( const ParameterManager& ); // never implemented
409 : : };
410 : :
411 : : //........................................................................
412 : : } // namespacefrm
413 : : //........................................................................
414 : :
415 : : #endif // CONNECTIVITY_PARAMETERS_HXX
416 : :
417 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|