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