Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef _CONNECTIVITY_SQLPARSE_HXX
20 : #define _CONNECTIVITY_SQLPARSE_HXX
21 :
22 : #include <com/sun/star/uno/Reference.h>
23 : #include <osl/mutex.hxx>
24 : #include <connectivity/sqlnode.hxx>
25 : #ifndef DISABLE_DBCONNECTIVITY
26 : #ifndef YYBISON
27 : #ifndef FLEX_SCANNER
28 : #include "sqlbison.hxx"
29 : #endif
30 : #endif
31 : #endif
32 : #include <com/sun/star/i18n/XCharacterClassification.hpp>
33 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 : #include <com/sun/star/i18n/XLocaleData4.hpp>
35 : #include "connectivity/IParseContext.hxx"
36 : #include "connectivity/dbtoolsdllapi.hxx"
37 : #include "connectivity/sqlerror.hxx"
38 : #include <salhelper/singletonref.hxx>
39 :
40 : #include <map>
41 :
42 : // forward declarations
43 : namespace com
44 : {
45 : namespace sun
46 : {
47 : namespace star
48 : {
49 : namespace beans
50 : {
51 : class XPropertySet;
52 : }
53 : namespace util
54 : {
55 : class XNumberFormatter;
56 : }
57 : namespace lang
58 : {
59 : struct Locale;
60 : }
61 : }
62 : }
63 : }
64 : namespace connectivity
65 : {
66 : class OSQLScanner;
67 : class SQLError;
68 :
69 : //==========================================================================
70 : //= OParseContext
71 : //==========================================================================
72 : class OOO_DLLPUBLIC_DBTOOLS OParseContext : public IParseContext
73 : {
74 : public:
75 : OParseContext();
76 :
77 : virtual ~OParseContext();
78 : // retrieves language specific error messages
79 : virtual OUString getErrorMessage(ErrorCode _eCodes) const;
80 :
81 : // retrieves language specific keyword strings (only ASCII allowed)
82 : virtual OString getIntlKeywordAscii(InternationalKeyCode _eKey) const;
83 :
84 : // finds out, if we have an international keyword (only ASCII allowed)
85 : virtual InternationalKeyCode getIntlKeyCode(const OString& rToken) const;
86 :
87 : // determines the default international setting
88 : static const ::com::sun::star::lang::Locale& getDefaultLocale();
89 :
90 : /** get's a locale instance which should be used when parsing in the context specified by this instance
91 : <p>if this is not overridden by derived classes, it returns the static default locale.</p>
92 : */
93 : virtual ::com::sun::star::lang::Locale getPreferredLocale( ) const;
94 : };
95 :
96 : //==========================================================================
97 : // OSQLParseNodesContainer
98 : // grabage collection of nodes
99 : //==========================================================================
100 : class OSQLParseNodesContainer
101 : {
102 : ::osl::Mutex m_aMutex;
103 : ::std::vector< OSQLParseNode* > m_aNodes;
104 : public:
105 : OSQLParseNodesContainer();
106 : ~OSQLParseNodesContainer();
107 :
108 : void push_back(OSQLParseNode* _pNode);
109 : void erase(OSQLParseNode* _pNode);
110 : void clear();
111 : void clearAndDelete();
112 : };
113 :
114 : typedef salhelper::SingletonRef<OSQLParseNodesContainer> OSQLParseNodesGarbageCollector;
115 :
116 : //==========================================================================
117 : //= OSQLParser
118 : //==========================================================================
119 112 : struct OSQLParser_Data
120 : {
121 : ::com::sun::star::lang::Locale aLocale;
122 : ::connectivity::SQLError aErrors;
123 :
124 114 : OSQLParser_Data( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext )
125 114 : :aErrors( _rxContext )
126 : {
127 114 : }
128 : };
129 :
130 : /** Parser for SQL92
131 : */
132 : class OOO_DLLPUBLIC_DBTOOLS OSQLParser
133 : {
134 : friend class OSQLParseNode;
135 : friend class OSQLInternalNode;
136 : friend struct SQLParseNodeParameter;
137 :
138 : private:
139 : typedef ::std::map< sal_uInt32, OSQLParseNode::Rule > RuleIDMap;
140 : // static parts for parsers
141 : static sal_uInt32 s_nRuleIDs[OSQLParseNode::rule_count + 1];
142 : static RuleIDMap s_aReverseRuleIDLookup;
143 : static OParseContext s_aDefaultContext;
144 :
145 : static OSQLScanner* s_pScanner;
146 : static OSQLParseNodesGarbageCollector* s_pGarbageCollector;
147 : static sal_Int32 s_nRefCount;
148 :
149 : // information on the current parse action
150 : const IParseContext* m_pContext;
151 : OSQLParseNode* m_pParseTree; // result from parsing
152 : ::std::auto_ptr< OSQLParser_Data >
153 : m_pData;
154 : OUString m_sFieldName; // current field name for a predicate
155 : OUString m_sErrorMessage;// current error msg
156 :
157 : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
158 : m_xField; // current field
159 : ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >
160 : m_xFormatter; // current number formatter
161 : sal_Int32 m_nFormatKey; // numberformat, which should be used
162 : sal_Int32 m_nDateFormatKey;
163 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
164 : ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification> m_xCharClass;
165 : static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData4> s_xLocaleData;
166 : ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData> xDummy; // can be deleted after 627
167 :
168 : // convert a string into double trim it to scale of _nscale and than transform it back to string
169 : OUString stringToDouble(const OUString& _rValue,sal_Int16 _nScale);
170 : OSQLParseNode* buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral);
171 : bool extractDate(OSQLParseNode* pLiteral,double& _rfValue);
172 : void killThousandSeparator(OSQLParseNode* pLiteral);
173 : OSQLParseNode* convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral);
174 : // makes a string out of a number, pLiteral will be deleted
175 : OSQLParseNode* buildNode_STR_NUM(OSQLParseNode*& pLiteral);
176 : OSQLParseNode* buildNode_Date(const double& fValue, sal_Int32 nType);
177 :
178 : static ::osl::Mutex& getMutex();
179 :
180 : public:
181 : // if NULL, a default context will be used
182 : // the context must live as long as the parser
183 : OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext, const IParseContext* _pContext = NULL);
184 : ~OSQLParser();
185 :
186 : // Parsing an SQLStatement
187 : OSQLParseNode* parseTree(OUString& rErrorMessage,
188 : const OUString& rStatement,
189 : sal_Bool bInternational = sal_False);
190 :
191 : // Check a Predicate
192 : OSQLParseNode* predicateTree(OUString& rErrorMessage, const OUString& rStatement,
193 : const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
194 : const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xField);
195 :
196 : // Access to the context
197 81 : const IParseContext& getContext() const {return *m_pContext;}
198 :
199 : /// access to the SQLError instance owned by this parser
200 : const SQLError& getErrorHelper() const;
201 :
202 : // TokenIDToStr: token name belonging to a token number.
203 : static OString TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext = NULL);
204 :
205 : #if OSL_DEBUG_LEVEL > 1
206 : // (empty string if not found)
207 : static OUString RuleIDToStr(sal_uInt32 nRuleID);
208 : #endif
209 :
210 : // StrToRuleID calculates the RuleID for a OUString (that is, ::com::sun::star::sdbcx::Index in yytname)
211 : // (0 if not found). The search for an ID based on a String is
212 : // extremely inefficient (sequential search for OUString)!
213 : static sal_uInt32 StrToRuleID(const OString & rValue);
214 :
215 : static OSQLParseNode::Rule RuleIDToRule( sal_uInt32 _nRule );
216 :
217 : // RuleId with enum, far more efficient
218 : static sal_uInt32 RuleID(OSQLParseNode::Rule eRule);
219 : // compares the _sFunctionName with all known function names and return the DataType of the return value
220 : static sal_Int32 getFunctionReturnType(const OUString& _sFunctionName, const IParseContext* pContext = NULL);
221 :
222 : // returns the type for a parameter in a given function name
223 : static sal_Int32 getFunctionParameterType(sal_uInt32 _nTokenId,sal_uInt32 _nPos);
224 :
225 : void error(const sal_Char *fmt);
226 : int SQLlex();
227 : #ifdef YYBISON
228 : void setParseTree(OSQLParseNode * pNewParseTree);
229 :
230 : // Is the parse in a special mode?
231 : // Predicate chack is used to check a condition for a field
232 73 : sal_Bool inPredicateCheck() const {return m_xField.is();}
233 0 : const OUString& getFieldName() const {return m_sFieldName;}
234 :
235 : void reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank);
236 : // does not change the pLiteral argument
237 : sal_Int16 buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pCompare,OSQLParseNode* pLiteral,OSQLParseNode* pLiteral2);
238 :
239 : sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral);
240 : // pCompre will be deleted if it is not used
241 : sal_Int16 buildPredicateRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare,OSQLParseNode* pLiteral2 = NULL);
242 :
243 : sal_Int16 buildLikeRule(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,const OSQLParseNode* pEscape);
244 : sal_Int16 buildStringNodes(OSQLParseNode*& pLiteral);
245 : #else
246 : #endif
247 : };
248 : }
249 :
250 :
251 : #endif //_CONNECTIVITY_SQLPARSE_HXX
252 :
253 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|