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