forked from mysql/mysql-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmysql_query_runner.h
239 lines (211 loc) · 7.39 KB
/
mysql_query_runner.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*
Copyright (c) 2014, 2023, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MYSQL_QUERY_RUNNER_INCLUDED
#define MYSQL_QUERY_RUNNER_INCLUDED
#include "my_global.h"
#include "mysql.h"
#include "mutex.h"
#include "i_callable.h"
#include "message_data.h"
#include "atomic.h"
#include <algorithm>
#include <string>
#include <vector>
namespace Mysql{
namespace Tools{
namespace Base{
/**
Helper class to run SQL query on existing MySQL database server connection,
receive all data and all errors, warnings and notes returned during query
execution. All acquired information is passed to set of callbacks to make
data flows more customizable.
*/
class Mysql_query_runner
{
public:
class Row;
/**
Standard constructor based on MySQL connection.
*/
Mysql_query_runner(MYSQL* connection);
/**
Copy constructor.
*/
Mysql_query_runner(const Mysql_query_runner& source);
~Mysql_query_runner();
/**
Adds new callback to be called on every result row of query.
If callback return value other than 0 then query execution, passing
current row to other callbacks and error messages processing, and
Mysql_query_runner::run_query() will return value returned from this
callback.
Callbacks are called in reverse order of addition, i.e. newest are first.
*/
Mysql_query_runner& add_result_callback(
I_callable<int64, const Row&>* result_callback);
/**
Adds new callback to be called on every message after query execution,
this includes errors, warnings and other notes. Return value from callback
of 0 will lead to next handler being called, positive number return value
will cause Mysql_query_runner::run_query() will return immediately this
value and negative number will continue query execution and other messages
processing, but will not pass current message to rest of callbacks.
Callbacks are called in reverse order of addition, i.e. newest are first.
*/
Mysql_query_runner& add_message_callback(
I_callable<int64, const Message_data&>* message_callback);
/**
Runs specified query and processes result rows and messages to callbacks.
*/
int64 run_query(std::string query);
/**
Runs specified query, fills result vector with processed result rows
and processes messages to callbacks.
*/
int64 run_query_store(
std::string query, std::vector<const Row*>* result);
/**
Runs specified query with result callback specified. Does not add specified
callback to list of callbacks, next queries will not process rows to this
callback.
*/
int64 run_query(
std::string query,
I_callable<int64, const Row&>* result_callback);
/**
Returns escaped copy of string to use in queries.
*/
std::string escape_string(const std::string& original);
/**
Escapes specified input string and appends it escaped to destination
string.
*/
void append_escape_string(std::string* destination_string,
const std::string& original);
/**
Escapes specified input string specified as characters buffer and its size,
and appends it escaped to destination string.
*/
void append_escape_string(std::string* destination_string,
const char* original, size_t original_length);
/**
Converts to HEX specified input string specified as characters buffer and
its size, and appends it escaped to destination string.
*/
void append_hex_string(std::string* destination_string,
const char* original, size_t original_length);
/**
Empties memory used by result strings.
*/
static void cleanup_result(const Row& result);
/**
Empties memory used by result strings.
*/
static void cleanup_result(std::vector<const Row*>* result);
MYSQL* get_low_level_connection() const;
class Row
{
public:
class Iterator;
Row(MYSQL_RES* mysql_result_info, unsigned int column_count,
MYSQL_ROW row);
~Row();
std::string operator[] (std::size_t index) const;
void push_back(char* buff, std::size_t length);
const char* get_buffer(std::size_t index, std::size_t& length) const;
std::size_t size_of_element(std::size_t index) const;
bool is_value_null(std::size_t index) const;
std::size_t size() const;
Iterator begin() const;
Iterator end() const;
MYSQL_RES* get_mysql_result_info() const;
class Iterator
{
public:
Iterator(const Row& row, std::size_t index);
bool is_value_null();
std::string operator *();
void operator ++();
bool operator ==(const Iterator& other);
bool operator !=(const Iterator& other);
private:
const Row& m_row;
std::size_t m_index;
};
private:
void reserve(std::size_t strings, std::size_t buffer_size);
// Represents table row as a string
char* m_buffer;
// Represents offsets to each column in m_buffer
std::vector<std::size_t> m_buffer_starts;
// Total buffer size
std::size_t m_buffer_capacity;
// Actual buffer size
std::size_t m_buffer_size;
MYSQL_RES* m_mysql_result_info;
};
private:
/**
Runs specified query and process result rows and messages to callbacks.
Does not check for multiple queries being executed in parallel.
*/
int64 run_query_unguarded(std::string query);
/**
Creates error message from mysql_errno and mysql_error and passes it to
callbacks.
*/
int64 report_mysql_error();
/**
Creates error message from mysql_errno and mysql_error and passes it to
callbacks.
*/
int64 report_message(Message_data &message);
/**
Returns parsed Message_type from given MySQL severity string.
*/
Message_type get_message_type_from_severity(std::string severity);
class Store_result_helper
{
public:
Store_result_helper(std::vector<const Row*>* result);
I_callable<int64, const Row&>* get_result_callback();
private:
int64 result_callback(const Row& row);
std::vector<const Row*>* m_result;
};
std::vector<I_callable<int64, const Row&>*>
m_result_callbacks;
std::vector<I_callable<int64, const Message_data&>*> m_message_callbacks;
/**
Indicates if there is query currently executed. Only one query can be
executed in specified time moment.
*/
my_boost::atomic<bool>* m_is_processing;
/**
Indicates if this is original runner or a copy. In case of original the
cleanup is performed on destruction.
*/
bool m_is_original_runner;
MYSQL* m_connection;
};
}
}
}
#endif