From 231bc3fc8d1902bb19b6fce39ffd72cce4b4f2c3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 12 Jun 2021 20:26:01 +0100 Subject: Avoid direct use of runtime_error in MySQL stuff Adds proper exception which extends it and gets the MySQL error message. --- lib/input/mysqlBindings.h | 2 +- lib/input/mysqlConn.cpp | 14 ++++++++------ lib/input/mysqlConn.h | 5 +++++ lib/input/mysqlRecordSet.cpp | 12 ++++++------ lib/input/mysqlStmt.cpp | 7 ++++--- lib/input/replStream.cpp | 2 +- lib/input/replStream.h | 2 +- 7 files changed, 26 insertions(+), 18 deletions(-) (limited to 'lib/input') diff --git a/lib/input/mysqlBindings.h b/lib/input/mysqlBindings.h index 569aeb5..84a2d28 100644 --- a/lib/input/mysqlBindings.h +++ b/lib/input/mysqlBindings.h @@ -63,7 +63,7 @@ namespace MyGrate::Input { void operator()(const T &) { - throw std::runtime_error("Not implemented"); + throw std::logic_error("Not implemented"); } std::vector binds; std::vector data; diff --git a/lib/input/mysqlConn.cpp b/lib/input/mysqlConn.cpp index 4899deb..c7705f5 100644 --- a/lib/input/mysqlConn.cpp +++ b/lib/input/mysqlConn.cpp @@ -11,6 +11,8 @@ #include namespace MyGrate::Input { + MySQLErr::MySQLErr(const std::string & when, MYSQL * c) : std::runtime_error(when + ": " + mysql_error(c)) { } + MySQLConn::MySQLConn( const char * const host, const char * const user, const char * const pass, unsigned short port) : st_mysql {} @@ -18,9 +20,9 @@ namespace MyGrate::Input { mysql_init(this); if (!mysql_real_connect(this, host, user, pass, "", port, nullptr, 0)) { mysql_close(this); - throw std::runtime_error("ConnectionError"); + throw MySQLErr("Connecting", this); } - verify(!mysql_set_character_set(this, "utf8"), "Set character set"); + verify(!mysql_set_character_set(this, "utf8"), "Setting char set", this); } MySQLConn::~MySQLConn() @@ -31,18 +33,18 @@ namespace MyGrate::Input { void MySQLConn::query(const char * const q) { - verify(!mysql_query(this, q), q); + verify(!mysql_query(this, q), q, this); } void MySQLConn::query(const char * const q, const std::initializer_list & vs) { StmtPtr stmt {mysql_stmt_init(this), &mysql_stmt_close}; - verify(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q); + verify(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q, this); verify(mysql_stmt_param_count(stmt.get()) == vs.size(), "Param count mismatch"); Bindings b {vs}; - verify(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); - verify(!mysql_stmt_execute(stmt.get()), q); + verify(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); + verify(!mysql_stmt_execute(stmt.get()), q, this); } DbPrepStmtPtr diff --git a/lib/input/mysqlConn.h b/lib/input/mysqlConn.h index db30ff0..d779fd1 100644 --- a/lib/input/mysqlConn.h +++ b/lib/input/mysqlConn.h @@ -10,6 +10,11 @@ namespace MyGrate { class DbValue; } namespace MyGrate::Input { + class MySQLErr : public std::runtime_error { + public: + MySQLErr(const std::string & when, MYSQL *); + }; + class MySQLConn : public MYSQL, public DbConn { public: static constexpr auto paramMode {ParamMode::QMark}; diff --git a/lib/input/mysqlRecordSet.cpp b/lib/input/mysqlRecordSet.cpp index 51be15f..22b7214 100644 --- a/lib/input/mysqlRecordSet.cpp +++ b/lib/input/mysqlRecordSet.cpp @@ -1,5 +1,6 @@ #include "mysqlRecordSet.h" #include "mysqlBindings.h" +#include "mysqlConn.h" #include "mysqlStmt.h" #include #include @@ -61,18 +62,17 @@ namespace MyGrate::Input { case MYSQL_TYPE_SET: case MYSQL_TYPE_GEOMETRY:; } - throw std::runtime_error("Unsupported column type"); + throw std::logic_error("Unsupported column type"); }; ResPtr meta {mysql_stmt_result_metadata(stmt.get()), mysql_free_result}; - const auto fieldDefs = mysql_fetch_fields(meta.get()); - verify(fieldDefs, "Fetch fields"); + const auto fieldDefs = verify(mysql_fetch_fields(meta.get()), "Fetch fields", stmt->mysql); for (std::size_t i = 0; i < fields.size(); i += 1) { extras[i] = getBind(fieldDefs[i], fields[i]); } - verify(!mysql_stmt_bind_result(stmt.get(), fields.data()), "Store result error"); - verify(!mysql_stmt_store_result(stmt.get()), "Store result error"); + verify(!mysql_stmt_bind_result(stmt.get(), fields.data()), "Store result error", stmt->mysql); + verify(!mysql_stmt_store_result(stmt.get()), "Store result error", stmt->mysql); stmtres = {stmt.get(), mysql_stmt_free_result}; - verify(!mysql_stmt_fetch(stmt.get()), "Fetch"); + verify(!mysql_stmt_fetch(stmt.get()), "Fetch", stmt->mysql); } std::size_t diff --git a/lib/input/mysqlStmt.cpp b/lib/input/mysqlStmt.cpp index 08d1303..d3ba9ef 100644 --- a/lib/input/mysqlStmt.cpp +++ b/lib/input/mysqlStmt.cpp @@ -1,5 +1,6 @@ #include "mysqlStmt.h" #include "mysqlBindings.h" +#include "mysqlConn.h" #include "mysqlRecordSet.h" #include #include @@ -10,15 +11,15 @@ namespace MyGrate::Input { MySQLPrepStmt::MySQLPrepStmt(const char * const q, MYSQL * c) : stmt {mysql_stmt_init(c), &mysql_stmt_close} { - verify(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q); + verify(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q, c); } void MySQLPrepStmt::execute(const std::initializer_list & vs) { Bindings b {vs}; - verify(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); - verify(!mysql_stmt_execute(stmt.get()), "Prepared statement execute"); + verify(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); + verify(!mysql_stmt_execute(stmt.get()), "Prepared statement execute", stmt->mysql); } std::size_t diff --git a/lib/input/replStream.cpp b/lib/input/replStream.cpp index 1ec696a..90f26d6 100644 --- a/lib/input/replStream.cpp +++ b/lib/input/replStream.cpp @@ -30,7 +30,7 @@ namespace MyGrate::Input { mariadb_rpl_optionsv(rpl.get(), MARIADB_RPL_START, position); mariadb_rpl_optionsv(rpl.get(), MARIADB_RPL_FLAGS, MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS); - verify(!mariadb_rpl_open(rpl.get()), "Failed to mariadb_rpl_open"); + verify(!mariadb_rpl_open(rpl.get()), "Failed to mariadb_rpl_open", this); while (MyGrate::MariaDB_Event_Ptr event {mariadb_rpl_fetch(rpl.get(), nullptr), &mariadb_free_rpl_event}) { position = event->next_event_pos; diff --git a/lib/input/replStream.h b/lib/input/replStream.h index bc47267..dcfee19 100644 --- a/lib/input/replStream.h +++ b/lib/input/replStream.h @@ -11,7 +11,7 @@ namespace MyGrate { } namespace MyGrate::Input { - class ReplicationStream : public EventSourceBase, MySQLConn { + class ReplicationStream : public EventSourceBase, public MySQLConn { public: ReplicationStream(const std::string & host, const std::string & user, const std::string & pass, unsigned short port, uint64_t serverid, std::string filename, uint64_t position); -- cgit v1.2.3