From 46a975bd04d7609ba9c912aa8c4de91ffb3d00a1 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Mon, 28 Dec 2015 09:00:24 +0100 Subject: [PATCH] Added st_mariadb_api structure which contains api definition for use in dynamic plugins --- include/mysql.h | 124 +++++++++++++++++++++++++++++- libmariadb/libmariadb.c | 125 +++++++++++++++++++++++++++++++ plugins/connection/aurora.c | 23 +++--- plugins/connection/replication.c | 11 ++- 4 files changed, 270 insertions(+), 13 deletions(-) diff --git a/include/mysql.h b/include/mysql.h index dc2577a4..473f7401 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -443,7 +443,6 @@ int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher); const char * STDCALL mysql_get_ssl_cipher(MYSQL *mysql); -int STDCALL mysql_ssl_clear(MYSQL *mysql); MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd); my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, @@ -640,6 +639,128 @@ int STDCALL mysql_stmt_send_long_data_cont(my_bool *ret, MYSQL_STMT *stmt, int status); +/* API function calls (used by dynmic plugins) */ +struct st_mariadb_api { + my_ulonglong (*mysql_num_rows)(MYSQL_RES *res); + unsigned int (*mysql_num_fields)(MYSQL_RES *res); + my_bool (*mysql_eof)(MYSQL_RES *res); + MYSQL_FIELD *(*mysql_fetch_field_direct)(MYSQL_RES *res, unsigned int fieldnr); + MYSQL_FIELD * (*mysql_fetch_fields)(MYSQL_RES *res); + MYSQL_ROWS * (*mysql_row_tell)(MYSQL_RES *res); + unsigned int (*mysql_field_tell)(MYSQL_RES *res); + unsigned int (*mysql_field_count)(MYSQL *mysql); + my_bool (*mysql_more_results)(MYSQL *mysql); + int (*mysql_next_result)(MYSQL *mysql); + my_ulonglong (*mysql_affected_rows)(MYSQL *mysql); + my_bool (*mysql_autocommit)(MYSQL *mysql, my_bool mode); + my_bool (*mysql_commit)(MYSQL *mysql); + my_bool (*mysql_rollback)(MYSQL *mysql); + my_ulonglong (*mysql_insert_id)(MYSQL *mysql); + unsigned int (*mysql_errno)(MYSQL *mysql); + char * (*mysql_error)(MYSQL *mysql); + char * (*mysql_info)(MYSQL *mysql); + unsigned long (*mysql_thread_id)(MYSQL *mysql); + const char * (*mysql_character_set_name)(MYSQL *mysql); + void (*mysql_get_character_set_info)(MYSQL *mysql, MY_CHARSET_INFO *cs); + int (*mysql_set_character_set)(MYSQL *mysql, const char *csname); + my_bool (*mariadb_get_infov)(MYSQL *mysql, enum mariadb_value value, void *arg, ...); + my_bool (*mariadb_get_info)(MYSQL *mysql, enum mariadb_value value, void *arg); + MYSQL * (*mysql_init)(MYSQL *mysql); + int (*mysql_ssl_set)(MYSQL *mysql, const char *key, const char *cert, const char *ca, const char *capath, const char *cipher); + const char * (*mysql_get_ssl_cipher)(MYSQL *mysql); + MYSQL * (*mysql_connect)(MYSQL *mysql, const char *host, const char *user, const char *passwd); + my_bool (*mysql_change_user)(MYSQL *mysql, const char *user, const char *passwd, const char *db); + MYSQL * (*mysql_real_connect)(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag); + void (*mysql_close)(MYSQL *sock); + int (*mysql_select_db)(MYSQL *mysql, const char *db); + int (*mysql_query)(MYSQL *mysql, const char *q); + int (*mysql_send_query)(MYSQL *mysql, const char *q, size_t length); + my_bool (*mysql_read_query_result)(MYSQL *mysql); + int (*mysql_real_query)(MYSQL *mysql, const char *q, size_t length); + int (*mysql_create_db)(MYSQL *mysql, const char *DB); + int (*mysql_drop_db)(MYSQL *mysql, const char *DB); + int (*mysql_shutdown)(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level); + int (*mysql_dump_debug_info)(MYSQL *mysql); + int (*mysql_refresh)(MYSQL *mysql, unsigned int refresh_options); + int (*mysql_kill)(MYSQL *mysql,unsigned long pid); + int (*mysql_ping)(MYSQL *mysql); + char * (*mysql_stat)(MYSQL *mysql); + char * (*mysql_get_server_info)(MYSQL *mysql); + unsigned long (*mysql_get_server_version)(MYSQL *mysql); + char * (*mysql_get_host_info)(MYSQL *mysql); + unsigned int (*mysql_get_proto_info)(MYSQL *mysql); + MYSQL_RES * (*mysql_list_dbs)(MYSQL *mysql,const char *wild); + MYSQL_RES * (*mysql_list_tables)(MYSQL *mysql,const char *wild); + MYSQL_RES * (*mysql_list_fields)(MYSQL *mysql, const char *table, const char *wild); + MYSQL_RES * (*mysql_list_processes)(MYSQL *mysql); + MYSQL_RES * (*mysql_store_result)(MYSQL *mysql); + MYSQL_RES * (*mysql_use_result)(MYSQL *mysql); + int (*mysql_options)(MYSQL *mysql,enum mysql_option option, const void *arg); + void (*mysql_free_result)(MYSQL_RES *result); + void (*mysql_data_seek)(MYSQL_RES *result, my_ulonglong offset); + MYSQL_ROW_OFFSET (*mysql_row_seek)(MYSQL_RES *result, MYSQL_ROW_OFFSET); + MYSQL_FIELD_OFFSET (*mysql_field_seek)(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset); + MYSQL_ROW (*mysql_fetch_row)(MYSQL_RES *result); + unsigned long * (*mysql_fetch_lengths)(MYSQL_RES *result); + MYSQL_FIELD * (*mysql_fetch_field)(MYSQL_RES *result); + unsigned long (*mysql_escape_string)(char *to,const char *from, unsigned long from_length); + unsigned long (*mysql_real_escape_string)(MYSQL *mysql, char *to,const char *from, unsigned long length); + void (*mysql_debug)(const char *debug); + void (*mysql_debug_end)(void); + unsigned int (*mysql_thread_safe)(void); + unsigned int (*mysql_warning_count)(MYSQL *mysql); + const char * (*mysql_sqlstate)(MYSQL *mysql); + int (*mysql_server_init)(int argc, char **argv, char **groups); + void (*mysql_server_end)(void); + void (*mysql_thread_end)(void); + my_bool (*mysql_thread_init)(void); + int (*mysql_set_server_option)(MYSQL *mysql, enum enum_mysql_set_option option); + const char * (*mysql_get_client_info)(void); + unsigned long (*mysql_get_client_version)(void); + my_bool (*mariadb_connection)(MYSQL *mysql); + const char * (*mysql_get_server_name)(MYSQL *mysql); + CHARSET_INFO * (*mariadb_get_charset_by_name)(const char *csname); + CHARSET_INFO * (*mariadb_get_charset_by_nr)(unsigned int csnr); + size_t (*mariadb_convert_string)(const char *from, size_t *from_len, CHARSET_INFO *from_cs, char *to, size_t *to_len, CHARSET_INFO *to_cs, int *errorcode); + int (*mysql_optionsv)(MYSQL *mysql,enum mysql_option option, ...); + int (*mysql_get_optionv)(MYSQL *mysql, enum mysql_option option, void *arg, ...); + int (*mysql_get_option)(MYSQL *mysql, enum mysql_option option, void *arg); + MYSQL_PARAMETERS *(*mysql_get_parameters)(void); + unsigned long (*mysql_hex_string)(char *to, const char *from, size_t len); + my_socket (*mysql_get_socket)(MYSQL *mysql); + unsigned int (*mysql_get_timeout_value)(const MYSQL *mysql); + unsigned int (*mysql_get_timeout_value_ms)(const MYSQL *mysql); + my_bool (*mysql_reconnect)(MYSQL *mysql); + MYSQL_STMT * (*mysql_stmt_init)(MYSQL *mysql); + int (*mysql_stmt_prepare)(MYSQL_STMT *stmt, const char *query, size_t length); + int (*mysql_stmt_execute)(MYSQL_STMT *stmt); + int (*mysql_stmt_fetch)(MYSQL_STMT *stmt); + int (*mysql_stmt_fetch_column)(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, unsigned int column, unsigned long offset); + int (*mysql_stmt_store_result)(MYSQL_STMT *stmt); + unsigned long (*mysql_stmt_param_count)(MYSQL_STMT * stmt); + my_bool (*mysql_stmt_attr_set)(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, const void *attr); + my_bool (*mysql_stmt_attr_get)(MYSQL_STMT *stmt, enum enum_stmt_attr_type attr_type, void *attr); + my_bool (*mysql_stmt_bind_param)(MYSQL_STMT * stmt, MYSQL_BIND * bnd); + my_bool (*mysql_stmt_bind_result)(MYSQL_STMT * stmt, MYSQL_BIND * bnd); + my_bool (*mysql_stmt_close)(MYSQL_STMT * stmt); + my_bool (*mysql_stmt_reset)(MYSQL_STMT * stmt); + my_bool (*mysql_stmt_free_result)(MYSQL_STMT *stmt); + my_bool (*mysql_stmt_send_long_data)(MYSQL_STMT *stmt, unsigned int param_number, const char *data, size_t length); + MYSQL_RES *(*mysql_stmt_result_metadata)(MYSQL_STMT *stmt); + MYSQL_RES *(*mysql_stmt_param_metadata)(MYSQL_STMT *stmt); + unsigned int (*mysql_stmt_errno)(MYSQL_STMT * stmt); + const char *(*mysql_stmt_error)(MYSQL_STMT * stmt); + const char *(*mysql_stmt_sqlstate)(MYSQL_STMT * stmt); + MYSQL_ROW_OFFSET (*mysql_stmt_row_seek)(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset); + MYSQL_ROW_OFFSET (*mysql_stmt_row_tell)(MYSQL_STMT *stmt); + void (*mysql_stmt_data_seek)(MYSQL_STMT *stmt, my_ulonglong offset); + my_ulonglong (*mysql_stmt_num_rows)(MYSQL_STMT *stmt); + my_ulonglong (*mysql_stmt_affected_rows)(MYSQL_STMT *stmt); + my_ulonglong (*mysql_stmt_insert_id)(MYSQL_STMT *stmt); + unsigned int (*mysql_stmt_field_count)(MYSQL_STMT *stmt); + int (*mysql_stmt_next_result)(MYSQL_STMT *stmt); + my_bool (*mysql_stmt_more_results)(MYSQL_STMT *stmt); +}; /* these methods can be overwritten by db plugins */ struct st_mysql_methods { @@ -663,6 +784,7 @@ struct st_mysql_methods { int (*db_stmt_fetch_to_bind)(MYSQL_STMT *stmt, unsigned char *row); void (*db_stmt_flush_unbuffered)(MYSQL_STMT *stmt); void (*set_error)(MYSQL *mysql, unsigned int error_nr, const char *sqlstate, const char *format, ...); + struct st_mariadb_api *api; }; /* synonyms/aliases functions */ diff --git a/libmariadb/libmariadb.c b/libmariadb/libmariadb.c index 9d8a43c5..bb976041 100644 --- a/libmariadb/libmariadb.c +++ b/libmariadb/libmariadb.c @@ -3742,6 +3742,130 @@ my_bool STDCALL mariadb_get_info(MYSQL *mysql, enum mariadb_value value, void *a { return mariadb_get_infov(mysql, value, arg); } + +/* API functions for usage in dynamic plugins */ +struct st_mariadb_api MARIADB_API= { + mysql_num_rows, + mysql_num_fields, + mysql_eof, + mysql_fetch_field_direct, + mysql_fetch_fields, + mysql_row_tell, + mysql_field_tell, + mysql_field_count, + mysql_more_results, + mysql_next_result, + mysql_affected_rows, + mysql_autocommit, + mysql_commit, + mysql_rollback, + mysql_insert_id, + mysql_errno, + mysql_error, + mysql_info, + mysql_thread_id, + mysql_character_set_name, + mysql_get_character_set_info, + mysql_set_character_set, + mariadb_get_infov, + mariadb_get_info, + mysql_init, + mysql_ssl_set, + mysql_get_ssl_cipher, + mysql_connect, + mysql_change_user, + mysql_real_connect, + mysql_close, + mysql_select_db, + mysql_query, + mysql_send_query, + mysql_read_query_result, + mysql_real_query, + mysql_create_db, + mysql_drop_db, + mysql_shutdown, + mysql_dump_debug_info, + mysql_refresh, + mysql_kill, + mysql_ping, + mysql_stat, + mysql_get_server_info, + mysql_get_server_version, + mysql_get_host_info, + mysql_get_proto_info, + mysql_list_dbs, + mysql_list_tables, + mysql_list_fields, + mysql_list_processes, + mysql_store_result, + mysql_use_result, + mysql_options, + mysql_free_result, + mysql_data_seek, + mysql_row_seek, + mysql_field_seek, + mysql_fetch_row, + mysql_fetch_lengths, + mysql_fetch_field, + mysql_escape_string, + mysql_real_escape_string, + mysql_debug, + mysql_debug_end, + mysql_thread_safe, + mysql_warning_count, + mysql_sqlstate, + mysql_server_init, + mysql_server_end, + mysql_thread_end, + mysql_thread_init, + mysql_set_server_option, + mysql_get_client_info, + mysql_get_client_version, + mariadb_connection, + mysql_get_server_name, + mariadb_get_charset_by_name, + mariadb_get_charset_by_nr, + mariadb_convert_string, + mysql_optionsv, + mysql_get_optionv, + mysql_get_option, + mysql_get_parameters, + mysql_hex_string, + mysql_get_socket, + mysql_get_timeout_value, + mysql_get_timeout_value_ms, + mysql_reconnect, + mysql_stmt_init, + mysql_stmt_prepare, + mysql_stmt_execute, + mysql_stmt_fetch, + mysql_stmt_fetch_column, + mysql_stmt_store_result, + mysql_stmt_param_count, + mysql_stmt_attr_set, + mysql_stmt_attr_get, + mysql_stmt_bind_param, + mysql_stmt_bind_result, + mysql_stmt_close, + mysql_stmt_reset, + mysql_stmt_free_result, + mysql_stmt_send_long_data, + mysql_stmt_result_metadata, + mysql_stmt_param_metadata, + mysql_stmt_errno, + mysql_stmt_error, + mysql_stmt_sqlstate, + mysql_stmt_row_seek, + mysql_stmt_row_tell, + mysql_stmt_data_seek, + mysql_stmt_num_rows, + mysql_stmt_affected_rows, + mysql_stmt_insert_id, + mysql_stmt_field_count, + mysql_stmt_next_result, + mysql_stmt_more_results +}; + /* * Default methods for a connection. These methods are * stored in mysql->methods and can be overwritten by @@ -3782,4 +3906,5 @@ struct st_mysql_methods MARIADB_DEFAULT_METHODS = { mthd_stmt_flush_unbuffered, /* set error */ my_set_error, + &MARIADB_API }; diff --git a/plugins/connection/aurora.c b/plugins/connection/aurora.c index 3f54dd04..76d828de 100644 --- a/plugins/connection/aurora.c +++ b/plugins/connection/aurora.c @@ -82,6 +82,8 @@ MARIADB_CONNECTION_PLUGIN _mysql_client_plugin_declaration_ = aurora_reconnect }; +struct st_mariadb_api *mariadb_api= NULL; + typedef struct st_aurora_instance { char *host; int port; @@ -258,7 +260,7 @@ int aurora_get_instance_type(MYSQL *mysql) int rc; char *query= "select variable_value from information_schema.global_variables where variable_name='INNODB_READ_ONLY' AND variable_value='OFF'"; - if (!mysql_query(mysql, query)) + if (!mariadb_api->mysql_query(mysql, query)) { MYSQL_RES *res= mysql_store_result(mysql); rc= mysql_num_rows(res) ? AURORA_PRIMARY : AURORA_REPLICA; @@ -286,7 +288,7 @@ my_bool aurora_get_primary_id(MYSQL *mysql, AURORA *aurora) { my_bool rc= 0; - if (!mysql_query(mysql, "select server_id from information_schema.replica_host_status " + if (!mariadb_api->mysql_query(mysql, "select server_id from information_schema.replica_host_status " "where session_id = 'MASTER_SESSION_ID'")) { MYSQL_RES *res; @@ -414,7 +416,7 @@ void aurora_copy_mysql(MYSQL *from, MYSQL *to) memset(&to->options, 0, sizeof(to->options)); to->free_me= 0; to->net.conn_hdlr= 0; - mysql_close(to); + mariadb_api->mysql_close(to); *to= *from; to->net.pvio= from->net.pvio; to->net.pvio->mysql= to; @@ -434,7 +436,7 @@ my_bool aurora_find_replica(AURORA *aurora) if (aurora->num_instances < 2) return 0; - mysql_init(&mysql); + mariadb_api->mysql_init(&mysql); mysql.options= aurora->mysql[AURORA_PRIMARY]->options; /* don't execute init_command on slave */ @@ -503,7 +505,7 @@ my_bool aurora_find_primary(AURORA *aurora) if (!aurora->num_instances) return 0; - mysql_init(&mysql); + mariadb_api->mysql_init(&mysql); mysql.options= aurora->mysql[AURORA_PRIMARY]->options; mysql.net.conn_hdlr= aurora->mysql[AURORA_PRIMARY]->net.conn_hdlr; @@ -545,7 +547,7 @@ void aurora_close_replica(MYSQL *mysql, AURORA *aurora) { aurora->mysql[AURORA_REPLICA]->net.pvio->mysql= aurora->mysql[AURORA_REPLICA]; aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0; - mysql_close(aurora->mysql[AURORA_REPLICA]); + mariadb_api->mysql_close(aurora->mysql[AURORA_REPLICA]); aurora->pvio[AURORA_REPLICA]= 0; aurora->mysql[AURORA_REPLICA]= NULL; } @@ -560,6 +562,9 @@ MYSQL *aurora_connect(MYSQL *mysql, const char *host, const char *user, const ch MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr; my_bool is_reconnect= 0; + if (!mariadb_api) + mariadb_api= mysql->methods->api; + if ((aurora= (AURORA *)hdlr->data)) { aurora_refresh_blacklist(aurora); @@ -660,7 +665,7 @@ my_bool aurora_reconnect(MYSQL *mysql) switch (aurora->last_instance_type) { case AURORA_REPLICA: - if (!(rc= mysql_reconnect(aurora->mysql[aurora->last_instance_type]))) + if (!(rc= mariadb_api->mysql_reconnect(aurora->mysql[aurora->last_instance_type]))) aurora_switch_connection(mysql, aurora, AURORA_REPLICA); break; case AURORA_PRIMARY: @@ -692,7 +697,7 @@ void aurora_close(MYSQL *mysql) { /* we got options from primary, so don't free it twice */ memset(&aurora->mysql[AURORA_REPLICA]->options, 0, sizeof(mysql->options)); - /* connection handler wull be freed in mysql_close() */ + /* connection handler wull be freed in mariadb_api->mysql_close() */ aurora->mysql[AURORA_REPLICA]->net.conn_hdlr= 0; mysql_close(aurora->mysql[AURORA_REPLICA]); @@ -781,7 +786,7 @@ int aurora_command(MYSQL *mysql,enum enum_server_command command, const char *ar { aurora_switch_connection(mysql, aurora, AURORA_REPLICA); DISABLE_AURORA(mysql); - mysql_select_db(aurora->mysql[AURORA_REPLICA], arg); + mariadb_api->mysql_select_db(aurora->mysql[AURORA_REPLICA], arg); ENABLE_AURORA(mysql); aurora_switch_connection(mysql, aurora, AURORA_PRIMARY); } diff --git a/plugins/connection/replication.c b/plugins/connection/replication.c index 7c5eeabf..9b4d1865 100644 --- a/plugins/connection/replication.c +++ b/plugins/connection/replication.c @@ -45,6 +45,8 @@ int repl_set_options(MYSQL *msql, enum mysql_option option, void *arg); #define MARIADB_MASTER 0 #define MARIADB_SLAVE 1 +struct st_mariadb_api *mariadb_api= NULL; + #ifndef HAVE_REPLICATION_DYNAMIC MARIADB_CONNECTION_PLUGIN connection_replication_plugin = #else @@ -179,6 +181,9 @@ MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char REPL_DATA *data= NULL; MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr; + if (!mariadb_api) + mariadb_api= mysql->methods->api; + if ((data= (REPL_DATA *)hdlr->data)) { data->pvio[MARIADB_MASTER]->methods->close(data->pvio[MARIADB_MASTER]); @@ -209,12 +214,12 @@ MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char * connecting to slave(s) in background */ /* if slave connection will fail, we will not return error but use master instead */ - if (!(data->slave_mysql= mysql_init(NULL)) || + if (!(data->slave_mysql= mariadb_api->mysql_init(NULL)) || !(mysql->methods->db_connect(data->slave_mysql, data->host[MARIADB_SLAVE], user, passwd, db, data->port[MARIADB_SLAVE] ? data->port[MARIADB_SLAVE] : port, unix_socket, clientflag))) { if (data->slave_mysql) - mysql_close(data->slave_mysql); + mariadb_api->mysql_close(data->slave_mysql); data->pvio[MARIADB_SLAVE]= NULL; } else @@ -246,7 +251,7 @@ void repl_close(MYSQL *mysql) { /* restore mysql */ data->pvio[MARIADB_SLAVE]->mysql= data->slave_mysql; - mysql_close(data->slave_mysql); + mariadb_api->mysql_close(data->slave_mysql); data->pvio[MARIADB_SLAVE]= NULL; data->slave_mysql= NULL; }