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