Branch libreoffice-5-0-4
[LibreOffice.git] / include / connectivity / sqliterator.hxx
blobbe8274a8e6071ce9c17da3ed885cfa13833617a2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
20 #define INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
22 #include <connectivity/dbtoolsdllapi.hxx>
23 #include <connectivity/sqlnode.hxx>
24 #include <connectivity/IParseContext.hxx>
25 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
26 #include <com/sun/star/sdbc/DataType.hpp>
27 #include <com/sun/star/sdbc/SQLWarning.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <connectivity/CommonTools.hxx>
30 #include <rtl/ref.hxx>
31 #include <cppuhelper/weak.hxx>
33 #include <map>
34 #include <memory>
35 #include <vector>
37 namespace connectivity
40 class OSQLParseNode;
41 class OSQLParser;
43 typedef ::std::pair<const OSQLParseNode*,const OSQLParseNode* > TNodePair;
45 enum OSQLStatementType {
46 SQL_STATEMENT_UNKNOWN,
47 SQL_STATEMENT_SELECT,
48 SQL_STATEMENT_INSERT,
49 SQL_STATEMENT_UPDATE,
50 SQL_STATEMENT_DELETE,
51 SQL_STATEMENT_ODBC_CALL,
52 SQL_STATEMENT_CREATE_TABLE
55 struct OSQLParseTreeIteratorImpl;
57 class OOO_DLLPUBLIC_DBTOOLS OSQLParseTreeIterator
59 private:
60 ::com::sun::star::sdbc::SQLException m_aErrors; // conatins the error while iterating through the statement
61 const OSQLParseNode* m_pParseTree; // current ParseTree
62 const OSQLParser& m_rParser; // if set used for general error messages from the context
63 OSQLStatementType m_eStatementType;
64 ::rtl::Reference<OSQLColumns> m_aSelectColumns; // all columns from the Select clause
65 ::rtl::Reference<OSQLColumns> m_aParameters; // all parameters
66 ::rtl::Reference<OSQLColumns> m_aGroupColumns; // the group by columns
67 ::rtl::Reference<OSQLColumns> m_aOrderColumns; // the order by columns
68 ::rtl::Reference<OSQLColumns> m_aCreateColumns; // the columns for Create table clause
70 ::std::unique_ptr< OSQLParseTreeIteratorImpl > m_pImpl;
72 void traverseParameter(const OSQLParseNode* _pParseNode,const OSQLParseNode* _pColumnRef,const OUString& _aColumnName, OUString& _aTableRange, const OUString& _rColumnAlias);
73 // inserts a table into the map
74 void traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const OUString & rTableRange );
75 void traverseSearchCondition(OSQLParseNode * pSearchCondition);
76 void traverseOnePredicate(
77 OSQLParseNode * pColumnRef,
78 OUString& aValue,
79 OSQLParseNode * pParameter);
80 void traverseByColumnNames(const OSQLParseNode* pSelectNode, bool _bOrder);
81 void traverseParameters(const OSQLParseNode* pSelectNode);
83 const OSQLParseNode* getTableNode( OSQLTables& _rTables, const OSQLParseNode* pTableRef, OUString& aTableRange );
84 void getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, OUString& aTableRange );
85 void getSelect_statement(OSQLTables& _rTables,const OSQLParseNode* pSelect);
86 OUString getUniqueColumnName(const OUString & rColumnName) const;
88 /** finds the column with a given name, belonging to a given table, in a given tables collection
89 @param _rTables
90 the tables collection to look in
91 @param rColumnName
92 the column name to look for
93 @param rTableRange
94 the table alias name; if empty, look in all tables
95 @return
96 the desired column object, or <NULL/> if no such column could be found
98 static ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
99 const OSQLTables& _rTables, const OUString & rColumnName, OUString & rTableRange );
101 /** finds a column with a given name, belonging to a given table
102 @param rColumnName
103 the column name to look for
104 @param rTableRange
105 the table alias name; if empty, look in all tables
106 @param _bLookInSubTables
107 <TRUE/> if and only if not only our direct tables, but also our sub tables (from sub selects)
108 should be searched
109 @return
111 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
112 const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables );
114 /** finds a column with a given name among the select columns
115 @param rColumnName
116 the column name to look for
117 @return
119 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findSelectColumn(
120 const OUString & rColumnName );
122 protected:
123 void setSelectColumnName(::rtl::Reference<OSQLColumns>& _rColumns,const OUString & rColumnName,const OUString & rColumnAlias, const OUString & rTableRange, bool bFkt=false, sal_Int32 _nType = com::sun::star::sdbc::DataType::VARCHAR, bool bAggFkt=false);
124 void appendColumns(::rtl::Reference<OSQLColumns>& _rColumns,const OUString& _rTableAlias,const OSQLTable& _rTable);
125 // Other member variables that should be available in the "set" functions
126 // can be defined in the derived class. They can be initialized
127 // in its constructor and, after the "traverse" routines have been used,
128 // they can be queried using other functions.
131 private:
132 OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter) SAL_DELETED_FUNCTION;
134 public:
135 OSQLParseTreeIterator(
136 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
137 const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxTables,
138 const OSQLParser& _rParser,
139 const OSQLParseNode* pRoot = NULL );
140 ~OSQLParseTreeIterator();
142 inline static void * SAL_CALL operator new( size_t nSize )
143 { return ::rtl_allocateMemory( nSize ); }
144 inline static void * SAL_CALL operator new( size_t,void* _pHint )
145 { return _pHint; }
146 inline static void SAL_CALL operator delete( void * pMem )
147 { ::rtl_freeMemory( pMem ); }
148 inline static void SAL_CALL operator delete( void *,void* )
151 void dispose();
152 bool isCaseSensitive() const;
153 // The parse tree to be analysed/traversed:
154 // If NULL is passed, the current parse tree will be deleted and the error status cleared.
155 void setParseTree(const OSQLParseNode * pNewParseTree);
156 // void setParser(const OSQLParser* _pParser) { m_pParser = _pParser; }
157 const OSQLParseNode * getParseTree() const { return m_pParseTree; };
159 // subtrees in case of a select statement
160 const OSQLParseNode* getWhereTree() const;
161 const OSQLParseNode* getOrderTree() const;
162 const OSQLParseNode* getGroupByTree() const;
163 const OSQLParseNode* getHavingTree() const;
165 const OSQLParseNode* getSimpleWhereTree() const;
166 const OSQLParseNode* getSimpleOrderTree() const;
167 const OSQLParseNode* getSimpleGroupByTree() const;
168 const OSQLParseNode* getSimpleHavingTree() const;
170 /** returns the errors which occurred during parsing.
172 The returned object contains a chain (via SQLException::NextException) of SQLExceptions.
174 inline const ::com::sun::star::sdbc::SQLException& getErrors() const { return m_aErrors; }
175 inline bool hasErrors() const { return !m_aErrors.Message.isEmpty(); }
177 // statement type (already set in setParseTree):
178 OSQLStatementType getStatementType() const { return m_eStatementType; }
180 /** traverses the complete statement tree, and fills all our data with
181 the information obatined during traversal.
183 Implemented by calling the single traverse* methods in the proper
184 order (depending on the statement type).
186 void traverseAll();
188 enum TraversalParts
190 Parameters = 0x0001,
191 TableNames = 0x0002,
192 SelectColumns = 0x0006, // note that this includes TableNames. No SelectColumns without TableNames
194 // Those are not implemented currently
195 // GroupColumns = 0x0008,
196 // OrderColumns = 0x0010,
197 // SelectColumns = 0x0020,
198 // CreateColumns = 0x0040,
200 All = 0xFFFF
202 /** traverses selected parts of the statement tree, and fills our data with
203 the information obtained during traversal
205 @param _nIncludeMask
206 set of TraversalParts bits, specifying which information is to be collected.
207 Note TraversalParts is currently not
209 void traverseSome( sal_uInt32 _nIncludeMask );
211 // The TableRangeMap contains all tables associated with the range name found first.
212 const OSQLTables& getTables() const;
214 ::rtl::Reference<OSQLColumns> getSelectColumns() const { return m_aSelectColumns;}
215 ::rtl::Reference<OSQLColumns> getGroupColumns() const { return m_aGroupColumns;}
216 ::rtl::Reference<OSQLColumns> getOrderColumns() const { return m_aOrderColumns;}
217 ::rtl::Reference<OSQLColumns> getParameters() const { return m_aParameters; }
218 ::rtl::Reference<OSQLColumns> getCreateColumns() const { return m_aCreateColumns;}
220 /** return the columname and the table range
221 @param _pColumnRef
222 The column ref parse node.
223 @param _rColumnName
224 The column name to be set.
225 @param _rTableRange
226 The table range to be set.
228 void getColumnRange( const OSQLParseNode* _pColumnRef,
229 OUString &_rColumnName,
230 OUString& _rTableRange) const;
232 /** retrieves a column's name, table range, and alias
234 @param _pColumnRef
235 The column_ref parse node.
236 @param _out_rColumnName
237 The column name to be set.
238 @param _out_rTableRange
239 The table range to be set.
240 @param _out_rColumnAliasIfPresent
241 If the column specified by _pColumnRef is part of the select columns, and contains a column alias there,
242 this alias is returned here.
244 void getColumnRange( const OSQLParseNode* _pColumnRef,
245 OUString& _out_rColumnName,
246 OUString& _out_rTableRange,
247 OUString& _out_rColumnAliasIfPresent
248 ) const;
250 /** return the alias name of a column
251 @param _pDerivedColumn
252 The parse node where SQL_ISRULE(_pDerivedColumn,derived_column) must be true
253 @return
254 The alias name of the column or an empty string.
256 static OUString getColumnAlias(const OSQLParseNode* _pDerivedColumn);
258 /** return the columname and the table range
259 @param _pColumnRef
260 The column ref parse node.
261 @param _xMetaData
262 The database meta data.
263 @param _rColumnName
264 The column name to be set.
265 @param _rTableRange
266 The table range to be set.
268 static void getColumnRange( const OSQLParseNode* _pColumnRef,
269 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
270 OUString &_rColumnName,
271 OUString& _rTableRange);
273 // empty if ambiguous
274 bool getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
276 // return true when the tableNode is a rule like catalog_name, schema_name or table_name
277 static bool isTableNode(const OSQLParseNode* _pTableNode);
279 // tries to find the correct type of the function
280 sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode );
282 // returns a lis of all joined columns
283 ::std::vector< TNodePair >& getJoinConditions() const;
285 private:
286 // helper to implement getColumnTableRange
287 bool impl_getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
289 /** traverses the list of table names, and filles _rTables
291 bool traverseTableNames( OSQLTables& _rTables );
293 /// traverses columns in a SELECT statement
294 bool traverseSelectColumnNames(const OSQLParseNode* pSelectNode);
295 /// traverses columns in a CREATE TABLE statement
296 void traverseCreateColumns(const OSQLParseNode* pSelectNode);
298 bool traverseOrderByColumnNames(const OSQLParseNode* pSelectNode);
299 bool traverseGroupByColumnNames(const OSQLParseNode* pSelectNode);
301 bool traverseSelectionCriteria(const OSQLParseNode* pSelectNode);
303 private:
304 /** constructs a new iterator, which inherits some of the settings from a parent iterator
306 OSQLParseTreeIterator(
307 const OSQLParseTreeIterator& _rParentIterator,
308 const OSQLParser& _rParser,
309 const OSQLParseNode* pRoot );
311 /** creates a table object and inserts it into our tables collection
313 only used when we're iterating through a CREATE TABLE statement
315 OSQLTable impl_createTableObject(
316 const OUString& rTableName, const OUString& rCatalogName, const OUString& rSchemaName );
318 /** locates a record source (a table or query) with the given name
320 OSQLTable impl_locateRecordSource(
321 const OUString& _rComposedName
324 /** implementation for both traverseAll and traverseSome
326 void impl_traverse( sal_uInt32 _nIncludeMask );
328 /** retrieves the parameter columns of the given query
330 void impl_getQueryParameterColumns( const OSQLTable& _rQuery );
332 void setOrderByColumnName(const OUString & rColumnName, OUString & rTableRange, bool bAscending);
333 void setGroupByColumnName(const OUString & rColumnName, OUString & rTableRange);
335 private:
336 /** appends an SQLException corresponding to the given error code to our error collection
338 @param _eError
339 the code of the error which occurred
340 @param _pReplaceToken1
341 if not <NULL/>, the first occurrence of '#' in the error message will be replaced
342 with the given token
343 @param _pReplaceToken2
344 if not <NULL/>, and if _rReplaceToken1 is not <NULL/>, the second occurrence of '#'
345 in the error message will be replaced with _rReplaceToken2
347 void impl_appendError( IParseContext::ErrorCode _eError,
348 const OUString* _pReplaceToken1 = NULL, const OUString* _pReplaceToken2 = NULL );
350 /** appends an SQLException corresponding to the given error code to our error collection
352 void impl_appendError( const ::com::sun::star::sdbc::SQLException& _rError );
354 /** resets our errors
356 inline void impl_resetErrors()
358 m_aErrors = ::com::sun::star::sdbc::SQLException();
360 void impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition);
364 #endif // INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */