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_FORMATTER_H_
27 #define _QUERY_FORMATTER_H_
28 
29 
30 #include <string>
31 #include <string.h>
32 #include <stdint.h>
33 #include <stdexcept>
34 #include <sstream>
35 #include "ngs/memory.h"
36 #include "ngs_common/to_string.h"
37 
38 
39 struct charset_info_st;
40 
41 namespace xpl
42 {
43 
44   class Query_formatter
45   {
46   public:
47     Query_formatter(ngs::PFS_string &query, charset_info_st &charser);
48 
49     template <typename Value_type>
50     class No_escape
51     {
52     public:
No_escape(const Value_type & value)53       No_escape(const Value_type &value)
54         : m_value(value)
55       {
56       }
57 
58       const Value_type &m_value;
59     };
60 
61     Query_formatter &operator % (const char *value);
62     Query_formatter &operator % (const No_escape<const char *> &value);
63     Query_formatter &operator % (const std::string &value);
64     Query_formatter &operator % (const No_escape<std::string> &value);
65 
66 
67     template<typename Value_type>
68     Query_formatter &operator % (const Value_type &value)
69     {
70       return put(value);
71     }
72 
73   private:
74     template<typename Value_type>
put(const Value_type & value)75     Query_formatter & put(const Value_type &value)
76     {
77       validate_next_tag();
78       std::string string_value = ngs::to_string(value);
79       put_value(string_value.c_str(), string_value.length());
80 
81       return *this;
82     }
83 
84     template<typename Value_type>
put_fp(const Value_type & value)85     Query_formatter & put_fp(const Value_type &value)
86     {
87       std::stringstream stream;
88       validate_next_tag();
89       stream << value;
90       std::string string_value = stream.str();
91       put_value(string_value.c_str(), string_value.length());
92 
93       return *this;
94     }
95 
96     void put_value(const char *value, const std::size_t length);
97     void put_value_and_escape(const char *value, const std::size_t length);
98     void validate_next_tag();
99 
100     ngs::PFS_string      &m_query;
101     charset_info_st &m_charset;
102     std::size_t      m_last_tag_position;
103   };
104 
105   template<>
106   inline  Query_formatter& Query_formatter::operator%<double>(const double &value)
107   {
108     return put_fp(value);
109   }
110 
111   template<>
112   inline  Query_formatter& Query_formatter::operator%<float>(const float &value)
113   {
114     return put_fp(value);
115   }
116 
117 } // namespace xpl
118 
119 
120 #endif // _QUERY_FORMATTER_H_
121