1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #ifndef _CONNECTIVITY_SQLPARSE_HXX 24 #define _CONNECTIVITY_SQLPARSE_HXX 25 26 #include <com/sun/star/uno/Reference.h> 27 #include <osl/mutex.hxx> 28 #include <connectivity/sqlnode.hxx> 29 #ifndef YYBISON 30 #ifndef FLEX_SCANNER 31 #ifndef BISON_INCLUDED 32 #define BISON_INCLUDED 33 #include "sqlbison.hxx" 34 #endif 35 #endif 36 #endif 37 #include <com/sun/star/i18n/XCharacterClassification.hpp> 38 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 39 #include <com/sun/star/i18n/XLocaleData.hpp> 40 #include <com/sun/star/lang/Locale.hpp> 41 #include "connectivity/IParseContext.hxx" 42 #include "connectivity/dbtoolsdllapi.hxx" 43 #include "connectivity/sqlerror.hxx" 44 #include <salhelper/singletonref.hxx> 45 #include <osl/mutex.hxx> 46 47 #include <map> 48 49 // forward declarations 50 namespace com 51 { 52 namespace sun 53 { 54 namespace star 55 { 56 namespace beans 57 { 58 class XPropertySet; 59 } 60 namespace util 61 { 62 class XNumberFormatter; 63 } 64 namespace lang 65 { 66 struct Locale; 67 } 68 } 69 } 70 } 71 namespace connectivity 72 { 73 class OSQLScanner; 74 class SQLError; 75 76 //========================================================================== 77 //= OParseContext 78 //========================================================================== 79 class OOO_DLLPUBLIC_DBTOOLS OParseContext : public IParseContext 80 { 81 public: 82 OParseContext(); 83 84 virtual ~OParseContext(); 85 // retrieves language specific error messages 86 virtual ::rtl::OUString getErrorMessage(ErrorCode _eCodes) const; 87 88 // retrieves language specific keyword strings (only ASCII allowed) 89 virtual ::rtl::OString getIntlKeywordAscii(InternationalKeyCode _eKey) const; 90 91 // finds out, if we have an international keyword (only ASCII allowed) 92 virtual InternationalKeyCode getIntlKeyCode(const ::rtl::OString& rToken) const; 93 94 // determines the default international setting 95 static const ::com::sun::star::lang::Locale& getDefaultLocale(); 96 97 /** set's the default locale which should be used when analyzing strings 98 <p>If no locale is set, and any method which needs a locale is called, a default 99 (en-US) is used.</p> 100 <p>If, while parsing, the locale can be obtained from other sources (such as the number format 101 set for a table column), the preferred locale is ignored.</p> 102 */ 103 static void setDefaultLocale( const ::com::sun::star::lang::Locale& _rLocale ); 104 105 /** get's a locale instance which should be used when parsing in the context specified by this instance 106 <p>if this is not overridden by derived classes, it returns the static default locale.</p> 107 */ 108 virtual ::com::sun::star::lang::Locale getPreferredLocale( ) const; 109 }; 110 111 //========================================================================== 112 // OSQLParseNodesContainer 113 // grabage collection of nodes 114 //========================================================================== 115 class OSQLParseNodesContainer 116 { 117 ::osl::Mutex m_aMutex; 118 ::std::vector< OSQLParseNode* > m_aNodes; 119 public: 120 OSQLParseNodesContainer(); 121 ~OSQLParseNodesContainer(); 122 123 void push_back(OSQLParseNode* _pNode); 124 void erase(OSQLParseNode* _pNode); 125 bool empty() const; 126 void clear(); 127 void clearAndDelete(); 128 }; 129 130 typedef salhelper::SingletonRef<OSQLParseNodesContainer> OSQLParseNodesGarbageCollector; 131 132 //========================================================================== 133 //= OSQLParser 134 //========================================================================== 135 struct OSQLParser_Data 136 { 137 ::com::sun::star::lang::Locale aLocale; 138 ::connectivity::SQLError aErrors; 139 140 OSQLParser_Data( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory ); 141 142 }; 143 /** Parser for SQL92 144 */ 145 class OOO_DLLPUBLIC_DBTOOLS OSQLParser 146 { 147 friend class OSQLParseNode; 148 friend class OSQLInternalNode; 149 friend struct SQLParseNodeParameter; 150 151 private: 152 typedef ::std::map< sal_uInt32, OSQLParseNode::Rule > RuleIDMap; 153 // static parts for parsers 154 static sal_uInt32 s_nRuleIDs[OSQLParseNode::rule_count + 1]; 155 static RuleIDMap s_aReverseRuleIDLookup; 156 static OParseContext s_aDefaultContext; 157 158 static OSQLScanner* s_pScanner; 159 static OSQLParseNodesGarbageCollector* s_pGarbageCollector; 160 static sal_Int32 s_nRefCount; 161 162 // informations on the current parse action 163 const IParseContext* m_pContext; 164 OSQLParseNode* m_pParseTree; // result from parsing 165 ::std::auto_ptr< OSQLParser_Data > 166 m_pData; 167 ::rtl::OUString m_sFieldName; // current field name for a predicate 168 ::rtl::OUString m_sErrorMessage;// current error msg 169 170 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > 171 m_xField; // current field 172 ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > 173 m_xFormatter; // current number formatter 174 sal_Int32 m_nFormatKey; // numberformat, which should be used 175 sal_Int32 m_nDateFormatKey; 176 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceFactory; 177 ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification> m_xCharClass; 178 static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData> s_xLocaleData; 179 ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData> xDummy; // can be deleted after 627 180 181 // convert a string into double trim it to scale of _nscale and than transform it back to string 182 ::rtl::OUString stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale); 183 OSQLParseNode* buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral); 184 bool extractDate(OSQLParseNode* pLiteral,double& _rfValue); 185 void killThousandSeparator(OSQLParseNode* pLiteral); 186 OSQLParseNode* convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral); 187 // makes a string out of a number, pLiteral will be deleted 188 OSQLParseNode* buildNode_STR_NUM(OSQLParseNode*& pLiteral); 189 OSQLParseNode* buildNode_Date(const double& fValue, sal_Int32 nType); 190 191 static ::osl::Mutex& getMutex(); 192 193 public: 194 // if NULL, a default context will be used 195 // the context must live as long as the parser 196 OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext = NULL); 197 ~OSQLParser(); 198 199 // Parsing an SQLStatement 200 OSQLParseNode* parseTree(::rtl::OUString& rErrorMessage, 201 const ::rtl::OUString& rStatement, 202 sal_Bool bInternational = sal_False); 203 204 // Check a Predicate 205 OSQLParseNode* predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement, 206 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter, 207 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xField); 208 209 // Access to the context getContext() const210 const IParseContext& getContext() const {return *m_pContext;} 211 212 /// access to the SQLError instance owned by this parser 213 const SQLError& getErrorHelper() const; 214 215 // TokenIDToStr: Token-Name zu einer Token-Nr. 216 static ::rtl::OString TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext = NULL); 217 218 // StrToTokenID: Token-Nr. zu einem Token-Namen. 219 // static sal_uInt32 StrToTokenID(const ::rtl::OString & rName); 220 221 // RuleIDToStr gibt den zu einer RuleID gehoerenden ::rtl::OUString zurueck 222 // (Leerstring, falls nicht gefunden) 223 static ::rtl::OUString RuleIDToStr(sal_uInt32 nRuleID); 224 225 // StrToRuleID berechnet zu einem ::rtl::OUString die RuleID (d.h. ::com::sun::star::sdbcx::Index in yytname) 226 // (0, falls nicht gefunden). Die Suche nach der ID aufgrund eines Strings ist 227 // extrem ineffizient (sequentielle Suche nach ::rtl::OUString)! 228 static sal_uInt32 StrToRuleID(const ::rtl::OString & rValue); 229 230 static OSQLParseNode::Rule RuleIDToRule( sal_uInt32 _nRule ); 231 232 // RuleId mit enum, wesentlich effizienter 233 static sal_uInt32 RuleID(OSQLParseNode::Rule eRule); 234 // compares the _sFunctionName with all known function names and return the DataType of the return value 235 static sal_Int32 getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext = NULL); 236 237 // returns the type for a parameter in a given function name 238 static sal_Int32 getFunctionParameterType(sal_uInt32 _nTokenId,sal_uInt32 _nPos); 239 240 void error( const sal_Char* pFormat); 241 int SQLlex(); 242 #ifdef YYBISON 243 void setParseTree(OSQLParseNode * pNewParseTree); 244 245 // Is the parse in a special mode? 246 // Predicate chack is used to check a condition for a field inPredicateCheck() const247 sal_Bool inPredicateCheck() const {return m_xField.is();} getFieldName() const248 const ::rtl::OUString& getFieldName() const {return m_sFieldName;} 249 250 void reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank); 251 // does not change the pLiteral argument 252 sal_Int16 buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pCompare,OSQLParseNode* pLiteral,OSQLParseNode* pLiteral2); 253 254 sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral); 255 // pCompre will be deleted if it is not used 256 sal_Int16 buildPredicateRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare,OSQLParseNode* pLiteral2 = NULL); 257 258 sal_Int16 buildLikeRule(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,const OSQLParseNode* pEscape); 259 sal_Int16 buildStringNodes(OSQLParseNode*& pLiteral); 260 #else 261 #endif 262 }; 263 } 264 265 266 #endif //_CONNECTIVITY_SQLPARSE_HXX 267