1 /*
2  * Copyright (c) 2015, 2021, Oracle and/or its affiliates.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License, version 2.0,
6  * as published by the Free Software Foundation.
7  *
8  * This program is also distributed with certain software (including
9  * but not limited to OpenSSL) that is licensed under separate terms,
10  * as designated in a particular file or component or in included license
11  * documentation.  The authors of MySQL hereby grant you an additional
12  * permission to link the program and your derivative works with the
13  * separately licensed software that they have included with MySQL.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License, version 2.0, for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301  USA
24  */
25 
26 #ifndef _QUERY_STRING_BUILDER_H_
27 #define _QUERY_STRING_BUILDER_H_
28 
29 #include <string>
30 #include <string.h>
31 #include <stdint.h>
32 
33 #include <ngs/thread.h>
34 #include <ngs/memory.h>
35 
36 #include <query_formatter.h>
37 
38 struct charset_info_st;
39 
40 namespace xpl
41 {
42 
43 class Query_string_builder
44 {
45 public:
46   Query_string_builder(size_t reserve = 256);
47   ~Query_string_builder();
48 
bquote()49   Query_string_builder &bquote()
50   {
51     m_str.push_back('\'');
52     m_in_quoted = true;
53     return *this;
54   }
55 
equote()56   Query_string_builder &equote()
57   {
58     m_str.push_back('\'');
59     m_in_quoted = false;
60     return *this;
61   }
62 
bident()63   Query_string_builder &bident()
64   {
65     m_str.push_back('`');
66     m_in_identifier = true;
67     return *this;
68   }
69 
eident()70   Query_string_builder &eident()
71   {
72     m_str.push_back('`');
73     m_in_identifier = false;
74     return *this;
75   }
76 
77   Query_string_builder &quote_identifier_if_needed(const char *s, size_t length);
78   Query_string_builder &quote_identifier(const char *s, size_t length);
79   Query_string_builder &quote_string(const char *s, size_t length);
80 
quote_identifier_if_needed(const std::string & s)81   Query_string_builder &quote_identifier_if_needed(const std::string &s)
82   {
83     return quote_identifier_if_needed(s.data(), s.length());
84   }
85 
quote_identifier(const std::string & s)86   Query_string_builder &quote_identifier(const std::string &s)
87   {
88     return quote_identifier(s.data(), s.length());
89   }
90 
quote_string(const std::string & s)91   Query_string_builder &quote_string(const std::string &s)
92   {
93     return quote_string(s.data(), s.length());
94   }
95 
96   Query_string_builder &escape_identifier(const char *s, size_t length);
97   Query_string_builder &escape_string(const char *s, size_t length);
98 
dot()99   Query_string_builder &dot() { return put(".", 1); }
100 
put(const int64_t i)101   Query_string_builder &put(const int64_t i) { return put(ngs::to_string(i)); }
put(const uint64_t u)102   Query_string_builder &put(const uint64_t u) { return put(ngs::to_string(u)); }
103 
104 //  NOTE: Commented for coverage. Uncomment when needed.
105 //  Query_string_builder &put(const int32_t i) { return put(ngs::to_string(i)); }
106 
put(const uint32_t u)107   Query_string_builder &put(const uint32_t u) { return put(ngs::to_string(u)); }
put(const float f)108   Query_string_builder &put(const float f) { return put(ngs::to_string(f)); }
put(const double d)109   Query_string_builder &put(const double d) { return put(ngs::to_string(d)); }
110 
111   Query_string_builder &put(const char *s, size_t length);
112 
113   Query_formatter format();
114 
put(const char * s)115   Query_string_builder &put(const char *s) { return put(s, strlen(s)); }
116 
put(const std::string & s)117   Query_string_builder &put(const std::string &s)
118   {
119     return put(s.data(), s.length());
120   }
121 
put(const ngs::PFS_string & s)122   Query_string_builder &put(const ngs::PFS_string &s)
123   {
124     return put(s.data(), s.length());
125   }
126 
clear()127   void clear()
128   {
129     m_str.clear();
130   }
131 
reserve(size_t bytes)132   void reserve(size_t bytes)
133   {
134     m_str.reserve(bytes);
135   }
136 
get()137   const ngs::PFS_string &get() const { return m_str; }
138 
139 private:
140   ngs::PFS_string m_str;
141   bool m_in_quoted;
142   bool m_in_identifier;
143 
144   static void init_charset();
145   static my_thread_once_t  m_charset_initialized;
146   static charset_info_st *m_charset;
147 };
148 
149 } // namespace xpl
150 
151 #endif
152