blob: 51ff4017da4883f82671b929ab99da9e2fb42d7c [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#ifndef _CONNECTIVITY_SQLPARSE_HXX
#define _CONNECTIVITY_SQLPARSE_HXX
#include <com/sun/star/uno/Reference.h>
#include <osl/mutex.hxx>
#include <connectivity/sqlnode.hxx>
#ifndef YYBISON
#ifndef FLEX_SCANNER
#ifndef BISON_INCLUDED
#define BISON_INCLUDED
#include "sqlbison.hxx"
#endif
#endif
#endif
#include <com/sun/star/i18n/XCharacterClassification.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/i18n/XLocaleData.hpp>
#include "connectivity/IParseContext.hxx"
#include "connectivity/dbtoolsdllapi.hxx"
#include <salhelper/singletonref.hxx>
#include <osl/mutex.hxx>
#include <map>
// forward declarations
namespace com
{
namespace sun
{
namespace star
{
namespace beans
{
class XPropertySet;
}
namespace util
{
class XNumberFormatter;
}
namespace lang
{
struct Locale;
}
}
}
}
namespace connectivity
{
class OSQLScanner;
class SQLError;
//==========================================================================
//= OParseContext
//==========================================================================
class OOO_DLLPUBLIC_DBTOOLS OParseContext : public IParseContext
{
public:
OParseContext();
virtual ~OParseContext();
// retrieves language specific error messages
virtual ::rtl::OUString getErrorMessage(ErrorCode _eCodes) const;
// retrieves language specific keyword strings (only ASCII allowed)
virtual ::rtl::OString getIntlKeywordAscii(InternationalKeyCode _eKey) const;
// finds out, if we have an international keyword (only ASCII allowed)
virtual InternationalKeyCode getIntlKeyCode(const ::rtl::OString& rToken) const;
// determines the default international setting
static const ::com::sun::star::lang::Locale& getDefaultLocale();
/** set's the default locale which should be used when analyzing strings
<p>If no locale is set, and any method which needs a locale is called, a default
(en-US) is used.</p>
<p>If, while parsing, the locale can be obtained from other sources (such as the number format
set for a table column), the preferred locale is ignored.</p>
*/
static void setDefaultLocale( const ::com::sun::star::lang::Locale& _rLocale );
/** get's a locale instance which should be used when parsing in the context specified by this instance
<p>if this is not overridden by derived classes, it returns the static default locale.</p>
*/
virtual ::com::sun::star::lang::Locale getPreferredLocale( ) const;
};
//==========================================================================
// OSQLParseNodesContainer
// grabage collection of nodes
//==========================================================================
class OSQLParseNodesContainer
{
::osl::Mutex m_aMutex;
::std::vector< OSQLParseNode* > m_aNodes;
public:
OSQLParseNodesContainer();
~OSQLParseNodesContainer();
void push_back(OSQLParseNode* _pNode);
void erase(OSQLParseNode* _pNode);
bool empty() const;
void clear();
void clearAndDelete();
};
typedef salhelper::SingletonRef<OSQLParseNodesContainer> OSQLParseNodesGarbageCollector;
//==========================================================================
//= OSQLParser
//==========================================================================
struct OSQLParser_Data;
/** Parser for SQL92
*/
class OOO_DLLPUBLIC_DBTOOLS OSQLParser
{
friend class OSQLParseNode;
friend class OSQLInternalNode;
friend struct SQLParseNodeParameter;
private:
typedef ::std::map< sal_uInt32, OSQLParseNode::Rule > RuleIDMap;
// static parts for parsers
static sal_uInt32 s_nRuleIDs[OSQLParseNode::rule_count + 1];
static RuleIDMap s_aReverseRuleIDLookup;
static OParseContext s_aDefaultContext;
static OSQLScanner* s_pScanner;
static OSQLParseNodesGarbageCollector* s_pGarbageCollector;
static sal_Int32 s_nRefCount;
// informations on the current parse action
const IParseContext* m_pContext;
OSQLParseNode* m_pParseTree; // result from parsing
::std::auto_ptr< OSQLParser_Data >
m_pData;
::rtl::OUString m_sFieldName; // current field name for a predicate
::rtl::OUString m_sErrorMessage;// current error msg
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
m_xField; // current field
::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >
m_xFormatter; // current number formatter
sal_Int32 m_nFormatKey; // numberformat, which should be used
sal_Int32 m_nDateFormatKey;
::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceFactory;
::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification> m_xCharClass;
static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData> s_xLocaleData;
::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData> xDummy; // can be deleted after 627
// convert a string into double trim it to scale of _nscale and than transform it back to string
::rtl::OUString stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale);
OSQLParseNode* buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral);
bool extractDate(OSQLParseNode* pLiteral,double& _rfValue);
void killThousandSeparator(OSQLParseNode* pLiteral);
OSQLParseNode* convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral);
// makes a string out of a number, pLiteral will be deleted
OSQLParseNode* buildNode_STR_NUM(OSQLParseNode*& pLiteral);
OSQLParseNode* buildNode_Date(const double& fValue, sal_Int32 nType);
static ::osl::Mutex& getMutex();
public:
// if NULL, a default context will be used
// the context must live as long as the parser
OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext = NULL);
~OSQLParser();
// Parsing an SQLStatement
OSQLParseNode* parseTree(::rtl::OUString& rErrorMessage,
const ::rtl::OUString& rStatement,
sal_Bool bInternational = sal_False);
// Check a Predicate
OSQLParseNode* predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement,
const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xField);
// Access to the context
const IParseContext& getContext() const {return *m_pContext;}
/// access to the SQLError instance owned by this parser
const SQLError& getErrorHelper() const;
// TokenIDToStr: Token-Name zu einer Token-Nr.
static ::rtl::OString TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext = NULL);
// StrToTokenID: Token-Nr. zu einem Token-Namen.
// static sal_uInt32 StrToTokenID(const ::rtl::OString & rName);
// RuleIDToStr gibt den zu einer RuleID gehoerenden ::rtl::OUString zurueck
// (Leerstring, falls nicht gefunden)
static ::rtl::OUString RuleIDToStr(sal_uInt32 nRuleID);
// StrToRuleID berechnet zu einem ::rtl::OUString die RuleID (d.h. ::com::sun::star::sdbcx::Index in yytname)
// (0, falls nicht gefunden). Die Suche nach der ID aufgrund eines Strings ist
// extrem ineffizient (sequentielle Suche nach ::rtl::OUString)!
static sal_uInt32 StrToRuleID(const ::rtl::OString & rValue);
static OSQLParseNode::Rule RuleIDToRule( sal_uInt32 _nRule );
// RuleId mit enum, wesentlich effizienter
static sal_uInt32 RuleID(OSQLParseNode::Rule eRule);
// compares the _sFunctionName with all known function names and return the DataType of the return value
static sal_Int32 getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext = NULL);
// returns the type for a parameter in a given function name
static sal_Int32 getFunctionParameterType(sal_uInt32 _nTokenId,sal_uInt32 _nPos);
void error( const sal_Char* pFormat);
int SQLlex();
#ifdef YYBISON
void setParseTree(OSQLParseNode * pNewParseTree);
// Is the parse in a special mode?
// Predicate chack is used to check a condition for a field
sal_Bool inPredicateCheck() const {return m_xField.is();}
const ::rtl::OUString& getFieldName() const {return m_sFieldName;}
void reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank);
// does not change the pLiteral argument
sal_Int16 buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pCompare,OSQLParseNode* pLiteral,OSQLParseNode* pLiteral2);
sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral);
// pCompre will be deleted if it is not used
sal_Int16 buildPredicateRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare,OSQLParseNode* pLiteral2 = NULL);
sal_Int16 buildLikeRule(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,const OSQLParseNode* pEscape);
sal_Int16 buildStringNodes(OSQLParseNode*& pLiteral);
#else
#endif
};
}
#endif //_CONNECTIVITY_SQLPARSE_HXX