bump product version to 4.2.0.1
[LibreOffice.git] / include / connectivity / sqliterator.hxx
blob90d0404905740f5fb637826568e931d43ae5bbed
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::auto_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,sal_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,sal_Bool bFkt=sal_False,sal_Int32 _nType = com::sun::star::sdbc::DataType::VARCHAR,sal_Bool bAggFkt=sal_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(); // never implemented
133 OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter); // never implemented
135 public:
136 OSQLParseTreeIterator(
137 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
138 const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxTables,
139 const OSQLParser& _rParser,
140 const OSQLParseNode* pRoot = NULL );
141 ~OSQLParseTreeIterator();
143 inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
144 { return ::rtl_allocateMemory( nSize ); }
145 inline static void * SAL_CALL operator new( size_t,void* _pHint ) SAL_THROW(())
146 { return _pHint; }
147 inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
148 { ::rtl_freeMemory( pMem ); }
149 inline static void SAL_CALL operator delete( void *,void* ) SAL_THROW(())
152 void dispose();
153 bool isCaseSensitive() const;
154 // The parse tree to be analysed/traversed:
155 // If NULL is passed, the current parse tree will be deleted and the error status cleared.
156 void setParseTree(const OSQLParseNode * pNewParseTree);
157 // void setParser(const OSQLParser* _pParser) { m_pParser = _pParser; }
158 const OSQLParseNode * getParseTree() const { return m_pParseTree; };
160 // subtrees in case of a select statement
161 const OSQLParseNode* getWhereTree() const;
162 const OSQLParseNode* getOrderTree() const;
163 const OSQLParseNode* getGroupByTree() const;
164 const OSQLParseNode* getHavingTree() const;
166 const OSQLParseNode* getSimpleWhereTree() const;
167 const OSQLParseNode* getSimpleOrderTree() const;
168 const OSQLParseNode* getSimpleGroupByTree() const;
169 const OSQLParseNode* getSimpleHavingTree() const;
171 /** returns the errors which occurred during parsing.
173 The returned object contains a chain (via SQLException::NextException) of SQLExceptions.
175 inline const ::com::sun::star::sdbc::SQLException& getErrors() const { return m_aErrors; }
176 inline bool hasErrors() const { return !m_aErrors.Message.isEmpty(); }
178 // statement type (already set in setParseTree):
179 OSQLStatementType getStatementType() const { return m_eStatementType; }
181 /** traverses the complete statement tree, and fills all our data with
182 the information obatined during traversal.
184 Implemented by calling the single traverse* methods in the proper
185 order (depending on the statement type).
187 void traverseAll();
189 enum TraversalParts
191 Parameters = 0x0001,
192 TableNames = 0x0002,
193 SelectColumns = 0x0006, // note that this includes TableNames. No SelectColumns without TableNames
195 // Those are not implemented currently
196 // GroupColumns = 0x0008,
197 // OrderColumns = 0x0010,
198 // SelectColumns = 0x0020,
199 // CreateColumns = 0x0040,
201 All = 0xFFFF
203 /** traverses selected parts of the statement tree, and fills our data with
204 the information obtained during traversal
206 @param _nIncludeMask
207 set of TraversalParts bits, specifying which information is to be collected.
208 Note TraversalParts is currently not
210 void traverseSome( sal_uInt32 _nIncludeMask );
212 // The TableRangeMap contains all tables associated with the range name found first.
213 const OSQLTables& getTables() const;
215 ::rtl::Reference<OSQLColumns> getSelectColumns() const { return m_aSelectColumns;}
216 ::rtl::Reference<OSQLColumns> getGroupColumns() const { return m_aGroupColumns;}
217 ::rtl::Reference<OSQLColumns> getOrderColumns() const { return m_aOrderColumns;}
218 ::rtl::Reference<OSQLColumns> getParameters() const { return m_aParameters; }
219 ::rtl::Reference<OSQLColumns> getCreateColumns() const { return m_aCreateColumns;}
221 /** return the columname and the table range
222 @param _pColumnRef
223 The column ref parse node.
224 @param _rColumnName
225 The column name to be set.
226 @param _rTableRange
227 The table range to be set.
229 void getColumnRange( const OSQLParseNode* _pColumnRef,
230 OUString &_rColumnName,
231 OUString& _rTableRange) const;
233 /** retrieves a column's name, table range, and alias
235 @param _pColumnRef
236 The column_ref parse node.
237 @param _out_rColumnName
238 The column name to be set.
239 @param _out_rTableRange
240 The table range to be set.
241 @param _out_rColumnAliasIfPresent
242 If the column specified by _pColumnRef is part of the select columns, and contains a column alias there,
243 this alias is returned here.
245 void getColumnRange( const OSQLParseNode* _pColumnRef,
246 OUString& _out_rColumnName,
247 OUString& _out_rTableRange,
248 OUString& _out_rColumnAliasIfPresent
249 ) const;
251 /** return the alias name of a column
252 @param _pDerivedColumn
253 The parse node where SQL_ISRULE(_pDerivedColumn,derived_column) must be true
254 @return
255 The alias name of the column or an empty string.
257 static OUString getColumnAlias(const OSQLParseNode* _pDerivedColumn);
259 /** return the columname and the table range
260 @param _pColumnRef
261 The column ref parse node.
262 @param _xMetaData
263 The database meta data.
264 @param _rColumnName
265 The column name to be set.
266 @param _rTableRange
267 The table range to be set.
269 static void getColumnRange( const OSQLParseNode* _pColumnRef,
270 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
271 OUString &_rColumnName,
272 OUString& _rTableRange);
274 // empty if ambiguous
275 bool getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
277 // return true when the tableNode is a rule like catalog_name, schema_name or table_name
278 sal_Bool isTableNode(const OSQLParseNode* _pTableNode) const;
280 // tries to find the correct type of the function
281 sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode );
283 // returns a lis of all joined columns
284 ::std::vector< TNodePair >& getJoinConditions() const;
286 private:
287 // helper to implement getColumnTableRange
288 bool impl_getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
290 /** traverses the list of table names, and filles _rTables
292 bool traverseTableNames( OSQLTables& _rTables );
294 /// traverses columns in a SELECT statement
295 bool traverseSelectColumnNames(const OSQLParseNode* pSelectNode);
296 /// traverses columns in a CREATE TABLE statement
297 void traverseCreateColumns(const OSQLParseNode* pSelectNode);
299 bool traverseOrderByColumnNames(const OSQLParseNode* pSelectNode);
300 bool traverseGroupByColumnNames(const OSQLParseNode* pSelectNode);
302 bool traverseSelectionCriteria(const OSQLParseNode* pSelectNode);
304 private:
305 /** constructs a new iterator, which inherits some of the settings from a parent iterator
307 OSQLParseTreeIterator(
308 const OSQLParseTreeIterator& _rParentIterator,
309 const OSQLParser& _rParser,
310 const OSQLParseNode* pRoot );
312 /** creates a table object and inserts it into our tables collection
314 only used when we're iterating through a CREATE TABLE statement
316 OSQLTable impl_createTableObject(
317 const OUString& rTableName, const OUString& rCatalogName, const OUString& rSchemaName );
319 /** locates a record source (a table or query) with the given name
321 OSQLTable impl_locateRecordSource(
322 const OUString& _rComposedName
325 /** implementation for both traverseAll and traverseSome
327 void impl_traverse( sal_uInt32 _nIncludeMask );
329 /** retrieves the parameter columns of the given query
331 void impl_getQueryParameterColumns( const OSQLTable& _rQuery );
333 void setOrderByColumnName(const OUString & rColumnName, OUString & rTableRange, sal_Bool bAscending);
334 void setGroupByColumnName(const OUString & rColumnName, OUString & rTableRange);
336 private:
337 /** appends an SQLException corresponding to the given error code to our error collection
339 @param _eError
340 the code of the error which occurred
341 @param _pReplaceToken1
342 if not <NULL/>, the first occurrence of '#' in the error message will be replaced
343 with the given token
344 @param _pReplaceToken2
345 if not <NULL/>, and if _rReplaceToken1 is not <NULL/>, the second occurrence of '#'
346 in the error message will be replaced with _rReplaceToken2
348 void impl_appendError( IParseContext::ErrorCode _eError,
349 const OUString* _pReplaceToken1 = NULL, const OUString* _pReplaceToken2 = NULL );
351 /** appends an SQLException corresponding to the given error code to our error collection
353 void impl_appendError( const ::com::sun::star::sdbc::SQLException& _rError );
355 /** resets our errors
357 inline void impl_resetErrors()
359 m_aErrors = ::com::sun::star::sdbc::SQLException();
361 void impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition);
365 #endif // INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */