233 lines
7.0 KiB
C++
233 lines
7.0 KiB
C++
/*
|
|
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
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 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
|