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