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