/* -*- 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 CONNECTIVITY_PARAMETERS_HXX #define CONNECTIVITY_PARAMETERS_HXX #include #include #include #include #include #include #include #include #include #include #include #include "connectivity/dbtoolsdllapi.hxx" #include "connectivity/paramwrapper.hxx" #include #include #include //........................................................................ 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 XParamaters::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 indicies 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< ::rtl::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< ::rtl::OUString > m_aMasterFields; ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aDetailFields; ::rtl::OUString m_sIdentifierQuoteString; ::rtl::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

In particular, all values which can be filled from the master-detail relationship of between our database component and it's parent are filled in.

@param _rxCompletionHandler an interaction handler which should be used to fill all parameters which cannot be filled by other means. May be @param _rClearForNotifies the mutex guard to be (temporarily) cleared for notifications @precond the instance is alive, i.e. isAlive returns @return if and only if the parameter filling has not 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 XParameters::setNull) @precond the instance is alive, i.e. isAlive returns */ void setAllParametersNull() SAL_THROW( ( ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException ) ); /** 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 SELECT * from invoice where inv_id = :cid, and there is one master-detail link from @precond the instance is alive, i.e. isAlive returns */ void resetParameterValues() SAL_THROW(()); /** tells the object that it's database component is being disposed The object then fires the XEventListener::disposing 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 ::rtl::OUString& typeName); void setBoolean ( sal_Int32 _nIndex, sal_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 ::rtl::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 */ ::rtl::OUString createFilterConditionFromColumnLink( const ::rtl::OUString& /* [in] */ _rMasterColumn, const ::rtl::OUString& /* [in] */ _rDetailColumn, ::rtl::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 @return if and only if the initialization was successfull @postcond if and only if is returned, then m_xInnerParamColumns 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 m_aParameterInformation). @param _bSecondRun if , this is the second run, because we ourself previously extended the filter of the RowSet @precond m_xInnerParamColumns is not */ 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 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. isAlive returns */ 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 m_aMasterFields and m_aDetailFields 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< ::rtl::OUString >& _out_rAdditionalFilterComponents ) SAL_THROW(( ::com::sun::star::uno::Exception )); /** finalizes our m_pOuterParameters so that it can be used for external parameter listeners @precond m_pOuterParameters is @precond m_xInnerParamUpdate is not */ void createOuterParameters(); /** fills in the parameters values which result from the master-detail relationship between the database component and it's parent @param _rxParentColumns the columns of the parameter database component. Must not be @precond the instance is alive, i.e. isAlive returns */ 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. isAlive returns @return if and only if the parameter filling has not 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. isAlive returns @return if and only if the parameter filling has not 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. isAlive returns @return 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 , the columns are obtained from the composer, else from the living database component itself @return 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 ) SAL_THROW(( ::com::sun::star::uno::Exception )); /** 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() SAL_THROW(( )); private: ParameterManager(); // never implemented ParameterManager( const ParameterManager& ); // never implemented ParameterManager& operator=( const ParameterManager& ); // never implemented }; //........................................................................ } // namespacefrm //........................................................................ #endif // CONNECTIVITY_PARAMETERS_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */