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