summaryrefslogtreecommitdiff
path: root/include/connectivity/sqliterator.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'include/connectivity/sqliterator.hxx')
-rw-r--r--include/connectivity/sqliterator.hxx356
1 files changed, 356 insertions, 0 deletions
diff --git a/include/connectivity/sqliterator.hxx b/include/connectivity/sqliterator.hxx
new file mode 100644
index 000000000000..ee967dd7d7a3
--- /dev/null
+++ b/include/connectivity/sqliterator.hxx
@@ -0,0 +1,356 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
+#define _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
+
+#include "connectivity/dbtoolsdllapi.hxx"
+#include "connectivity/sqlnode.hxx"
+#include <connectivity/IParseContext.hxx>
+#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
+#include <com/sun/star/sdbc/DataType.hpp>
+#include <com/sun/star/sdbc/SQLWarning.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "connectivity/CommonTools.hxx"
+#include <rtl/ref.hxx>
+#include <cppuhelper/weak.hxx>
+
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace connectivity
+{
+
+ class OSQLParseNode;
+ class OSQLParser;
+
+ typedef ::std::pair<const OSQLParseNode*,const OSQLParseNode* > TNodePair;
+
+ enum OSQLStatementType {
+ SQL_STATEMENT_UNKNOWN,
+ SQL_STATEMENT_SELECT,
+ SQL_STATEMENT_INSERT,
+ SQL_STATEMENT_UPDATE,
+ SQL_STATEMENT_DELETE,
+ SQL_STATEMENT_ODBC_CALL,
+ SQL_STATEMENT_CREATE_TABLE
+ };
+
+ struct OSQLParseTreeIteratorImpl;
+
+ class OOO_DLLPUBLIC_DBTOOLS OSQLParseTreeIterator
+ {
+ private:
+ ::com::sun::star::sdbc::SQLException m_aErrors; // conatins the error while iterating through the statement
+ const OSQLParseNode* m_pParseTree; // current ParseTree
+ const OSQLParser& m_rParser; // if set used for general error messages from the context
+ OSQLStatementType m_eStatementType;
+ ::rtl::Reference<OSQLColumns> m_aSelectColumns; // all columns from the Select clause
+ ::rtl::Reference<OSQLColumns> m_aParameters; // all parameters
+ ::rtl::Reference<OSQLColumns> m_aGroupColumns; // the group by columns
+ ::rtl::Reference<OSQLColumns> m_aOrderColumns; // the order by columns
+ ::rtl::Reference<OSQLColumns> m_aCreateColumns; // the columns for Create table clause
+
+ ::std::auto_ptr< OSQLParseTreeIteratorImpl > m_pImpl;
+
+ void traverseParameter(const OSQLParseNode* _pParseNode,const OSQLParseNode* _pColumnRef,const OUString& _aColumnName, OUString& _aTableRange, const OUString& _rColumnAlias);
+ // inserts a table into the map
+ void traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const OUString & rTableRange );
+ void traverseSearchCondition(OSQLParseNode * pSearchCondition);
+ void traverseOnePredicate(
+ OSQLParseNode * pColumnRef,
+ OUString& aValue,
+ OSQLParseNode * pParameter);
+ void traverseByColumnNames(const OSQLParseNode* pSelectNode,sal_Bool _bOrder);
+ void traverseParameters(const OSQLParseNode* pSelectNode);
+
+ const OSQLParseNode* getTableNode( OSQLTables& _rTables, const OSQLParseNode* pTableRef, OUString& aTableRange );
+ void getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, OUString& aTableRange );
+ void getSelect_statement(OSQLTables& _rTables,const OSQLParseNode* pSelect);
+ OUString getUniqueColumnName(const OUString & rColumnName) const;
+
+ /** finds the column with a given name, belonging to a given table, in a given tables collection
+ @param _rTables
+ the tables collection to look in
+ @param rColumnName
+ the column name to look for
+ @param rTableRange
+ the table alias name; if empty, look in all tables
+ @return
+ the desired column object, or <NULL/> if no such column could be found
+ */
+ static ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
+ const OSQLTables& _rTables, const OUString & rColumnName, OUString & rTableRange );
+
+ /** finds a column with a given name, belonging to a given table
+ @param rColumnName
+ the column name to look for
+ @param rTableRange
+ the table alias name; if empty, look in all tables
+ @param _bLookInSubTables
+ <TRUE/> if and only if not only our direct tables, but also our sub tables (from sub selects)
+ should be searched
+ @return
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
+ const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables );
+
+ protected:
+ 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);
+ void appendColumns(::rtl::Reference<OSQLColumns>& _rColumns,const OUString& _rTableAlias,const OSQLTable& _rTable);
+ // Other member variables that should be available in the "set" functions
+ // can be defined in the derived class. They can be initialized
+ // in its constructor and, after the "traverse" routines have been used,
+ // they can be queried using other functions.
+
+
+ private:
+ OSQLParseTreeIterator(); // never implemented
+ OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter); // never implemented
+
+ public:
+ OSQLParseTreeIterator(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxTables,
+ const OSQLParser& _rParser,
+ const OSQLParseNode* pRoot = NULL );
+ ~OSQLParseTreeIterator();
+
+ inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
+ { return ::rtl_allocateMemory( nSize ); }
+ inline static void * SAL_CALL operator new( size_t,void* _pHint ) SAL_THROW(())
+ { return _pHint; }
+ inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
+ { ::rtl_freeMemory( pMem ); }
+ inline static void SAL_CALL operator delete( void *,void* ) SAL_THROW(())
+ { }
+
+ void dispose();
+ bool isCaseSensitive() const;
+ // The parse tree to be analysed/traversed:
+ // If NULL is passed, the current parse tree will be deleted and the error status cleared.
+ void setParseTree(const OSQLParseNode * pNewParseTree);
+// void setParser(const OSQLParser* _pParser) { m_pParser = _pParser; }
+ const OSQLParseNode * getParseTree() const { return m_pParseTree; };
+
+ // subtrees in case of a select statement
+ const OSQLParseNode* getWhereTree() const;
+ const OSQLParseNode* getOrderTree() const;
+ const OSQLParseNode* getGroupByTree() const;
+ const OSQLParseNode* getHavingTree() const;
+
+ const OSQLParseNode* getSimpleWhereTree() const;
+ const OSQLParseNode* getSimpleOrderTree() const;
+ const OSQLParseNode* getSimpleGroupByTree() const;
+ const OSQLParseNode* getSimpleHavingTree() const;
+
+ /** returns the errors which occurred during parsing.
+
+ The returned object contains a chain (via SQLException::NextException) of SQLExceptions.
+ */
+ inline const ::com::sun::star::sdbc::SQLException& getErrors() const { return m_aErrors; }
+ inline bool hasErrors() const { return !m_aErrors.Message.isEmpty(); }
+
+ // statement type (already set in setParseTree):
+ OSQLStatementType getStatementType() const { return m_eStatementType; }
+
+ /** traverses the complete statement tree, and fills all our data with
+ the information obatined during traversal.
+
+ Implemented by calling the single traverse* methods in the proper
+ order (depending on the statement type).
+ */
+ void traverseAll();
+
+ enum TraversalParts
+ {
+ Parameters = 0x0001,
+ TableNames = 0x0002,
+ SelectColumns = 0x0006, // note that this includes TableNames. No SelectColumns without TableNames
+
+ // Those are not implemented currently
+ // GroupColumns = 0x0008,
+ // OrderColumns = 0x0010,
+ // SelectColumns = 0x0020,
+ // CreateColumns = 0x0040,
+
+ All = 0xFFFF
+ };
+ /** traverses selected parts of the statement tree, and fills our data with
+ the information obtained during traversal
+
+ @param _nIncludeMask
+ set of TraversalParts bits, specifying which information is to be collected.
+ Note TraversalParts is currently not
+ */
+ void traverseSome( sal_uInt32 _nIncludeMask );
+
+ // The TableRangeMap contains all tables associated with the range name found first.
+ const OSQLTables& getTables() const;
+
+ ::rtl::Reference<OSQLColumns> getSelectColumns() const { return m_aSelectColumns;}
+ ::rtl::Reference<OSQLColumns> getGroupColumns() const { return m_aGroupColumns;}
+ ::rtl::Reference<OSQLColumns> getOrderColumns() const { return m_aOrderColumns;}
+ ::rtl::Reference<OSQLColumns> getParameters() const { return m_aParameters; }
+ ::rtl::Reference<OSQLColumns> getCreateColumns() const { return m_aCreateColumns;}
+
+ /** return the columname and the table range
+ @param _pColumnRef
+ The column ref parse node.
+ @param _rColumnName
+ The column name to be set.
+ @param _rTableRange
+ The table range to be set.
+ */
+ void getColumnRange( const OSQLParseNode* _pColumnRef,
+ OUString &_rColumnName,
+ OUString& _rTableRange) const;
+
+ /** retrieves a column's name, table range, and alias
+
+ @param _pColumnRef
+ The column_ref parse node.
+ @param _out_rColumnName
+ The column name to be set.
+ @param _out_rTableRange
+ The table range to be set.
+ @param _out_rColumnAliasIfPresent
+ If the column specified by _pColumnRef is part of the select columns, and contains a column alias there,
+ this alias is returned here.
+ */
+ void getColumnRange( const OSQLParseNode* _pColumnRef,
+ OUString& _out_rColumnName,
+ OUString& _out_rTableRange,
+ OUString& _out_rColumnAliasIfPresent
+ ) const;
+
+ /** return the alias name of a column
+ @param _pDerivedColumn
+ The parse node where SQL_ISRULE(_pDerivedColumn,derived_column) must be true
+ @return
+ The alias name of the column or an empty string.
+ */
+ static OUString getColumnAlias(const OSQLParseNode* _pDerivedColumn);
+
+ /** return the columname and the table range
+ @param _pColumnRef
+ The column ref parse node.
+ @param _xMetaData
+ The database meta data.
+ @param _rColumnName
+ The column name to be set.
+ @param _rTableRange
+ The table range to be set.
+ */
+ static void getColumnRange( const OSQLParseNode* _pColumnRef,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
+ OUString &_rColumnName,
+ OUString& _rTableRange);
+
+ // empty if ambiguous
+ sal_Bool getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
+
+ // return true when the tableNode is a rule like catalog_name, schema_name or table_name
+ sal_Bool isTableNode(const OSQLParseNode* _pTableNode) const;
+
+ // tries to find the correct type of the function
+ sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode );
+
+ // returns a lis of all joined columns
+ ::std::vector< TNodePair >& getJoinConditions() const;
+
+ private:
+ /** traverses the list of table names, and filles _rTables
+ */
+ bool traverseTableNames( OSQLTables& _rTables );
+
+ /// traverses columns in a SELECT statement
+ bool traverseSelectColumnNames(const OSQLParseNode* pSelectNode);
+ /// traverses columns in a CREATE TABLE statement
+ void traverseCreateColumns(const OSQLParseNode* pSelectNode);
+
+ bool traverseOrderByColumnNames(const OSQLParseNode* pSelectNode);
+ bool traverseGroupByColumnNames(const OSQLParseNode* pSelectNode);
+
+ bool traverseSelectionCriteria(const OSQLParseNode* pSelectNode);
+
+ private:
+ /** constructs a new iterator, which inherits some of the settings from a parent iterator
+ */
+ OSQLParseTreeIterator(
+ const OSQLParseTreeIterator& _rParentIterator,
+ const OSQLParser& _rParser,
+ const OSQLParseNode* pRoot );
+
+ /** creates a table object and inserts it into our tables collection
+
+ only used when we're iterating through a CREATE TABLE statement
+ */
+ OSQLTable impl_createTableObject(
+ const OUString& rTableName, const OUString& rCatalogName, const OUString& rSchemaName );
+
+ /** locates a record source (a table or query) with the given name
+ */
+ OSQLTable impl_locateRecordSource(
+ const OUString& _rComposedName
+ );
+
+ /** implementation for both traverseAll and traverseSome
+ */
+ void impl_traverse( sal_uInt32 _nIncludeMask );
+
+ /** retrieves the parameter columns of the given query
+ */
+ void impl_getQueryParameterColumns( const OSQLTable& _rQuery );
+
+ void setOrderByColumnName(const OUString & rColumnName, OUString & rTableRange, sal_Bool bAscending);
+ void setGroupByColumnName(const OUString & rColumnName, OUString & rTableRange);
+
+ private:
+ /** appends an SQLException corresponding to the given error code to our error collection
+
+ @param _eError
+ the code of the error which occurred
+ @param _pReplaceToken1
+ if not <NULL/>, the first occurrence of '#' in the error message will be replaced
+ with the given token
+ @param _pReplaceToken2
+ if not <NULL/>, and if _rReplaceToken1 is not <NULL/>, the second occurrence of '#'
+ in the error message will be replaced with _rReplaceToken2
+ */
+ void impl_appendError( IParseContext::ErrorCode _eError,
+ const OUString* _pReplaceToken1 = NULL, const OUString* _pReplaceToken2 = NULL );
+
+ /** appends an SQLException corresponding to the given error code to our error collection
+ */
+ void impl_appendError( const ::com::sun::star::sdbc::SQLException& _rError );
+
+ /** resets our errors
+ */
+ inline void impl_resetErrors()
+ {
+ m_aErrors = ::com::sun::star::sdbc::SQLException();
+ }
+ void impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition);
+ };
+}
+
+#endif // _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */