1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
37 namespace connectivity
43 typedef ::std::pair
<const OSQLParseNode
*,const OSQLParseNode
* > TNodePair
;
45 enum OSQLStatementType
{
46 SQL_STATEMENT_UNKNOWN
,
51 SQL_STATEMENT_ODBC_CALL
,
52 SQL_STATEMENT_CREATE_TABLE
55 struct OSQLParseTreeIteratorImpl
;
57 class OOO_DLLPUBLIC_DBTOOLS OSQLParseTreeIterator
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
,
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
90 the tables collection to look in
92 the column name to look for
94 the table alias name; if empty, look in all tables
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
103 the column name to look for
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)
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
116 the column name to look for
119 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> findSelectColumn(
120 const OUString
& rColumnName
);
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.
132 OSQLParseTreeIterator(); // never implemented
133 OSQLParseTreeIterator(const OSQLParseTreeIterator
& rIter
); // never implemented
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(())
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(())
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).
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,
203 /** traverses selected parts of the statement tree, and fills our data with
204 the information obtained during traversal
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
223 The column ref parse node.
225 The column name to be set.
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
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
251 /** return the alias name of a column
252 @param _pDerivedColumn
253 The parse node where SQL_ISRULE(_pDerivedColumn,derived_column) must be true
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
261 The column ref parse node.
263 The database meta data.
265 The column name to be set.
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;
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
);
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
);
337 /** appends an SQLException corresponding to the given error code to our error collection
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
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: */