xref: /AOO41X/main/connectivity/inc/connectivity/sqlparse.hxx (revision caf5cd79edad04a48dcaf209068b3b89eae4622e)
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