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 DBACCESS_CORE_API_SINGLESELECTQUERYCOMPOSER_HXX
28 #define DBACCESS_CORE_API_SINGLESELECTQUERYCOMPOSER_HXX
29 
30 #include <com/sun/star/sdb/XParametersSupplier.hpp>
31 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
32 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
33 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
34 #include <com/sun/star/lang/XServiceInfo.hpp>
35 #include <com/sun/star/script/XTypeConverter.hpp>
36 #include <cppuhelper/implbase5.hxx>
37 #include <connectivity/sqliterator.hxx>
38 #include <connectivity/sqlparse.hxx>
39 #include "apitools.hxx"
40 #include <comphelper/broadcasthelper.hxx>
41 #include <comphelper/uno3.hxx>
42 #include <comphelper/proparrhlp.hxx>
43 #include <comphelper/propertycontainer.hxx>
44 #include <comphelper/componentcontext.hxx>
45 
46 #include <memory>
47 
48 namespace com { namespace sun { namespace star { namespace util {
49 	class XNumberFormatsSupplier;
50 	class XNumberFormatter;
51 }}}}
52 
53 namespace dbaccess
54 {
55 	typedef ::cppu::ImplHelper5<	::com::sun::star::sdb::XSingleSelectQueryComposer,
56 									::com::sun::star::sdb::XParametersSupplier,
57 									::com::sun::star::sdbcx::XColumnsSupplier,
58 									::com::sun::star::sdbcx::XTablesSupplier,
59 									::com::sun::star::lang::XServiceInfo	> OSingleSelectQueryComposer_BASE;
60 
61 	class OPrivateColumns;
62 	class OPrivateTables;
63 
64 	class OSingleSelectQueryComposer :	 public ::comphelper::OMutexAndBroadcastHelper
65 										,public OSubComponent
66 										,public ::comphelper::OPropertyContainer
67 										,public ::comphelper::OPropertyArrayUsageHelper < OSingleSelectQueryComposer >
68 										,public OSingleSelectQueryComposer_BASE
69 	{
70 		enum SQLPart
71 		{
72 			Where = 0,      // the 0 is important, as it will be used as index into arrays
73 			Group,
74 			Having,
75 			Order,
76 
77             SQLPartCount
78 		};
79         inline void incSQLPart( SQLPart& e ) { e = (SQLPart)(1 + (size_t)e); }
80 		enum EColumnType
81 		{
82 			SelectColumns		= 0,
83 			GroupByColumns		= 1,
84 			OrderColumns		= 2,
85 			ParameterColumns	= 3
86 		};
87         typedef ::std::const_mem_fun_t< const ::connectivity::OSQLParseNode*, ::connectivity::OSQLParseTreeIterator >
88                                                 TGetParseNode;
89 		::connectivity::OSQLParser				m_aSqlParser;
90 		::connectivity::OSQLParseTreeIterator	m_aSqlIterator;         // the iterator for the complete statement
91 		::connectivity::OSQLParseTreeIterator	m_aAdditiveIterator;    // the iterator for the "additive statement" (means without the clauses of the elementary statement)
92 		::std::vector<OPrivateColumns*>			m_aColumnsCollection;   // used for columns and parameters of old queries
93 		::std::vector<OPrivateTables*>			m_aTablesCollection;
94 
95         ::std::vector< ::rtl::OUString >        m_aElementaryParts;     // the filter/groupby/having/order of the elementary statement
96 
97 		::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>				m_xConnection;
98 		::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>		m_xMetaData;
99 		::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>			m_xConnectionTables;
100         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>			m_xConnectionQueries;
101 		::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >	m_xNumberFormatsSupplier;
102 		::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>			m_xColumns;
103         ::comphelper::ComponentContext                                                      m_aContext;
104 		::com::sun::star::uno::Reference< ::com::sun::star::script::XTypeConverter >		m_xTypeConverter;
105 
106 		::std::vector<OPrivateColumns*>			m_aCurrentColumns;
107 		OPrivateTables*							m_pTables;		// currently used tables
108 
109 		::rtl::OUString							m_aPureSelectSQL;   // the pure select statement, without filter/order/groupby/having
110 		::rtl::OUString							m_sDecimalSep;
111         ::rtl::OUString							m_sCommand;
112 		::com::sun::star::lang::Locale			m_aLocale;
113 		sal_Int32								m_nBoolCompareMode; // how to compare bool values
114         sal_Int32								m_nCommandType;
115 
116 		// <properties>
117 		::rtl::OUString							m_sOrignal;
118 		// </properties>
119 
120 
121 		sal_Bool setORCriteria(::connectivity::OSQLParseNode* pCondition, ::connectivity::OSQLParseTreeIterator& _rIterator,
122 			::std::vector< ::std::vector < ::com::sun::star::beans::PropertyValue > >& rFilters, const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const;
123 		sal_Bool setANDCriteria(::connectivity::OSQLParseNode* pCondition, ::connectivity::OSQLParseTreeIterator& _rIterator,
124 			::std::vector < ::com::sun::star::beans::PropertyValue > & rFilters, const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const;
125 		sal_Bool setComparsionPredicate(::connectivity::OSQLParseNode* pCondition, ::connectivity::OSQLParseTreeIterator& _rIterator,
126 			::std::vector < ::com::sun::star::beans::PropertyValue > & rFilters, const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const;
127 
128 		::rtl::OUString getColumnName(::connectivity::OSQLParseNode* pColumnRef,::connectivity::OSQLParseTreeIterator& _rIterator) const;
129 		::rtl::OUString getTableAlias(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column ) const;
130 		sal_Int32 getPredicateType(::connectivity::OSQLParseNode * _pPredicate) const;
131 		// clears all Columns,Parameters and tables and insert it to their vectors
132 		void clearCurrentCollections();
133         // clears the columns collection given by EColumnType
134         void clearColumns( const EColumnType _eType );
135 
136         /** retrieves a particular part of a statement
137             @param _rIterator
138                 the iterator to use.
139         */
140 		::rtl::OUString getStatementPart( TGetParseNode& _aGetFunctor, ::connectivity::OSQLParseTreeIterator& _rIterator );
141 		void setQuery_Impl( const ::rtl::OUString& command );
142 
143 		void setConditionByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column
144 								, sal_Bool andCriteria
145 								,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,::rtl::OUString>& _aSetFunctor
146                                 ,sal_Int32 filterOperator);
147 
148 		/** getStructuredCondition returns the structured condition for the where or having clause
149 			@param	_aGetFunctor
150 				A member function to get the correct parse node.
151 
152 			@return
153 				The structured filter
154 		*/
155 		::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >
156 					getStructuredCondition( TGetParseNode& _aGetFunctor );
157 
158 		::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >
159 					setCurrentColumns( EColumnType _eType, const ::vos::ORef< ::connectivity::OSQLColumns >& _rCols );
160 
161 		//helper methods for mem_fun_t
162 		inline bool implSetFilter(::rtl::OUString _sFilter) { setFilter(_sFilter); return true;}
163 		inline bool implSetHavingClause(::rtl::OUString _sFilter) { setHavingClause(_sFilter); return true;}
164 
165 		/** returns the part of the seelect statement
166 			@param	_ePart
167 				Which part should be returned.
168 			@param	_bWithKeyword
169 				If <TRUE/> the keyword will be added too. Otherwise not.
170             @param _rIterator
171                 The iterator to use.
172 
173 			@return
174 				The part of the select statement.
175 		*/
176         ::rtl::OUString getSQLPart( SQLPart _ePart, ::connectivity::OSQLParseTreeIterator& _rIterator, sal_Bool _bWithKeyword );
177 
178         /** retrieves the keyword for the given SQLPart
179         */
180         ::rtl::OUString getKeyword( SQLPart _ePart ) const;
181 
182         /** sets a single "additive" clause, means a filter/groupby/having/order clause
183         */
184         void setSingleAdditiveClause( SQLPart _ePart, const ::rtl::OUString& _rClause );
185 
186         /** composes a statement from m_aPureSelectSQL and the 4 usual clauses
187         */
188         ::rtl::OUString composeStatementFromParts( const ::std::vector< ::rtl::OUString >& _rParts );
189 
190         /** return the name of the column.
191         */
192         ::rtl::OUString impl_getColumnName_throw(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column);
193 
194     protected:
195 		virtual ~OSingleSelectQueryComposer();
196 	public:
197 
198 		OSingleSelectQueryComposer(	const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& _xTableSupplier,
199 						const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _xConnection,
200                         const ::comphelper::ComponentContext& _rContext);
201 
202 
203 		void SAL_CALL disposing(void);
204 		// ::com::sun::star::lang::XTypeProvider
205 		DECLARE_TYPEPROVIDER( );
206 
207 		// com::sun::star::lang::XUnoTunnel
208 		virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
209 		// ::com::sun::star::uno::XInterface
210 		DECLARE_XINTERFACE( )
211 
212 		// XServiceInfo
213 		DECLARE_SERVICE_INFO();
214 
215 		DECLARE_PROPERTYCONTAINER_DEFAULTS();
216 
217 		// ::com::sun::star::sdb::XSingleSelectQueryComposer
218         virtual ::rtl::OUString SAL_CALL getElementaryQuery() throw (::com::sun::star::uno::RuntimeException);
219         virtual void SAL_CALL setElementaryQuery( const ::rtl::OUString& _rElementary ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
220 		virtual void SAL_CALL setFilter( const ::rtl::OUString& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
221 		virtual void SAL_CALL setStructuredFilter( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
222 		virtual void SAL_CALL appendFilterByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
223 		virtual void SAL_CALL appendGroupByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
224 		virtual void SAL_CALL setGroup( const ::rtl::OUString& group ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
225 		virtual void SAL_CALL setHavingClause( const ::rtl::OUString& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
226         virtual void SAL_CALL setStructuredHavingClause( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& filter ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
227         virtual void SAL_CALL appendHavingClauseByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
228 		virtual void SAL_CALL appendOrderByColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, sal_Bool ascending ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
229 		virtual void SAL_CALL setOrder( const ::rtl::OUString& order ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
230 
231 		// XSingleSelectQueryAnalyzer
232 		virtual ::rtl::OUString SAL_CALL getQuery(  ) throw (::com::sun::star::uno::RuntimeException);
233 		virtual void SAL_CALL setQuery( const ::rtl::OUString& command ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
234         virtual void SAL_CALL setCommand( const ::rtl::OUString& command,sal_Int32 CommandType ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
235 		virtual ::rtl::OUString SAL_CALL getFilter(  ) throw (::com::sun::star::uno::RuntimeException);
236 		virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > > SAL_CALL getStructuredFilter(  ) throw (::com::sun::star::uno::RuntimeException);
237 		virtual ::rtl::OUString SAL_CALL getGroup(  ) throw (::com::sun::star::uno::RuntimeException);
238 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL getGroupColumns(  ) throw (::com::sun::star::uno::RuntimeException);
239 		virtual ::rtl::OUString SAL_CALL getHavingClause(  ) throw (::com::sun::star::uno::RuntimeException);
240         virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > > SAL_CALL getStructuredHavingClause(  ) throw (::com::sun::star::uno::RuntimeException);
241 		virtual ::rtl::OUString SAL_CALL getOrder(  ) throw (::com::sun::star::uno::RuntimeException);
242 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL getOrderColumns(  ) throw (::com::sun::star::uno::RuntimeException);
243 		virtual ::rtl::OUString SAL_CALL getQueryWithSubstitution(  ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
244 
245 		// XColumnsSupplier
246 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns(  ) throw(::com::sun::star::uno::RuntimeException);
247 		// XTablesSupplier
248 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTables(  ) throw(::com::sun::star::uno::RuntimeException);
249 		// XParametersSupplier
250 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > SAL_CALL getParameters(  ) throw(::com::sun::star::uno::RuntimeException);
251 	};
252 }
253 #endif // DBACCESS_CORE_API_SINGLESELECTQUERYCOMPOSER_HXX
254