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