From 7777073bf1a3d29de2afb9409ba4e1fc59b1c788 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Sat, 23 Dec 2023 18:54:38 +0100 Subject: [PATCH] mx_mysql: Refactor error handling The current error handling in mx_mysql logs errors multiple times in different forms due to nested functions and the mapping of MySQL error codes to system error codes. This leads to unclear semantics and complicated code. The current error handling return the same error in errno and in the function return value which results in uneeded accesses to errno This commit introduces the following changes: * MySQL error strings are captured but not logged by the module. A new function mx_mysql_error() is provided for the caller to retrieve the latest error string. * System error codes are returned as the function value, but errno is not set. * It is now the caller's responsibility to log errors. This change reduces the object size of mx_mysql by 28%. Future commits will address error return values that do not relate to MySQL error strings. --- mx_mysql.c | 332 +++++++++++++++++------------------------------------ mx_mysql.h | 13 +-- 2 files changed, 110 insertions(+), 235 deletions(-) diff --git a/mx_mysql.c b/mx_mysql.c index 87e4789b..b29c7eda 100644 --- a/mx_mysql.c +++ b/mx_mysql.c @@ -20,36 +20,31 @@ #include "mx_util.h" #include "mx_log.h" -#define mx__mysql_log(lvl, mysql) \ - mx_log_ ## lvl("MySQL %s(): ERROR %u (%s): %s", \ - (mysql)->func, \ - mx__mysql_errno(mysql), \ - mx__mysql_sqlstate(mysql), \ - mx__mysql_error(mysql)) - -#define mx__mysql_stmt_log(lvl, stmt) \ - mx_log_ ## lvl("MySQL %s(): ERROR %u (%s): %s", \ - (stmt)->func, \ - mx__mysql_stmt_errno(stmt), \ - mx__mysql_stmt_sqlstate(stmt), \ - mx__mysql_stmt_error(stmt)) - -#define mx__mysql_log_emerg(mysql) mx__mysql_log(emerg, (mysql)) -#define mx__mysql_log_err(mysql) mx__mysql_log(err, (mysql)) -#define mx__mysql_log_warning(mysql) mx__mysql_log(warning, (mysql)) -#define mx__mysql_log_info(mysql) mx__mysql_log(info, (mysql)) -#define mx__mysql_log_debug(mysql) mx__mysql_log(debug, (mysql)) - -#define mx__mysql_stmt_log_emerg(stmt) mx__mysql_stmt_log(emerg, (stmt)) -#define mx__mysql_stmt_log_err(stmt) mx__mysql_stmt_log(err, (stmt)) -#define mx__mysql_stmt_log_warning(stmt) mx__mysql_stmt_log(warning, (stmt)) -#define mx__mysql_stmt_log_info(stmt) mx__mysql_stmt_log(info, (stmt)) -#define mx__mysql_stmt_log_debug(stmt) mx__mysql_stmt_log(debug, (stmt)) - static struct mx_mysql_stmt *mx_mysql_statement_prepare_with_bindings(struct mx_mysql *mysql, char *statement, struct mx_mysql_bind *param, struct mx_mysql_bind *result); /**********************************************************************/ +static char* mx_mysql_last_error; + +__attribute__((destructor)) +static void mx_mysql_exit(void) { + free(mx_mysql_last_error); +} + +static void mx_mysql_save_error(const char *err) { + size_t len = strlen(err); + mx_mysql_last_error = realloc(mx_mysql_last_error, len+1); + if (mx_mysql_last_error == NULL) { + mx_log_crit("out of memory"); + return; + } + strncpy(mx_mysql_last_error, err, len+1); +} + +char *mx_mysql_error(void) { + return mx_mysql_last_error == NULL ? "no error information" : mx_mysql_last_error; +} + static int mx__mysql_errno(struct mx_mysql *mysql) { unsigned int error; @@ -73,15 +68,6 @@ static const char *mx__mysql_error(struct mx_mysql *mysql) return mysql_error(mysql->mysql); } -static const char *mx__mysql_sqlstate(struct mx_mysql *mysql) -{ - mx_assert_return_NULL(mysql, EINVAL); - mx_assert_return_NULL(mysql->mysql, EBADF); - - /* no mysql errors possible */ - return mysql_sqlstate(mysql->mysql); -} - static int mx__mysql_stmt_errno(struct mx_mysql_stmt *stmt) { unsigned int error; @@ -96,39 +82,16 @@ static int mx__mysql_stmt_errno(struct mx_mysql_stmt *stmt) return (int)error; } -static const char *mx__mysql_stmt_error(struct mx_mysql_stmt *stmt) -{ - mx_assert_return_NULL(stmt, EINVAL); - mx_assert_return_NULL(stmt->stmt, EBADF); - - /* no mysql errors possible */ - return mysql_stmt_error(stmt->stmt); -} - -static const char *mx__mysql_stmt_sqlstate(struct mx_mysql_stmt *stmt) -{ - mx_assert_return_NULL(stmt, EINVAL); - mx_assert_return_NULL(stmt->stmt, EBADF); - - /* no mysql errors possible */ - return mysql_stmt_sqlstate(stmt->stmt); -} - static int mx__mysql_init(struct mx_mysql *mysql) { mx_assert_return_minus_errno(mysql, EINVAL); mx_assert_return_minus_errno(!mysql->mysql, EUCLEAN); - mysql->func = "mysql_init"; mysql->mysql = mysql_init(NULL); if (mysql->mysql) return 0; - - errno = ENOMEM; - - mx_log_debug("Error: MySQL mysql_init(): %m"); - - return -errno; + mx_mysql_save_error("out of memory"); + return -ENOMEM; } static int mx__mysql_options(struct mx_mysql *mysql, enum mysql_option option, const void *arg) @@ -138,13 +101,11 @@ static int mx__mysql_options(struct mx_mysql *mysql, enum mysql_option option, c mx_assert_return_minus_errno(mysql, EINVAL); mx_assert_return_minus_errno(mysql->mysql, EBADF); - mysql->func = "mysql_options"; res = mysql_options(mysql->mysql, option, arg); if (res == 0) return 0; - - mx__mysql_log_emerg(mysql); - return -(errno=EBADE); + mx_mysql_save_error(mysql_error(mysql->mysql)); + return -EBADE; } static int mx__mysql_real_connect(struct mx_mysql *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag) @@ -154,19 +115,18 @@ static int mx__mysql_real_connect(struct mx_mysql *mysql, const char *host, cons mx_assert_return_minus_errno(mysql, EINVAL); mx_assert_return_minus_errno(mysql->mysql, EBADF); - mysql->func = "mysql_real_connect"; m = mysql_real_connect(mysql->mysql, host, user, passwd, db, port, unix_socket, client_flag); if (m && m == mysql->mysql) return 0; - mx__mysql_log_warning(mysql); + mx_mysql_save_error(mysql_error(mysql->mysql)); switch (mx__mysql_errno(mysql)) { case CR_ALREADY_CONNECTED: - return -(errno=EALREADY); + return -EALREADY; case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_CONN_HOST_ERROR: case CR_CONNECTION_ERROR: @@ -176,19 +136,9 @@ static int mx__mysql_real_connect(struct mx_mysql *mysql, const char *host, cons case CR_VERSION_ERROR: case CR_SERVER_LOST: case CR_SERVER_GONE_ERROR: - return -(errno=EAGAIN); - - case CR_NAMEDPIPEOPEN_ERROR: - case CR_NAMEDPIPEWAIT_ERROR: - case CR_NAMEDPIPESETSTATE_ERROR: - mx__mysql_log_emerg(mysql); - mx_log_emerg("ERROR: mysql_real_connect() returned Windows error number: %d", mx__mysql_errno(mysql)); - return -(errno=EBADE); /* we are not on windows*/ + return -EAGAIN; } - - mx__mysql_log_emerg(mysql); - mx_log_emerg("ERROR: mysql_real_connect() returned undefined error number: %d", mx__mysql_errno(mysql)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_ping(struct mx_mysql *mysql) @@ -198,20 +148,18 @@ static int mx__mysql_ping(struct mx_mysql *mysql) int res; - mysql->func = "mysql_ping"; res = mysql_ping(mysql->mysql); if (res == 0) return 0; - mx__mysql_log_warning(mysql); + mx_mysql_save_error(mysql_error(mysql->mysql)); switch (mx__mysql_errno(mysql)) { case CR_COMMANDS_OUT_OF_SYNC: - mx__mysql_log_emerg(mysql); - return -(errno=EPROTO); + return -EPROTO; case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_CONN_HOST_ERROR: case CR_CONNECTION_ERROR: @@ -221,15 +169,12 @@ static int mx__mysql_ping(struct mx_mysql *mysql) case CR_VERSION_ERROR: case CR_SERVER_LOST: case CR_SERVER_GONE_ERROR: - return -(errno=EAGAIN); + return -EAGAIN; case CR_UNKNOWN_ERROR: - return -(errno=EIO); + return -EIO; } - - mx__mysql_log_emerg(mysql); - mx_log_emerg("ERROR: mysql_ping() returned undefined error number: %d", mx__mysql_errno(mysql)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_init(struct mx_mysql_stmt *stmt) @@ -238,19 +183,11 @@ static int mx__mysql_stmt_init(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(!stmt->stmt, EUCLEAN); mx_assert_return_minus_errno(stmt->mysql, EBADF); - stmt->mysql->func = "mysql_stmt_init"; stmt->stmt = mysql_stmt_init(stmt->mysql->mysql); if (stmt->stmt) return 0; - - mx__mysql_log_warning(stmt->mysql); - - if (mx__mysql_errno(stmt->mysql) == CR_OUT_OF_MEMORY) - return -(errno=ENOMEM); - - mx__mysql_log_emerg(stmt->mysql); - mx_log_emerg("ERROR: mysql_stmt_init() returned undefined error number: %d", mx__mysql_errno(stmt->mysql)); - return -(errno=EBADE); + mx_mysql_save_error("out of memory"); + return -ENOMEM; } static int mx__mysql_stmt_prepare(struct mx_mysql_stmt *stmt, char *statement) @@ -266,38 +203,32 @@ static int mx__mysql_stmt_prepare(struct mx_mysql_stmt *stmt, char *statement) mx_assert_return_minus_errno(stmt->mysql, EBADF); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_prepare"; res = mysql_stmt_prepare(stmt->stmt, statement, strlen(statement)); if (res == 0) { stmt->statement = statement; return 0; } - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_COMMANDS_OUT_OF_SYNC: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; case CR_SERVER_GONE_ERROR: case CR_SERVER_LOST: - return -(errno=EAGAIN); + return -EAGAIN; case CR_UNKNOWN_ERROR: - return -(errno=EIO); + return -EIO; case ER_PARSE_ERROR: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EBADRQC); + return -EBADRQC; } - - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_prepare() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_bind_param(struct mx_mysql_stmt *stmt) @@ -307,28 +238,23 @@ static int mx__mysql_stmt_bind_param(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_bind_param"; res = (int)mysql_stmt_bind_param(stmt->stmt, stmt->param.bind); if (res == 0) return 0; - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_UNSUPPORTED_PARAM_TYPE: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; case CR_UNKNOWN_ERROR: - return -(errno=EIO); + return -EIO; } - - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_bind_param() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_bind_result(struct mx_mysql_stmt *stmt) @@ -338,27 +264,23 @@ static int mx__mysql_stmt_bind_result(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_bind_result"; res = (int)mysql_stmt_bind_result(stmt->stmt, stmt->result.bind); if (res == 0) return 0; - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_UNSUPPORTED_PARAM_TYPE: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; case CR_UNKNOWN_ERROR: - return -(errno=EIO); + return -EIO; } - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_bind_result() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_execute(struct mx_mysql_stmt *stmt) @@ -368,31 +290,27 @@ static int mx__mysql_stmt_execute(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_execute"; res = mysql_stmt_execute(stmt->stmt); if (res == 0) return 0; - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_COMMANDS_OUT_OF_SYNC: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_SERVER_GONE_ERROR: case CR_SERVER_LOST: - return -(errno=EAGAIN); + return -EAGAIN; case CR_UNKNOWN_ERROR: - return -(errno=EIO); + return -EIO; } - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_execute() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_store_result(struct mx_mysql_stmt *stmt) @@ -402,32 +320,27 @@ static int mx__mysql_stmt_store_result(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_store_result"; res = mysql_stmt_store_result(stmt->stmt); if (res == 0) return 0; - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_COMMANDS_OUT_OF_SYNC: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_SERVER_GONE_ERROR: case CR_SERVER_LOST: - return -(errno=EAGAIN); + return -EAGAIN; case CR_UNKNOWN_ERROR: - return -(errno=EIO); + return -EIO; } - - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_store_result() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_free_result(struct mx_mysql_stmt *stmt) @@ -437,14 +350,12 @@ static int mx__mysql_stmt_free_result(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_free_result"; res = (int)mysql_stmt_free_result(stmt->stmt); if (res == 0) return 0; - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_free_result() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); + return -EBADE; } static int mx__mysql_stmt_fetch(struct mx_mysql_stmt *stmt) @@ -454,47 +365,39 @@ static int mx__mysql_stmt_fetch(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_fetch"; res = mysql_stmt_fetch(stmt->stmt); if (res == 0) return 0; if (res == 1) { - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_OUT_OF_MEMORY: - return -(errno=ENOMEM); + return -ENOMEM; case CR_SERVER_GONE_ERROR: case CR_SERVER_LOST: - return -(errno=EAGAIN); + return -EAGAIN; case CR_UNKNOWN_ERROR: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EIO); + return -EIO; case CR_COMMANDS_OUT_OF_SYNC: case CR_UNSUPPORTED_PARAM_TYPE: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; } - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_fetch() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } switch (res) { case MYSQL_NO_DATA: - return -(errno=ENOENT); + return -ENOENT; case MYSQL_DATA_TRUNCATED: - return -(errno=ERANGE); + return -ERANGE; } - - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_fetch() returned undefined result code: %d", res); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_fetch_column(struct mx_mysql_stmt *stmt, unsigned int column, unsigned long offset) @@ -504,24 +407,19 @@ static int mx__mysql_stmt_fetch_column(struct mx_mysql_stmt *stmt, unsigned int mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_fetch_column"; res = mysql_stmt_fetch_column(stmt->stmt, &(stmt->result.bind[column]), column, offset); if (res == 0) return 0; - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_INVALID_PARAMETER_NO: - mx__mysql_stmt_log_emerg(stmt); - return -(errno=EPROTO); + return -EPROTO; case CR_NO_DATA: - return -(errno=ENOENT); + return -ENOENT; } - - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_fetch_column() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_stmt_param_count(struct mx_mysql_stmt *stmt) @@ -531,7 +429,6 @@ static int mx__mysql_stmt_param_count(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_param_count"; count = mysql_stmt_param_count(stmt->stmt); mx_assert_return_minus_errno((unsigned long)(int)count == count, ERANGE); @@ -546,7 +443,6 @@ static int mx__mysql_stmt_field_count(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_field_count"; count = mysql_stmt_field_count(stmt->stmt); mx_assert_return_minus_errno((unsigned long)(int)count == count, ERANGE); @@ -561,7 +457,6 @@ static int mx__mysql_stmt_affected_rows(struct mx_mysql_stmt *stmt, unsigned lon mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_affected_rows"; c = mysql_stmt_affected_rows(stmt->stmt); *count = (unsigned long long)c; @@ -577,7 +472,6 @@ static int mx__mysql_stmt_insert_id(struct mx_mysql_stmt *stmt, unsigned long lo mx_assert_return_minus_errno(stmt, EINVAL); mx_assert_return_minus_errno(stmt->stmt, EBADF); - stmt->func = "mysql_stmt_insert_id"; c = mysql_stmt_insert_id(stmt->stmt); *count = (unsigned long long)c; @@ -592,33 +486,27 @@ static int mx__mysql_stmt_close(struct mx_mysql_stmt *stmt) mx_assert_return_minus_errno(stmt, EINVAL); - stmt->func = "mysql_stmt_close"; res = mysql_stmt_close(stmt->stmt); if (res == 0) { stmt->stmt = NULL; return 0; } - - mx__mysql_stmt_log_warning(stmt); + mx_mysql_save_error(mysql_stmt_error(stmt->stmt)); switch (mx__mysql_stmt_errno(stmt)) { case CR_SERVER_GONE_ERROR: - return -(errno=ECONNABORTED); + return -ECONNABORTED; case CR_UNKNOWN_ERROR : - return -(errno=EIO); + return -EIO; } - - mx__mysql_stmt_log_emerg(stmt); - mx_log_emerg("ERROR: mysql_stmt_close() returned undefined error number: %d", mx__mysql_stmt_errno(stmt)); - return -(errno=EBADE); + return -EBADE; } static int mx__mysql_close(struct mx_mysql *mysql) { mx_assert_return_minus_errno(mysql, EINVAL); if (mysql->mysql) { - mysql->func = "mysql_close"; mysql_close(mysql->mysql); mysql->mysql = NULL; } @@ -703,7 +591,8 @@ static int _mx_mysql_bind_validate(struct mx_mysql_bind *b) for (unsigned long i=0; i < b->count; i++) { if (!(b->data[i].flags)) { - return -(errno=EBADSLT); + mx_mysql_save_error("binding not fully initialized"); + return -EBADSLT; } } @@ -740,7 +629,7 @@ static int mx_mysql_init(struct mx_mysql *mysql) if (res != -ENOMEM) return res; - mx_log_debug("mx__mysql_init() failed: %m - retrying (forever) in %d second(s).", MX_MYSQL_FAIL_WAIT_DEFAULT); + mx_log_debug("mx__mysql_init() failed: %s - retrying (forever) in %d second(s).", strerror(-res), MX_MYSQL_FAIL_WAIT_DEFAULT); mx_sleep(MX_MYSQL_FAIL_WAIT_DEFAULT); } while (1); @@ -848,9 +737,8 @@ int mx_mysql_connect_forever_sec(struct mx_mysql **mysql, unsigned int seconds) int res; while ((res = mx_mysql_connect(mysql)) < 0) { - mx__mysql_log_warning(*mysql); mx_mysql_assert_usage_ok(res); - mx_log_warning("mx_mysql_connect() failed: %m - retrying (forever) in %d second(s).", seconds); + mx_log_warning("mx_mysql_connect() failed: %s - retrying (forever) in %d second(s).", mx_mysql_error(), seconds); mx_sleep(seconds); } @@ -921,9 +809,8 @@ static int mx_mysql_ping_forever(struct mx_mysql *mysql) fail++; - mx__mysql_log_warning(mysql); mx_mysql_assert_usage_ok(res); - mx_log_warning("mx_mysql_ping() failed: %m - retrying again (forever) in %d second(s).", MX_MYSQL_FAIL_WAIT_DEFAULT); + mx_log_warning("mx_mysql_ping() failed: %s - retrying again (forever) in %d second(s).", mx_mysql_error(), MX_MYSQL_FAIL_WAIT_DEFAULT); mx_sleep(MX_MYSQL_FAIL_WAIT_DEFAULT); } @@ -945,7 +832,6 @@ static int mx_mysql_statement_init(struct mx_mysql *mysql, struct mx_mysql_stmt s = mx_calloc_forever(1, sizeof(*s)); s->mysql = mysql; - s->func = ""; do { res = mx__mysql_stmt_init(s); @@ -955,7 +841,7 @@ static int mx_mysql_statement_init(struct mx_mysql *mysql, struct mx_mysql_stmt if (res != -ENOMEM) return res; - mx_log_debug("mx__mysql_stmt_init() failed: %m - retrying (forever) in %d second(s).", MX_MYSQL_FAIL_WAIT_DEFAULT); + mx_log_debug("mx__mysql_stmt_init() failed: %s - retrying (forever) in %d second(s).", strerror(-res), MX_MYSQL_FAIL_WAIT_DEFAULT); mx_sleep(MX_MYSQL_FAIL_WAIT_DEFAULT); } while (1); @@ -973,32 +859,31 @@ int mx_mysql_statement_execute(struct mx_mysql_stmt *stmt, unsigned long long *c res = _mx_mysql_bind_validate(&stmt->param); if (res < 0) { - mx_log_crit("MxSQL: parameter list for prepared statement not initialized completely."); return res; } res = mx__mysql_stmt_bind_param(stmt); if (res < 0) { - mx_log_debug("ERROR: mx__mysql_stmt_bind_param: %m"); + mx_log_debug("ERROR: mx__mysql_stmt_bind_param: %s", strerror(-res)); return res; } res = mx__mysql_stmt_execute(stmt); if (res < 0) { - mx_log_debug("ERROR: mx__mysql_stmt_execute: %m"); + mx_log_debug("ERROR: mx__mysql_stmt_execute: %s", strerror(-res)); return res; } res = mx__mysql_stmt_store_result(stmt); if (res < 0) { - mx_log_debug("ERROR: mx__mysql_stmt_store_result: %m"); + mx_log_debug("ERROR: mx__mysql_stmt_store_result: %s", strerror(-res)); return res; } if (count) { res = mx__mysql_stmt_affected_rows(stmt, count); if (res < 0) { - mx_log_debug("ERROR: mx__mysql_stmt_affected_rows(): %m"); + mx_log_debug("ERROR: mx__mysql_stmt_affected_rows(): %s", strerror(-res)); return res; } } @@ -1028,7 +913,7 @@ int mx_mysql_statement_fetch(struct mx_mysql_stmt *stmt) res = mx__mysql_stmt_bind_result(stmt); if (res < 0) { - mx_log_debug("ERROR: mx__mysql_stmt_bind_result: %m"); + mx_log_debug("ERROR: mx__mysql_stmt_bind_result: %s", strerror(-res)); return res; } @@ -1037,7 +922,7 @@ int mx_mysql_statement_fetch(struct mx_mysql_stmt *stmt) return 0; if (res < 0 && res != -ERANGE) { - mx_log_debug("ERROR: mx__mysql_stmt_fetch: %m"); + mx_log_debug("ERROR: mx__mysql_stmt_fetch: %s", strerror(-res)); return res; } @@ -1067,7 +952,7 @@ int mx_mysql_statement_fetch(struct mx_mysql_stmt *stmt) } if (!no_error) - return -(errno=ERANGE); + return -ERANGE; return 0; } @@ -1171,23 +1056,20 @@ static int _mx_mysql_do_statement(struct mx_mysql *mysql, char *query, struct mx stmt = mx_mysql_statement_prepare_with_bindings(mysql, query, param, result); if (!stmt) { - mx_log_err("mx_mysql_statement_prepare_with_bindings(): %m"); - mx_log_err("mx_mysql_statement_prepare_with_bindings(): query was: %s", query); if (cleanup) { mx_mysql_bind_cleanup(param); mx_mysql_bind_cleanup(result); } - return -errno; + return -EINVAL; } res = mx_mysql_statement_execute(stmt, &num_rows); if (res < 0) { - mx_log_err("mx_mysql_statement_execute(): %m"); if (cleanup) mx_mysql_statement_close(&stmt); else mx_mysql_statement_close_no_bind_cleanup(&stmt); - return -(errno=-res); + return res; } if (result && result->count && num_rows) { @@ -1196,13 +1078,12 @@ static int _mx_mysql_do_statement(struct mx_mysql *mysql, char *query, struct mx for (unsigned long cnt = 0; cnt < num_rows; cnt++) { res = mx_mysql_statement_fetch(stmt); if (res < 0) { - mx_log_err("mx_mysql_statement_fetch(): %m"); mx_free_null(tmpdata); if (cleanup) mx_mysql_statement_close(&stmt); else mx_mysql_statement_close_no_bind_cleanup(&stmt); - return -(errno=-res); + return res; } memcpy(tmpdata+(cnt*size), from, size); } @@ -1238,7 +1119,7 @@ int mx_mysql_do_statement_retry_on_fail(struct mx_mysql *mysql, char *query, str mx_mysql_assert_usage_ok(res); - mx_log_warning("mx_mysql_do_statement() failed: %m"); + mx_log_warning("mx_mysql_do_statement() failed: %s", strerror(-res)); if (res != -EAGAIN) break; @@ -1289,9 +1170,6 @@ static struct mx_mysql_stmt *mx_mysql_statement_prepare_with_bindings(struct mx_ return stmt; }; - if (res < 0) - mx__mysql_stmt_log_warning(stmt); - mx_mysql_statement_close_no_bind_cleanup(&stmt); return NULL; @@ -1342,7 +1220,7 @@ static int mx_mysql_bind_integer(struct mx_mysql_bind *b, unsigned int index, vo if (res == 0) return 0; - mx_log_debug("Failed to set index %d: %m", index); + mx_log_debug("Failed to set index %d: %s", index, strerror(-res)); return res; } @@ -1354,7 +1232,7 @@ int mx_mysql_bind_string(struct mx_mysql_bind *b, unsigned int index, char **val if (res == 0) return 0; - mx_log_debug("Failed to set index %d: %m", index); + mx_log_debug("Failed to set index %d: %s", index, strerror(-res)); return res; } diff --git a/mx_mysql.h b/mx_mysql.h index ae5f79e4..c09c3bb7 100644 --- a/mx_mysql.h +++ b/mx_mysql.h @@ -22,18 +22,15 @@ #define mx_mysql_assert_usage_ok(res) \ do { \ if ((res) < 0) { \ - assert((res) == -errno); \ - assert(errno != EINVAL); \ - assert(errno != EBADF); \ - assert(errno != EUCLEAN); \ + assert(res != EINVAL); \ + assert(res != EBADF); \ + assert(res != EUCLEAN); \ } \ } while (0) struct mx_mysql { MYSQL *mysql; - const char *func; - char *default_file; char *default_group; bool reconnect; @@ -74,8 +71,6 @@ struct mx_mysql_stmt { MYSQL_STMT *stmt; - const char *func; - unsigned long field_count; unsigned long param_count; @@ -149,4 +144,6 @@ int mx_mysql_bind_uint16(struct mx_mysql_bind *b, unsigned int index, uint16_t * int mx_mysql_bind_uint32(struct mx_mysql_bind *b, unsigned int index, uint32_t *value); int mx_mysql_bind_uint64(struct mx_mysql_bind *b, unsigned int index, uint64_t *value); +char *mx_mysql_error(void); + #endif