office-gobmx/include/connectivity/parameters.hxx
Stephan Bergmann c6be3cf03b loplugin:deletedspecial
Change-Id: I0faa47383f8952a74742a640ab2af602b4fcba8f
2015-02-07 12:35:57 +01:00

415 lines
19 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_CONNECTIVITY_PARAMETERS_HXX
#define INCLUDED_CONNECTIVITY_PARAMETERS_HXX
#include <map>
#include <vector>
#include <com/sun/star/uno/XAggregation.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/form/XDatabaseParameterListener.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/sdbc/XParameters.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
#include <connectivity/dbtoolsdllapi.hxx>
#include <connectivity/paramwrapper.hxx>
#include <unotools/sharedunocomponent.hxx>
#include <cppuhelper/interfacecontainer.hxx>
namespace dbtools
{
typedef ::utl::SharedUNOComponent< ::com::sun::star::sdb::XSingleSelectQueryComposer, ::utl::DisposableComponent >
SharedQueryComposer;
//= ParameterManager
class FilterManager;
class OOO_DLLPUBLIC_DBTOOLS ParameterManager
{
public:
/// classifies the origin of the data to fill a parameter
enum ParameterClassification
{
/** parameters which are filled from the master-detail relationship, where the detail
name is an explicit parameter name
*/
eLinkedByParamName,
/** parameters which are filled from the master-detail relationship, where the detail
name is a column name, so an implicit parameter had to be generated for it
*/
eLinkedByColumnName,
/** parameters which are filled externally (i.e. by XParameters::setXXX, or by the parameter listeners)
*/
eFilledExternally
};
/** meta data about an inner parameter
*/
private:
struct ParameterMetaData
{
/// the type of the parameter
ParameterClassification eType;
/// the column object for this parameter, as returned by the query composer
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
xComposerColumn;
/// the indices of inner parameters which need to be filled when this concrete parameter is set
::std::vector< sal_Int32 > aInnerIndexes;
/// default ctor
ParameterMetaData()
:eType( eFilledExternally )
{
}
/// ctor with composer column
ParameterMetaData( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxColumn )
:eType ( eFilledExternally )
,xComposerColumn ( _rxColumn )
{
}
};
typedef ::std::map< OUString, ParameterMetaData > ParameterInformation;
private:
::osl::Mutex& m_rMutex;
::cppu::OInterfaceContainerHelper m_aParameterListeners;
::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
m_xContext;
::com::sun::star::uno::WeakReference< ::com::sun::star::beans::XPropertySet >
m_xComponent; // the database component whose parameters we're handling
::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >
m_xAggregatedRowSet; // the aggregated row set - necessary for unwrapped access to some interfaces
::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XParameters >
m_xInnerParamUpdate; // write access to the inner parameters
SharedQueryComposer m_xComposer; // query composer wrapping the statement which the *aggregate* is based on
SharedQueryComposer m_xParentComposer; // query composer wrapping the statement of our parent database component
::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >
m_xInnerParamColumns; // index access to the parameter columns, as got from the query composer
::dbtools::param::ParametersContainerRef
m_pOuterParameters; // the container of parameters which still need to be filled in by
// external instances
sal_Int32 m_nInnerCount; // overall number of parameters as required by the database component's aggregate
ParameterInformation m_aParameterInformation;
::com::sun::star::uno::Sequence< OUString > m_aMasterFields;
::com::sun::star::uno::Sequence< OUString > m_aDetailFields;
OUString m_sIdentifierQuoteString;
OUString m_sSpecialCharacters;
::std::vector< bool > m_aParametersVisited;
bool m_bUpToDate;
public:
/** ctor
*/
explicit ParameterManager(
::osl::Mutex& _rMutex,
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext
);
/// late ctor
void initialize(
const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxComponent,
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation >& _rxComponentAggregate
);
/// makes the object forgetting the references to the database component
void dispose( );
/// clears the instance data
void clearAllParameterInformation();
/// checks whether the parameter information are up-to-date
inline bool isUpToDate() const { return m_bUpToDate; }
/** updates all parameter information represented by the instance
*/
void updateParameterInfo( FilterManager& _rFilterManager );
/** fills parameter values, as extensive as possible
<p>In particular, all values which can be filled from the master-detail relationship of
between our database component and its parent are filled in.</p>
@param _rxCompletionHandler
an interaction handler which should be used to fill all parameters which
cannot be filled by other means. May be <NULL/>
@param _rClearForNotifies
the mutex guard to be (temporarily) cleared for notifications
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
@return
<TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
*/
bool fillParameterValues(
const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler,
::osl::ResettableMutexGuard& _rClearForNotifies
);
/** sets all parameter values to null (via <member>XParameters::setNull</member>)
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
*/
void setAllParametersNull();
/** resets all detail columns which are, via a parameter, linked to a master column, to
the value of this master column.
For instance, if the database component is bound to a statement <code>SELECT * from invoice where inv_id = :cid</code>,
and there is <em>one</em> master-detail link from
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
*/
void resetParameterValues();
/** tells the object that it's database component is being disposed
The object then fires the <member>XEventListener::disposing</member> notification to
the parameter listeners
*/
void disposing( const ::com::sun::star::lang::EventObject& _rDisposingEvent );
/** adds the given listener to the list of parameter listeners
*/
void addParameterListener(
const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& _rxListener
);
/** removes the given listener from the list of parameter listeners
*/
void removeParameterListener(
const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& _rxListener
);
// XParameters equivalents
void setNull ( sal_Int32 _nIndex, sal_Int32 sqlType);
void setObjectNull ( sal_Int32 _nIndex, sal_Int32 sqlType, const OUString& typeName);
void setBoolean ( sal_Int32 _nIndex, bool x);
void setByte ( sal_Int32 _nIndex, sal_Int8 x);
void setShort ( sal_Int32 _nIndex, sal_Int16 x);
void setInt ( sal_Int32 _nIndex, sal_Int32 x);
void setLong ( sal_Int32 _nIndex, sal_Int64 x);
void setFloat ( sal_Int32 _nIndex, float x);
void setDouble ( sal_Int32 _nIndex, double x);
void setString ( sal_Int32 _nIndex, const OUString& x);
void setBytes ( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x);
void setDate ( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x);
void setTime ( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x);
void setTimestamp ( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x);
void setBinaryStream ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length);
void setCharacterStream ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length);
void setObject ( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x);
void setObjectWithInfo ( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale);
void setRef ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x);
void setBlob ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x);
void setClob ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x);
void setArray ( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x);
void clearParameters();
private:
/// checkes whether the object is already initialized, and not yet disposed
inline bool isAlive() const { return m_xComponent.get().is() && m_xInnerParamUpdate.is(); }
/** creates a filter expression from a master-detail link where the detail denotes a column name
*/
OUString
createFilterConditionFromColumnLink(
const OUString& /* [in] */ _rMasterColumn,
const OUString& /* [in] */ _rDetailColumn,
OUString& /* [out] */ _rNewParamName
);
/** initializes our query composer, and the collection of inner parameter columns
@param _rxComponent
the database component to initialize from. Must not be <NULL/>
@return
<TRUE/> if and only if the initialization was successful
@postcond
if and only if <TRUE/> is returned, then <member>m_xInnerParamColumns</member> contains the collection of
inner parameters
*/
bool initializeComposerByComponent(
const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxComponent
);
/** collects initial meta information about inner parameters (i.e. it initially fills
<member>m_aParameterInformation</member>).
@param _bSecondRun
if <TRUE/>, this is the second run, because we ourself previously extended the filter of
the RowSet
@precond
<member>m_xInnerParamColumns</member> is not <NULL/>
*/
void collectInnerParameters( bool _bSecondRun );
/** analyzes the master-detail links for our database component, and initializes m_aMasterFields and m_aDetailFields
@param _rFilterManager
the filter manager of the database component
@param _rColumnsInLinkDetails
will be set to <TRUE/> if and only if there were link pairs where the detail field denoted
a column name of our database component
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
*/
void analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails );
/** classifies the link pairs
@param _rxParentColumns
the columns of the parent database component
@param _rxColumns
the columns of our own database component
@param _out_rAdditionalFilterComponents
the additional filter components which are required for master-detail relationships where
the detail part denotes a column name. In such a case, an additional filter needs to be created,
containing a new parameter.
@precond
<member>m_aMasterFields</member> and <member>m_aDetailFields</member> have the same length
*/
void classifyLinks(
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentColumns,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxColumns,
::std::vector< OUString >& _out_rAdditionalFilterComponents
);
/** finalizes our <member>m_pOuterParameters</member> so that it can be used for
external parameter listeners
@precond
<member>m_pOuterParameters</member> is <NULL/>
@precond
<member>m_xInnerParamUpdate</member> is not <NULL/>
*/
void createOuterParameters();
/** fills in the parameters values which result from the master-detail relationship
between the database component and its parent
@param _rxParentColumns
the columns of the parameter database component. Must not be <NULL/>
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
*/
void fillLinkedParameters(
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxParentColumns
);
/** completes all missing parameters via an interaction handler
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
@return
<TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
*/
bool completeParameters(
const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxCompletionHandler,
const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > _rxConnection
);
/** asks the parameter listeners to fill in final values
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
@return
<TRUE/> if and only if the parameter filling has <em>not</em> been cancelled by the user
*/
bool consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies );
/** mark an externally filled parameter asvisited
*/
void externalParameterVisited( sal_Int32 _nIndex );
private:
/** retrieves the columns of the parent database component
@precond
the instance is alive, i.e. <member>isAlive</member> returns <TRUE/>
@return
<TRUE/> if and only if the columns could be successfully retrieved
*/
bool getParentColumns(
::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /* [out] */ _out_rxParentColumns,
bool _bFromComposer
);
/** retrieves the columns of our database component
@param _bFromComposer
if <TRUE/>, the columns are obtained from the composer, else from the living database component itself
@return
<TRUE/> if and only if the columns could be successfully retrieved
*/
bool getColumns(
::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& /* [out] */ _rxColumns,
bool _bFromComposer
);
/** retrieves the active connection of the database component
*/
bool getConnection(
::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& /* [out] */ _rxConnection
);
/** caches some info about the connection of our database component
*/
void cacheConnectionInfo();
private:
ParameterManager( const ParameterManager& ) SAL_DELETED_FUNCTION;
ParameterManager& operator=( const ParameterManager& ) SAL_DELETED_FUNCTION;
};
} // namespacefrm
#endif // INCLUDED_CONNECTIVITY_PARAMETERS_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */