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