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 190 : 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 24 : 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 : /** adds the given listener to the list of parameter listeners
202 : */
203 : void addParameterListener(
204 : const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& _rxListener
205 : );
206 :
207 : /** removes the given listener from the list of parameter listeners
208 : */
209 : void removeParameterListener(
210 : const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& _rxListener
211 : );
212 :
213 : // XParameters equivalents
214 : void setNull ( sal_Int32 _nIndex, sal_Int32 sqlType);
215 : void setObjectNull ( sal_Int32 _nIndex, sal_Int32 sqlType, const OUString& typeName);
216 : void setBoolean ( sal_Int32 _nIndex, bool x);
217 : void setByte ( sal_Int32 _nIndex, sal_Int8 x);
218 : void setShort ( sal_Int32 _nIndex, sal_Int16 x);
219 : void setInt ( sal_Int32 _nIndex, sal_Int32 x);
220 : void setLong ( sal_Int32 _nIndex, sal_Int64 x);
221 : void setFloat ( sal_Int32 _nIndex, float x);
222 : void setDouble ( sal_Int32 _nIndex, double x);
223 : void setString ( sal_Int32 _nIndex, const OUString& x);
224 : void setBytes ( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x);
225 : void setDate ( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x);
226 : void setTime ( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x);
227 : void setTimestamp ( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x);
228 : void setBinaryStream ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length);
229 : void setCharacterStream ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length);
230 : void setObject ( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x);
231 : void setObjectWithInfo ( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale);
232 : void setRef ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x);
233 : void setBlob ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x);
234 : void setClob ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x);
235 : void setArray ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x);
236 : void clearParameters();
237 :
238 : private:
239 : /// checkes whether the object is already initialized, and not yet disposed
240 48 : inline bool isAlive() const { return m_xComponent.get().is() && m_xInnerParamUpdate.is(); }
241 :
242 : /** creates a filter expression from a master-detail link where the detail denotes a column name
243 : */
244 : OUString
245 : createFilterConditionFromColumnLink(
246 : const OUString& /* [in] */ _rMasterColumn,
247 : const OUString& /* [in] */ _rDetailColumn,
248 : OUString& /* [out] */ _rNewParamName
249 : );
250 :
251 : /** initializes our query composer, and the collection of inner parameter columns
252 :
253 : @param _rxComponent
254 : the database component to initialize from. Must not be <NULL/>
255 : @return
256 : <TRUE/> if and only if the initialization was successful
257 :
258 : @postcond
259 : if and only if <TRUE/> is returned, then <member>m_xInnerParamColumns</member> contains the collection of
260 : inner parameters
261 : */
262 : bool initializeComposerByComponent(
263 : const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxComponent
264 : );
265 :
266 : /** collects initial meta information about inner parameters (i.e. it initially fills
267 : <member>m_aParameterInformation</member>).
268 :
269 : @param _bSecondRun
270 : if <TRUE/>, this is the second run, because we ourself previously extended the filter of
271 : the RowSet
272 :
273 : @precond
274 : <member>m_xInnerParamColumns</member> is not <NULL/>
275 : */
276 : void collectInnerParameters( bool _bSecondRun );
277 :
278 : /** analyzes the master-detail links for our database component, and initializes m_aMasterFields and m_aDetailFields
279 :
280 : @param _rFilterManager
281 : the filter manager of the database component
282 : @param _rColumnsInLinkDetails
283 : will be set to <TRUE/> if and only if there were link pairs where the detail field denoted
284 : a column name of our database component
285 :
286 : @precond
287 : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
288 : */
289 : void analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails );
290 :
291 : /** classifies the link pairs
292 :
293 : @param _rxParentColumns
294 : the columns of the parent database component
295 :
296 : @param _rxColumns
297 : the columns of our own database component
298 :
299 : @param _out_rAdditionalFilterComponents
300 : the additional filter components which are required for master-detail relationships where
301 : the detail part denotes a column name. In such a case, an additional filter needs to be created,
302 : containing a new parameter.
303 :
304 : @precond
305 : <member>m_aMasterFields</member> and <member>m_aDetailFields</member> have the same length
306 : */
307 : void classifyLinks(
308 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentColumns,
309 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxColumns,
310 : ::std::vector< OUString >& _out_rAdditionalFilterComponents
311 : );
312 :
313 : /** finalizes our <member>m_pOuterParameters</member> so that it can be used for
314 : external parameter listeners
315 :
316 : @precond
317 : <member>m_pOuterParameters</member> is <NULL/>
318 : @precond
319 : <member>m_xInnerParamUpdate</member> is not <NULL/>
320 : */
321 : void createOuterParameters();
322 :
323 : /** fills in the parameters values which result from the master-detail relationship
324 : between the database component and its parent
325 :
326 : @param _rxParentColumns
327 : the columns of the parameter database component. Must not be <NULL/>
328 : @precond
329 : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
330 : */
331 : void fillLinkedParameters(
332 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentColumns
333 : );
334 :
335 : /** completes all missing parameters via an interaction handler
336 :
337 : @precond
338 : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
339 :
340 : @return
341 : <TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
342 : */
343 : bool completeParameters(
344 : const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler,
345 : const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection
346 : );
347 :
348 : /** asks the parameter listeners to fill in final values
349 :
350 : @precond
351 : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
352 :
353 : @return
354 : <TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
355 : */
356 : bool consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies );
357 :
358 : /** mark an externally filled parameter asvisited
359 : */
360 : void externalParameterVisited( sal_Int32 _nIndex );
361 :
362 : private:
363 : /** retrieves the columns of the parent database component
364 :
365 : @precond
366 : the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
367 : @return
368 : <TRUE/> if and only if the columns could be successfully retrieved
369 : */
370 : bool getParentColumns(
371 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /* [out] */ _out_rxParentColumns,
372 : bool _bFromComposer
373 : );
374 :
375 : /** retrieves the columns of our database component
376 :
377 : @param _bFromComposer
378 : if <TRUE/>, the columns are obtained from the composer, else from the living database component itself
379 : @return
380 : <TRUE/> if and only if the columns could be successfully retrieved
381 : */
382 : bool getColumns(
383 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /* [out] */ _rxColumns,
384 : bool _bFromComposer
385 : );
386 :
387 : /** retrieves the active connection of the database component
388 : */
389 : bool getConnection(
390 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& /* [out] */ _rxConnection
391 : );
392 :
393 : /** caches some info about the connection of our database component
394 : */
395 : void cacheConnectionInfo();
396 :
397 : private:
398 : ParameterManager( const ParameterManager& ) SAL_DELETED_FUNCTION;
399 : ParameterManager& operator=( const ParameterManager& ) SAL_DELETED_FUNCTION;
400 : };
401 :
402 :
403 : } // namespacefrm
404 :
405 :
406 : #endif // INCLUDED_CONNECTIVITY_PARAMETERS_HXX
407 :
408 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|