1 /*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
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 #include "callback_command_delegate.h"
27
28 #include "xpl_log.h"
29
30 using namespace xpl;
31
32
Field_value()33 Callback_command_delegate::Field_value::Field_value()
34 : is_unsigned(false), is_string(false)
35 {}
36
Field_value(const Field_value & other)37 Callback_command_delegate::Field_value::Field_value(const Field_value& other)
38 : value(other.value),
39 is_unsigned(other.is_unsigned),
40 is_string(other.is_string)
41 {
42 if (other.is_string)
43 value.v_string = new std::string(*other.value.v_string);
44 }
45
46 /*
47 NOTE: Commented for coverage. Uncomment when needed.
48
49 Callback_command_delegate::Field_value& Callback_command_delegate::Field_value::operator = (const Field_value& other)
50 {
51 if (&other != this)
52 {
53 this->~Field_value();
54
55 value = other.value;
56 is_unsigned = other.is_unsigned;
57 is_string = other.is_string;
58
59 if (other.is_string)
60 value.v_string = new std::string(*other.value.v_string);
61 }
62
63 return *this;
64 }
65 */
66
Field_value(const longlong & num,bool unsign)67 Callback_command_delegate::Field_value::Field_value(const longlong &num, bool unsign)
68 {
69 value.v_long = num;
70 is_unsigned = unsign;
71 is_string = false;
72 }
73
Field_value(const double num)74 Callback_command_delegate::Field_value::Field_value(const double num)
75 {
76 value.v_double = num;
77 is_string = false;
78 }
79
Field_value(const decimal_t & decimal)80 Callback_command_delegate::Field_value::Field_value(const decimal_t &decimal)
81 {
82 value.v_decimal = decimal;
83 is_string = false;
84 }
85
86
Field_value(const MYSQL_TIME & time)87 Callback_command_delegate::Field_value::Field_value(const MYSQL_TIME &time)
88 {
89 value.v_time = time;
90 is_string = false;
91 }
92
Field_value(const char * str,size_t length)93 Callback_command_delegate::Field_value::Field_value(const char *str, size_t length)
94 {
95 value.v_string = new std::string(str, length);
96 is_string = true;
97 }
98
99
~Field_value()100 Callback_command_delegate::Field_value::~Field_value()
101 {
102 if (is_string && value.v_string)
103 delete value.v_string;
104 }
105
~Row_data()106 Callback_command_delegate::Row_data::~Row_data()
107 {
108 clear();
109 }
110
clear()111 void Callback_command_delegate::Row_data::clear()
112 {
113 std::vector<Field_value*>::iterator i = fields.begin();
114
115 for (; i != fields.end(); ++i)
116 ngs::free_object(*i);
117
118 fields.clear();
119 }
120
Row_data(const Row_data & other)121 Callback_command_delegate::Row_data::Row_data(const Row_data& other)
122 {
123 clone_fields(other);
124 }
125
operator =(const Row_data & other)126 Callback_command_delegate::Row_data& Callback_command_delegate::Row_data::operator=(const Row_data& other)
127 {
128 if (&other != this)
129 {
130 clear();
131 clone_fields(other);
132 }
133
134 return *this;
135 }
136
clone_fields(const Row_data & other)137 void Callback_command_delegate::Row_data::clone_fields(const Row_data& other)
138 {
139 fields.reserve(other.fields.size());
140 std::vector<Field_value*>::const_iterator i = other.fields.begin();
141 for (; i != other.fields.end(); ++i)
142 {
143 this->fields.push_back((*i) ? ngs::allocate_object<Field_value>(**i) : NULL);
144 }
145 }
146
147
148
Callback_command_delegate()149 Callback_command_delegate::Callback_command_delegate()
150 : m_current_row(NULL)
151 {
152 }
153
154
Callback_command_delegate(Start_row_callback start_row,End_row_callback end_row)155 Callback_command_delegate::Callback_command_delegate(Start_row_callback start_row, End_row_callback end_row)
156 : m_start_row(start_row), m_end_row(end_row), m_current_row(NULL)
157 {
158 }
159
160
set_callbacks(Start_row_callback start_row,End_row_callback end_row)161 void Callback_command_delegate::set_callbacks(Start_row_callback start_row, End_row_callback end_row)
162 {
163 m_start_row = start_row;
164 m_end_row = end_row;
165 }
166
167
reset()168 void Callback_command_delegate::reset()
169 {
170 m_current_row = NULL;
171 Command_delegate::reset();
172 }
173
174
start_row()175 int Callback_command_delegate::start_row()
176 {
177 if (m_start_row)
178 {
179 m_current_row = m_start_row();
180 if (!m_current_row)
181 return true;
182 }
183 else
184 m_current_row = NULL;
185 return false;
186 }
187
end_row()188 int Callback_command_delegate::end_row()
189 {
190 if (m_end_row && !m_end_row(m_current_row))
191 return true;
192 return false;
193 }
194
abort_row()195 void Callback_command_delegate::abort_row()
196 {
197 }
198
get_client_capabilities()199 ulong Callback_command_delegate::get_client_capabilities()
200 {
201 return CLIENT_DEPRECATE_EOF;
202 }
203
204 /****** Getting data ******/
get_null()205 int Callback_command_delegate::get_null()
206 {
207 try
208 {
209 if (m_current_row)
210 m_current_row->fields.push_back(NULL);
211 }
212 catch (std::exception &e)
213 {
214 log_error("Error getting result data: %s", e.what());
215 return true;
216 }
217 return false;
218 }
219
get_integer(longlong value)220 int Callback_command_delegate::get_integer(longlong value)
221 {
222 try
223 {
224 if (m_current_row)
225 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(value));
226 }
227 catch (std::exception &e)
228 {
229 log_error("Error getting result data: %s", e.what());
230 return true;
231 }
232 return false;
233 }
234
get_longlong(longlong value,uint unsigned_flag)235 int Callback_command_delegate::get_longlong(longlong value, uint unsigned_flag)
236 {
237 try
238 {
239 if (m_current_row)
240 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(value, unsigned_flag));
241 }
242 catch (std::exception &e)
243 {
244 log_error("Error getting result data: %s", e.what());
245 return true;
246 }
247 return false;
248 }
249
get_decimal(const decimal_t * value)250 int Callback_command_delegate::get_decimal(const decimal_t * value)
251 {
252 try
253 {
254 if (m_current_row)
255 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(*value));
256 }
257 catch (std::exception &e)
258 {
259 log_error("Error getting result data: %s", e.what());
260 return true;
261 }
262 return false;
263 }
264
get_double(double value,uint32 decimals)265 int Callback_command_delegate::get_double(double value, uint32 decimals)
266 {
267 try
268 {
269 if (m_current_row)
270 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(value));
271 }
272 catch (std::exception &e)
273 {
274 log_error("Error getting result data: %s", e.what());
275 return true;
276 }
277 return false;
278 }
279
get_date(const MYSQL_TIME * value)280 int Callback_command_delegate::get_date(const MYSQL_TIME * value)
281 {
282 try
283 {
284 if (m_current_row)
285 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(*value));
286 }
287 catch (std::exception &e)
288 {
289 log_error("Error getting result data: %s", e.what());
290 return true;
291 }
292 return false;
293 }
294
get_time(const MYSQL_TIME * value,uint decimals)295 int Callback_command_delegate::get_time(const MYSQL_TIME * value, uint decimals)
296 {
297 try
298 {
299 if (m_current_row)
300 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(*value));
301 }
302 catch (std::exception &e)
303 {
304 log_error("Error getting result data: %s", e.what());
305 return true;
306 }
307 return false;
308 }
309
get_datetime(const MYSQL_TIME * value,uint decimals)310 int Callback_command_delegate::get_datetime(const MYSQL_TIME * value, uint decimals)
311 {
312 try
313 {
314 if (m_current_row)
315 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(*value));
316 }
317 catch (std::exception &e)
318 {
319 log_error("Error getting result data: %s", e.what());
320 return true;
321 }
322 return false;
323 }
324
get_string(const char * const value,size_t length,const CHARSET_INFO * const valuecs)325 int Callback_command_delegate::get_string(const char * const value, size_t length,
326 const CHARSET_INFO * const valuecs)
327 {
328 try
329 {
330 if (m_current_row)
331 m_current_row->fields.push_back(ngs::allocate_object<Field_value>(value, length));
332 }
333 catch (std::exception &e)
334 {
335 log_error("Error getting result data: %s", e.what());
336 return true;
337 }
338 return false;
339 }
340