Files
libreoffice/include/connectivity/sqliterator.hxx

368 lines
17 KiB
C++
Raw Normal View History

2010-10-27 13:11:31 +01:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2012-06-12 22:04:38 +01:00
/*
* 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 .
*/
2000-09-18 15:18:56 +00:00
#ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
#define _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
CWS-TOOLING: integrate CWS sb102 2008-12-11 16:18:12 +0100 sb r265332 : #i95065# cleanup, to make Windows linking work 2008-12-11 16:16:03 +0100 sb r265331 : #i95065# missing SAL_DLLPUBLIC_EXPORT 2008-12-09 17:40:28 +0100 sb r265122 : #i94469# move CJK specific configuration data to brand layer 2008-12-09 16:09:08 +0100 sb r265112 : #i96959# use PTHREAD_MUTEX_RECURSIVE on all platforms 2008-12-09 15:54:31 +0100 sb r265110 : #i95065# do not derive apphelper::LifeTimeGuard from osl::ResettableMutexGuard to avoid problems with VISIBILITY_HIDDEN=TRUE on MSC 2008-12-09 15:40:51 +0100 sb r265104 : #i95065# add VISIBILITY_HIDDEN=TRUE to connectivity/source/drivers/mozab 2008-12-09 15:36:21 +0100 sb r265102 : #i95501# updated SDK_HOME 2008-12-09 15:31:46 +0100 sb r265099 : typo (temppath vs. tmppath) 2008-12-08 11:48:08 +0100 sb r264979 : #i95065# removed spurious ExplicitCategoriesProvider.obj (ExplicitCategoriesProvider.cxx is not in this directory) 2008-12-07 19:41:07 +0100 sb r264960 : #i96994# erroneously doubled backslash caused visibility feature to be disabled for all GCC versions on Mac OS X 2008-12-06 23:54:49 +0100 sb r264948 : changes from trunk that CWS-TOOLING's rebase to DEV300:m37 (r264891) had missed, as files had been moved around on this CWS 2008-12-05 20:29:23 +0100 sb r264919 : #i85508# versions of flex apparently differ in whether input() resp. yyinput() returns zero or EOF upon end of file 2008-12-05 15:37:23 +0100 sb r264908 : #i95315# removed obsolete jut 2008-12-05 15:34:59 +0100 sb r264907 : #i95531# removed empty obsolete directories 2008-12-05 10:09:23 +0100 sb r264891 : CWS-TOOLING: rebase CWS sb102 to trunk@264807 (milestone: DEV300:m37) 2008-12-04 14:50:20 +0100 sb r264845 : #i95065# introduced VISIBILITY_HIDDEN makefile flag to reduce duplications; made additional libraries use VISIBILITY_HIDDEN=TRUE to avoid warnings with recent GCC 4 versions (had to split certain code directories to make changes that would otherwise erroneously affect multiple libraries built in the same makefile); changed connectivity::ORefVector to no longer derive from std::vector, as that caused problems with the MSC implementation of VISIBILITY_HIDDEN=TRUE; replaced uses of JNIEXPORT with SAL_DLLPUBLIC_EXPORT, as the former does not expand to visibility attributes on some platforms where the latter does 2008-12-03 11:29:38 +0100 sb r264759 : #i94583# remove unnecessary (and wrong) assertion check for rtl_getAppCommandArg return value (which is guaranteed to return osl_Process_E_None or not return at all) 2008-12-02 17:18:31 +0100 sb r264724 : #i96809# silenced GCC 4.3.2 warning 2008-12-02 13:29:34 +0100 sb r264695 : #i96797# make get_tmp_dir fail less often 2008-11-28 17:19:24 +0100 sb r264566 : #i95691# inadvertently missing from -c 264564 2008-11-28 17:07:50 +0100 sb r264564 : #i95691# only structs of exactly 1, 2, 4, or 8 bytes are returned through registers 2008-11-25 13:28:08 +0100 sb r264291 : #i96427# support for SAL_EXCEPTION_DLLPUBLIC_EXPORT (patch by np) 2008-11-21 14:45:22 +0100 sb r264140 : #i95428# added SAL_EXCEPTION_DLLPUBLIC_EXPORT and SAL_EXCEPTION_DLLPRIVATE 2008-11-19 13:19:37 +0100 sb r263984 : #i95525# removed erroneous application/octet-stream svn:mime-type properties
2008-12-30 13:32:01 +00:00
#include "connectivity/dbtoolsdllapi.hxx"
2000-09-18 15:18:56 +00:00
#include "connectivity/sqlnode.hxx"
#include <connectivity/IParseContext.hxx>
2000-09-18 15:18:56 +00:00
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
2001-02-23 13:54:11 +00:00
#include <com/sun/star/sdbc/SQLWarning.hpp>
2000-09-18 15:18:56 +00:00
#include <com/sun/star/beans/XPropertySet.hpp>
#include "connectivity/CommonTools.hxx"
2010-10-15 12:10:06 -05:00
#include <rtl/ref.hxx>
2000-09-18 15:18:56 +00:00
#include <cppuhelper/weak.hxx>
#include <map>
#include <memory>
#include <vector>
2000-09-18 15:18:56 +00:00
namespace connectivity
{
class OSQLParseNode;
class OSQLParser;
2000-09-18 15:18:56 +00:00
typedef ::std::pair<const OSQLParseNode*,const OSQLParseNode* > TNodePair;
2000-09-18 15:18:56 +00:00
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
2000-09-18 15:18:56 +00:00
};
struct OSQLParseTreeIteratorImpl;
2000-09-18 15:18:56 +00:00
CWS-TOOLING: integrate CWS sb102 2008-12-11 16:18:12 +0100 sb r265332 : #i95065# cleanup, to make Windows linking work 2008-12-11 16:16:03 +0100 sb r265331 : #i95065# missing SAL_DLLPUBLIC_EXPORT 2008-12-09 17:40:28 +0100 sb r265122 : #i94469# move CJK specific configuration data to brand layer 2008-12-09 16:09:08 +0100 sb r265112 : #i96959# use PTHREAD_MUTEX_RECURSIVE on all platforms 2008-12-09 15:54:31 +0100 sb r265110 : #i95065# do not derive apphelper::LifeTimeGuard from osl::ResettableMutexGuard to avoid problems with VISIBILITY_HIDDEN=TRUE on MSC 2008-12-09 15:40:51 +0100 sb r265104 : #i95065# add VISIBILITY_HIDDEN=TRUE to connectivity/source/drivers/mozab 2008-12-09 15:36:21 +0100 sb r265102 : #i95501# updated SDK_HOME 2008-12-09 15:31:46 +0100 sb r265099 : typo (temppath vs. tmppath) 2008-12-08 11:48:08 +0100 sb r264979 : #i95065# removed spurious ExplicitCategoriesProvider.obj (ExplicitCategoriesProvider.cxx is not in this directory) 2008-12-07 19:41:07 +0100 sb r264960 : #i96994# erroneously doubled backslash caused visibility feature to be disabled for all GCC versions on Mac OS X 2008-12-06 23:54:49 +0100 sb r264948 : changes from trunk that CWS-TOOLING's rebase to DEV300:m37 (r264891) had missed, as files had been moved around on this CWS 2008-12-05 20:29:23 +0100 sb r264919 : #i85508# versions of flex apparently differ in whether input() resp. yyinput() returns zero or EOF upon end of file 2008-12-05 15:37:23 +0100 sb r264908 : #i95315# removed obsolete jut 2008-12-05 15:34:59 +0100 sb r264907 : #i95531# removed empty obsolete directories 2008-12-05 10:09:23 +0100 sb r264891 : CWS-TOOLING: rebase CWS sb102 to trunk@264807 (milestone: DEV300:m37) 2008-12-04 14:50:20 +0100 sb r264845 : #i95065# introduced VISIBILITY_HIDDEN makefile flag to reduce duplications; made additional libraries use VISIBILITY_HIDDEN=TRUE to avoid warnings with recent GCC 4 versions (had to split certain code directories to make changes that would otherwise erroneously affect multiple libraries built in the same makefile); changed connectivity::ORefVector to no longer derive from std::vector, as that caused problems with the MSC implementation of VISIBILITY_HIDDEN=TRUE; replaced uses of JNIEXPORT with SAL_DLLPUBLIC_EXPORT, as the former does not expand to visibility attributes on some platforms where the latter does 2008-12-03 11:29:38 +0100 sb r264759 : #i94583# remove unnecessary (and wrong) assertion check for rtl_getAppCommandArg return value (which is guaranteed to return osl_Process_E_None or not return at all) 2008-12-02 17:18:31 +0100 sb r264724 : #i96809# silenced GCC 4.3.2 warning 2008-12-02 13:29:34 +0100 sb r264695 : #i96797# make get_tmp_dir fail less often 2008-11-28 17:19:24 +0100 sb r264566 : #i95691# inadvertently missing from -c 264564 2008-11-28 17:07:50 +0100 sb r264564 : #i95691# only structs of exactly 1, 2, 4, or 8 bytes are returned through registers 2008-11-25 13:28:08 +0100 sb r264291 : #i96427# support for SAL_EXCEPTION_DLLPUBLIC_EXPORT (patch by np) 2008-11-21 14:45:22 +0100 sb r264140 : #i95428# added SAL_EXCEPTION_DLLPUBLIC_EXPORT and SAL_EXCEPTION_DLLPRIVATE 2008-11-19 13:19:37 +0100 sb r263984 : #i95525# removed erroneous application/octet-stream svn:mime-type properties
2008-12-30 13:32:01 +00:00
class OOO_DLLPUBLIC_DBTOOLS OSQLParseTreeIterator
2000-09-18 15:18:56 +00:00
{
2001-02-23 13:54:11 +00:00
private:
::com::sun::star::sdbc::SQLException m_aErrors; // conatins the error while iterating through the statement
2011-01-31 11:11:14 +00:00
const OSQLParseNode* m_pParseTree; // current ParseTree
const OSQLParser& m_rParser; // if set used for general error messages from the context
2011-01-31 11:11:14 +00:00
OSQLStatementType m_eStatementType;
::rtl::Reference<OSQLColumns> m_aSelectColumns; // all columns from the Select clause
2010-10-15 12:10:06 -05:00
::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);
2011-01-31 11:11:14 +00:00
// inserts a table into the map
void traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const OUString & rTableRange );
void traverseSearchCondition(OSQLParseNode * pSearchCondition);
2000-09-18 15:18:56 +00:00
void traverseOnePredicate(
OSQLParseNode * pColumnRef,
OUString& aValue,
2000-09-18 15:18:56 +00:00
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 );
/** finds a column with a given name among the select columns
@param rColumnName
the column name to look for
@return
*/
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findSelectColumn(
const OUString & rColumnName );
2000-09-18 15:18:56 +00:00
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);
2011-01-31 11:11:14 +00:00
// 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.
2000-09-18 15:18:56 +00:00
private:
OSQLParseTreeIterator(); // never implemented
OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter); // never implemented
2000-09-18 15:18:56 +00:00
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 );
2000-09-18 15:18:56 +00:00
~OSQLParseTreeIterator();
2012-01-26 16:00:09 +01:00
inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
{ return ::rtl_allocateMemory( nSize ); }
2012-01-26 16:00:09 +01:00
inline static void * SAL_CALL operator new( size_t,void* _pHint ) SAL_THROW(())
{ return _pHint; }
2012-01-26 16:00:09 +01:00
inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
{ ::rtl_freeMemory( pMem ); }
2012-01-26 16:00:09 +01:00
inline static void SAL_CALL operator delete( void *,void* ) SAL_THROW(())
{ }
2000-11-03 12:25:37 +00:00
void dispose();
bool isCaseSensitive() const;
2011-01-31 11:11:14 +00:00
// The parse tree to be analysed/traversed:
// If NULL is passed, the current parse tree will be deleted and the error status cleared.
2000-09-18 15:18:56 +00:00
void setParseTree(const OSQLParseNode * pNewParseTree);
// void setParser(const OSQLParser* _pParser) { m_pParser = _pParser; }
2000-09-18 15:18:56 +00:00
const OSQLParseNode * getParseTree() const { return m_pParseTree; };
2011-01-31 11:11:14 +00:00
// subtrees in case of a select statement
2000-09-18 15:18:56 +00:00
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;
2010-12-04 13:16:21 +09:00
/** 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(); }
2011-01-31 11:11:14 +00:00
// statement type (already set in setParseTree):
2000-09-18 15:18:56 +00:00
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).
*/
2000-09-18 15:18:56 +00:00
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 );
2011-01-31 11:11:14 +00:00
// The TableRangeMap contains all tables associated with the range name found first.
const OSQLTables& getTables() const;
2000-09-18 15:18:56 +00:00
2010-10-15 12:10:06 -05:00
::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;}
2002-07-15 11:34:56 +00:00
/** 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;
2002-07-15 11:34:56 +00:00
/** 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;
2002-07-15 11:34:56 +00:00
/** 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);
2002-07-15 11:34:56 +00:00
/** 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);
2000-09-18 15:18:56 +00:00
2011-01-31 11:11:14 +00:00
// empty if ambiguous
bool getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
2001-01-09 12:11:07 +00:00
// 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:
// helper to implement getColumnTableRange
bool impl_getColumnTableRange(const OSQLParseNode* pNode, OUString &rTableRange) const;
/** 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
2010-12-04 13:16:21 +09:00
the code of the error which occurred
@param _pReplaceToken1
2010-12-04 13:16:21 +09:00
if not <NULL/>, the first occurrence of '#' in the error message will be replaced
with the given token
@param _pReplaceToken2
2010-12-04 13:16:21 +09:00
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);
2000-09-18 15:18:56 +00:00
};
}
#endif // _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
2010-10-27 13:11:31 +01:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */