1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_CONNECTIVITY_SQLPARSE_HXX
20 #define INCLUDED_CONNECTIVITY_SQLPARSE_HXX
22 #include <com/sun/star/uno/Reference.h>
23 #include <connectivity/sqlnode.hxx>
24 #include <connectivity/IParseContext.hxx>
25 #include <connectivity/dbtoolsdllapi.hxx>
26 #include <connectivity/sqlerror.hxx>
27 #include <comphelper/singletonref.hxx>
28 #include <tools/lazydelete.hxx>
33 #include <string_view>
35 namespace com::sun::star::i18n
{ class XCharacterClassification
; }
36 namespace com::sun::star::i18n
{ class XLocaleData4
; }
38 namespace com::sun::star
46 class XNumberFormatter
;
50 namespace connectivity
56 class OParseContext final
: public IParseContext
61 virtual ~OParseContext();
62 // retrieves language specific error messages
63 virtual OUString
getErrorMessage(ErrorCode _eCodes
) const override
;
65 // retrieves language specific keyword strings (only ASCII allowed)
66 virtual OString
getIntlKeywordAscii(InternationalKeyCode _eKey
) const override
;
68 // finds out, if we have an international keyword (only ASCII allowed)
69 virtual InternationalKeyCode
getIntlKeyCode(const OString
& rToken
) const override
;
71 // determines the default international setting
72 static const css::lang::Locale
& getDefaultLocale();
74 /** gets a locale instance which should be used when parsing in the context specified by this instance
75 <p>if this is not overridden by derived classes, it returns the static default locale.</p>
77 virtual css::lang::Locale
getPreferredLocale( ) const override
;
80 // OSQLParseNodesContainer
81 // garbage collection of nodes
83 class OSQLParseNodesContainer
86 ::std::vector
< OSQLParseNode
* > m_aNodes
;
88 OSQLParseNodesContainer();
89 ~OSQLParseNodesContainer();
91 void push_back(OSQLParseNode
* _pNode
);
92 void erase(OSQLParseNode
* _pNode
);
94 void clearAndDelete();
97 typedef comphelper::SingletonRef
<OSQLParseNodesContainer
> OSQLParseNodesGarbageCollector
;
101 struct OSQLParser_Data
103 css::lang::Locale aLocale
;
104 ::connectivity::SQLError aErrors
;
109 class OOO_DLLPUBLIC_DBTOOLS OSQLParser
111 friend class OSQLParseNode
;
112 friend class OSQLInternalNode
;
113 friend struct SQLParseNodeParameter
;
116 typedef ::std::map
< sal_uInt32
, OSQLParseNode::Rule
> RuleIDMap
;
117 // static parts for parsers
118 static sal_uInt32 s_nRuleIDs
[OSQLParseNode::rule_count
+ 1];
119 static RuleIDMap s_aReverseRuleIDLookup
;
120 static OParseContext s_aDefaultContext
;
122 static OSQLScanner
* s_pScanner
;
123 static OSQLParseNodesGarbageCollector
* s_pGarbageCollector
;
124 static sal_Int32 s_nRefCount
;
126 // information on the current parse action
127 const IParseContext
* m_pContext
;
128 const IParseContext
* m_pNeutral
;
129 std::unique_ptr
<OSQLParseNode
> m_pParseTree
; // result from parsing
130 ::std::unique_ptr
< OSQLParser_Data
>
132 OUString m_sFieldName
; // current field name for a predicate
133 OUString m_sErrorMessage
;// current error msg
135 css::uno::Reference
< css::beans::XPropertySet
>
136 m_xField
; // current field
137 css::uno::Reference
< css::util::XNumberFormatter
>
138 m_xFormatter
; // current number formatter
139 sal_Int32 m_nFormatKey
; // numberformat, which should be used
140 sal_Int32 m_nDateFormatKey
;
141 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
142 css::uno::Reference
< css::i18n::XCharacterClassification
> m_xCharClass
;
143 static tools::DeleteOnDeinit
<css::uno::Reference
< css::i18n::XLocaleData4
>>& getLocaleData();
145 // convert a string into double trim it to scale of _nscale and then transform it back to string
146 OUString
stringToDouble(const OUString
& _rValue
,sal_Int16 _nScale
);
147 OSQLParseNode
* buildDate(sal_Int32 _nType
,OSQLParseNode
*& pLiteral
);
148 bool extractDate(OSQLParseNode
const * pLiteral
,double& _rfValue
);
149 void killThousandSeparator(OSQLParseNode
* pLiteral
);
150 OSQLParseNode
* convertNode(sal_Int32 nType
, OSQLParseNode
* pLiteral
);
151 // makes a string out of a number, pLiteral will be deleted
152 OSQLParseNode
* buildNode_STR_NUM(OSQLParseNode
*& pLiteral
);
153 OSQLParseNode
* buildNode_Date(const double& fValue
, sal_Int32 nType
);
155 static std::mutex
& getMutex();
158 // if NULL, a default context will be used
159 // the context must live as long as the parser
160 OSQLParser(css::uno::Reference
< css::uno::XComponentContext
> xContext
,
161 const IParseContext
* _pContext
= nullptr,
162 const IParseContext
* _pNeutral
= nullptr);
165 // Parsing an SQLStatement
166 std::unique_ptr
<OSQLParseNode
> parseTree(OUString
& rErrorMessage
,
167 const OUString
& rStatement
,
168 bool bInternational
= false);
171 // set bUseRealName to false if you pass a xField that comes from where you got that field,
172 // as opposed from to from yourself.
173 std::unique_ptr
<OSQLParseNode
> predicateTree(OUString
& rErrorMessage
, const OUString
& rStatement
,
174 const css::uno::Reference
< css::util::XNumberFormatter
> & xFormatter
,
175 const css::uno::Reference
< css::beans::XPropertySet
> & xField
,
176 bool bUseRealName
= true);
178 // Access to the context
179 const IParseContext
& getContext() const { return *m_pContext
; }
180 const IParseContext
* getNeutral() const { return m_pNeutral
; }
182 /// access to the SQLError instance owned by this parser
183 const SQLError
& getErrorHelper() const;
185 // TokenIDToStr: token name belonging to a token number.
186 static OString
TokenIDToStr(sal_uInt32 nTokenID
, const IParseContext
* pContext
= nullptr);
188 #if OSL_DEBUG_LEVEL > 0
189 // (empty string if not found)
190 static OUString
RuleIDToStr(sal_uInt32 nRuleID
);
193 // StrToRuleID calculates the RuleID for an OUString (that is, css::sdbcx::Index in yytname)
194 // (0 if not found). The search for an ID based on a String is
195 // extremely inefficient (sequential search for OUString)!
196 static sal_uInt32
StrToRuleID(const OString
& rValue
);
198 static OSQLParseNode::Rule
RuleIDToRule( sal_uInt32 _nRule
);
200 // RuleId with enum, far more efficient
201 static sal_uInt32
RuleID(OSQLParseNode::Rule eRule
);
202 // compares the _sFunctionName with all known function names and return the DataType of the return value
203 static sal_Int32
getFunctionReturnType(std::u16string_view _sFunctionName
, const IParseContext
* pContext
);
205 // returns the type for a parameter in a given function name
206 static sal_Int32
getFunctionParameterType(sal_uInt32 _nTokenId
,sal_uInt32 _nPos
);
208 void error(const char *fmt
);
211 void setParseTree(OSQLParseNode
* pNewParseTree
);
213 // Is the parse in a special mode?
214 // Predicate check is used to check a condition for a field
215 bool inPredicateCheck() const {return m_xField
.is();}
216 const OUString
& getFieldName() const {return m_sFieldName
;}
218 static void reduceLiteral(OSQLParseNode
*& pLiteral
, bool bAppendBlank
);
219 // does not change the pLiteral argument
220 sal_Int16
buildNode(OSQLParseNode
*& pAppend
,OSQLParseNode
* pCompare
,OSQLParseNode
* pLiteral
,OSQLParseNode
* pLiteral2
);
222 sal_Int16
buildComparisonRule(OSQLParseNode
*& pAppend
,OSQLParseNode
* pLiteral
);
223 // pCompre will be deleted if it is not used
224 sal_Int16
buildPredicateRule(OSQLParseNode
*& pAppend
,OSQLParseNode
* const pLiteral
,OSQLParseNode
* pCompare
,OSQLParseNode
* pLiteral2
= nullptr);
226 sal_Int16
buildLikeRule(OSQLParseNode
* pAppend
, OSQLParseNode
*& pLiteral
, const OSQLParseNode
* pEscape
);
227 sal_Int16
buildStringNodes(OSQLParseNode
*& pLiteral
);
232 #endif // INCLUDED_CONNECTIVITY_SQLPARSE_HXX
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */