driver/connection_proxy.cc (299 lines of code) (raw):

// Copyright Amazon.com, Inc. 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, version 2.0 // (GPLv2), as published by the Free Software Foundation, with the // following additional permissions: // // This program is distributed with certain software that is licensed // under separate terms, as designated in a particular file or component // or in the license documentation. Without limiting your rights under // the GPLv2, the authors of this program hereby grant you an additional // permission to link the program and your derivative works with the // separately licensed software that they have included with the program. // // Without limiting the foregoing grant of rights under the GPLv2 and // additional permission as to separately licensed software, this // program is also subject to the Universal FOSS Exception, version 1.0, // a copy of which can be found along with its FAQ at // http://oss.oracle.com/licenses/universal-foss-exception. // // 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, see // http://www.gnu.org/licenses/gpl-2.0.html. #include "driver.h" CONNECTION_PROXY::CONNECTION_PROXY(DBC* dbc, DataSource* ds) : dbc{dbc}, ds{ds} { if (!this->dbc) { throw std::runtime_error("DBC cannot be null."); } if (!this->ds) { throw std::runtime_error("DataSource cannot be null."); } } CONNECTION_PROXY::~CONNECTION_PROXY() { if (this->next_proxy) { delete next_proxy; } } bool CONNECTION_PROXY::connect(const char* host, const char* user, const char* password, const char* database, unsigned int port, const char* socket, unsigned long flags) { if (ds->opt_ENABLE_DNS_SRV) { return this->real_connect_dns_srv(host, user, password, database, flags); } return this->real_connect(host, user, password, database, port, socket, flags); } void CONNECTION_PROXY::delete_ds() { next_proxy->delete_ds(); } uint64_t CONNECTION_PROXY::num_rows(MYSQL_RES* res) { return next_proxy->num_rows(res); } unsigned int CONNECTION_PROXY::num_fields(MYSQL_RES* res) { return next_proxy->num_fields(res); } MYSQL_FIELD* CONNECTION_PROXY::fetch_field_direct(MYSQL_RES* res, unsigned int fieldnr) { return next_proxy->fetch_field_direct(res, fieldnr); } MYSQL_ROW_OFFSET CONNECTION_PROXY::row_tell(MYSQL_RES* res) { return next_proxy->row_tell(res); } unsigned int CONNECTION_PROXY::field_count() { return next_proxy->field_count(); } uint64_t CONNECTION_PROXY::affected_rows() { return next_proxy->affected_rows(); } unsigned int CONNECTION_PROXY::error_code() { return next_proxy->error_code(); } const char* CONNECTION_PROXY::error() { if (has_custom_error_message) { // We disable this flag after fetching the custom message once // so it does not obscure future proxy errors. has_custom_error_message = false; return this->custom_error_message.c_str(); } return next_proxy->error(); } const char* CONNECTION_PROXY::sqlstate() { return next_proxy->sqlstate(); } unsigned long CONNECTION_PROXY::thread_id() { return next_proxy->thread_id(); } int CONNECTION_PROXY::set_character_set(const char* csname) { return next_proxy->set_character_set(csname); } void CONNECTION_PROXY::init() { next_proxy->init(); } bool CONNECTION_PROXY::change_user(const char* user, const char* passwd, const char* db) { return next_proxy->change_user(user, passwd, db); } bool CONNECTION_PROXY::real_connect( const char* host, const char* user, const char* passwd, const char* db, unsigned int port, const char* unix_socket, unsigned long clientflag) { return next_proxy->real_connect(host, user, passwd, db, port, unix_socket, clientflag); } int CONNECTION_PROXY::select_db(const char* db) { return next_proxy->select_db(db); } int CONNECTION_PROXY::query(const char* q) { return next_proxy->query(q); } int CONNECTION_PROXY::real_query(const char* q, unsigned long length) { return next_proxy->real_query(q, length); } MYSQL_RES* CONNECTION_PROXY::store_result() { return next_proxy->store_result(); } MYSQL_RES* CONNECTION_PROXY::use_result() { return next_proxy->use_result(); } struct CHARSET_INFO* CONNECTION_PROXY::get_character_set() const { return next_proxy->get_character_set(); } void CONNECTION_PROXY::get_character_set_info(MY_CHARSET_INFO* charset) { next_proxy->get_character_set_info(charset); } bool CONNECTION_PROXY::autocommit(bool auto_mode) { return next_proxy->autocommit(auto_mode); } bool CONNECTION_PROXY::commit() { return next_proxy->commit(); } bool CONNECTION_PROXY::rollback() { return next_proxy->rollback(); } bool CONNECTION_PROXY::more_results() { return next_proxy->more_results(); } int CONNECTION_PROXY::next_result() { return next_proxy->next_result(); } int CONNECTION_PROXY::stmt_next_result(MYSQL_STMT* stmt) { return next_proxy->stmt_next_result(stmt); } void CONNECTION_PROXY::close() { next_proxy->close(); } bool CONNECTION_PROXY::real_connect_dns_srv( const char* dns_srv_name, const char* user, const char* passwd, const char* db, unsigned long client_flag) { return next_proxy->real_connect_dns_srv(dns_srv_name, user, passwd, db, client_flag); } int CONNECTION_PROXY::ping() { return next_proxy->ping(); } unsigned long CONNECTION_PROXY::get_client_version(void) { return mysql_get_client_version(); } int CONNECTION_PROXY::get_option(mysql_option option, const void* arg) { return next_proxy->get_option(option, arg); } int CONNECTION_PROXY::options4(mysql_option option, const void* arg1, const void* arg2) { return next_proxy->options4(option, arg1, arg2); } int CONNECTION_PROXY::options(mysql_option option, const void* arg) { return next_proxy->options(option, arg); } void CONNECTION_PROXY::free_result(MYSQL_RES* result) { next_proxy->free_result(result); } void CONNECTION_PROXY::data_seek(MYSQL_RES* result, uint64_t offset) { next_proxy->data_seek(result, offset); } MYSQL_ROW_OFFSET CONNECTION_PROXY::row_seek(MYSQL_RES* result, MYSQL_ROW_OFFSET offset) { return next_proxy->row_seek(result, offset); } MYSQL_FIELD_OFFSET CONNECTION_PROXY::field_seek(MYSQL_RES* result, MYSQL_FIELD_OFFSET offset) { return next_proxy->field_seek(result, offset); } MYSQL_ROW CONNECTION_PROXY::fetch_row(MYSQL_RES* result) { return next_proxy->fetch_row(result); } unsigned long* CONNECTION_PROXY::fetch_lengths(MYSQL_RES* result) { return next_proxy->fetch_lengths(result); } MYSQL_FIELD* CONNECTION_PROXY::fetch_field(MYSQL_RES* result) { return next_proxy->fetch_field(result); } unsigned long CONNECTION_PROXY::real_escape_string(char* to, const char* from, unsigned long length) { return next_proxy->real_escape_string(to, from, length); } bool CONNECTION_PROXY::bind_param(unsigned n_params, MYSQL_BIND* binds, const char** names) { return next_proxy->bind_param(n_params, binds, names); } MYSQL_STMT* CONNECTION_PROXY::stmt_init() { return next_proxy->stmt_init(); } int CONNECTION_PROXY::stmt_prepare(MYSQL_STMT* stmt, const char* query, unsigned long length) { return next_proxy->stmt_prepare(stmt, query, length); } int CONNECTION_PROXY::stmt_execute(MYSQL_STMT* stmt) { return next_proxy->stmt_execute(stmt); } int CONNECTION_PROXY::stmt_fetch(MYSQL_STMT* stmt) { return next_proxy->stmt_fetch(stmt); } int CONNECTION_PROXY::stmt_fetch_column(MYSQL_STMT* stmt, MYSQL_BIND* bind_arg, unsigned int column, unsigned long offset) { return next_proxy->stmt_fetch_column(stmt, bind_arg, column, offset); } int CONNECTION_PROXY::stmt_store_result(MYSQL_STMT* stmt) { return next_proxy->stmt_store_result(stmt); } unsigned long CONNECTION_PROXY::stmt_param_count(MYSQL_STMT* stmt) { return next_proxy->stmt_param_count(stmt); } bool CONNECTION_PROXY::stmt_bind_named_param(MYSQL_STMT *stmt, MYSQL_BIND *binds, unsigned n_params, const char **names) { return next_proxy->stmt_bind_named_param(stmt, binds, n_params, names); } bool CONNECTION_PROXY::stmt_bind_param(MYSQL_STMT* stmt, MYSQL_BIND* bnd) { return next_proxy->stmt_bind_param(stmt, bnd); } bool CONNECTION_PROXY::stmt_bind_result(MYSQL_STMT* stmt, MYSQL_BIND* bnd) { return next_proxy->stmt_bind_result(stmt, bnd); } bool CONNECTION_PROXY::stmt_close(MYSQL_STMT* stmt) { return next_proxy->stmt_close(stmt); } bool CONNECTION_PROXY::stmt_reset(MYSQL_STMT* stmt) { return next_proxy->stmt_reset(stmt); } bool CONNECTION_PROXY::stmt_free_result(MYSQL_STMT* stmt) { return next_proxy->stmt_free_result(stmt); } bool CONNECTION_PROXY::stmt_send_long_data(MYSQL_STMT* stmt, unsigned int param_number, const char* data, unsigned long length) { return next_proxy->stmt_send_long_data(stmt, param_number, data, length); } MYSQL_RES* CONNECTION_PROXY::stmt_result_metadata(MYSQL_STMT* stmt) { return next_proxy->stmt_result_metadata(stmt); } unsigned int CONNECTION_PROXY::stmt_errno(MYSQL_STMT* stmt) { return next_proxy->stmt_errno(stmt); } const char* CONNECTION_PROXY::stmt_error(MYSQL_STMT* stmt) { return next_proxy->stmt_error(stmt); } MYSQL_ROW_OFFSET CONNECTION_PROXY::stmt_row_seek(MYSQL_STMT* stmt, MYSQL_ROW_OFFSET offset) { return next_proxy->stmt_row_seek(stmt, offset); } MYSQL_ROW_OFFSET CONNECTION_PROXY::stmt_row_tell(MYSQL_STMT* stmt) { return next_proxy->stmt_row_tell(stmt); } void CONNECTION_PROXY::stmt_data_seek(MYSQL_STMT* stmt, uint64_t offset) { next_proxy->stmt_data_seek(stmt, offset); } uint64_t CONNECTION_PROXY::stmt_num_rows(MYSQL_STMT* stmt) { return next_proxy->stmt_num_rows(stmt); } uint64_t CONNECTION_PROXY::stmt_affected_rows(MYSQL_STMT* stmt) { return next_proxy->stmt_affected_rows(stmt); } unsigned int CONNECTION_PROXY::stmt_field_count(MYSQL_STMT* stmt) { return next_proxy->stmt_field_count(stmt); } st_mysql_client_plugin* CONNECTION_PROXY::client_find_plugin(const char* name, int type) { return next_proxy->client_find_plugin(name, type); } bool CONNECTION_PROXY::is_connected() { return next_proxy->is_connected(); } void CONNECTION_PROXY::set_last_error_code(unsigned int error_code) { next_proxy->set_last_error_code(error_code); } char* CONNECTION_PROXY::get_last_error() const { return next_proxy->get_last_error(); } unsigned int CONNECTION_PROXY::get_last_error_code() const { return next_proxy->get_last_error_code(); } char* CONNECTION_PROXY::get_sqlstate() const { return next_proxy->get_sqlstate(); } char* CONNECTION_PROXY::get_server_version() const { return next_proxy->get_server_version(); } uint64_t CONNECTION_PROXY::get_affected_rows() const { return next_proxy->get_affected_rows(); } void CONNECTION_PROXY::set_affected_rows(uint64_t num_rows) { next_proxy->set_affected_rows(num_rows); } char* CONNECTION_PROXY::get_host_info() const { return next_proxy->get_host_info(); } std::string CONNECTION_PROXY::get_host() { return next_proxy->get_host(); } unsigned int CONNECTION_PROXY::get_port() { return next_proxy->get_port(); } unsigned long CONNECTION_PROXY::get_max_packet() const { return next_proxy->get_max_packet(); } unsigned long CONNECTION_PROXY::get_server_capabilities() const { return next_proxy->get_server_capabilities(); } unsigned int CONNECTION_PROXY::get_server_status() const { return next_proxy->get_server_status(); } void CONNECTION_PROXY::set_connection(CONNECTION_PROXY* connection_proxy) { next_proxy->set_connection(connection_proxy); } void CONNECTION_PROXY::close_socket() { next_proxy->close_socket(); } void CONNECTION_PROXY::set_next_proxy(CONNECTION_PROXY* next_proxy) { if (this->next_proxy) { throw std::runtime_error("There is already a next proxy present!"); } this->next_proxy = next_proxy; } MYSQL* CONNECTION_PROXY::move_mysql_connection() { return next_proxy ? next_proxy->move_mysql_connection() : nullptr; } void CONNECTION_PROXY::set_custom_error_message(const char* error_message) { this->custom_error_message = error_message; has_custom_error_message = true; }