diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-06-12 20:26:01 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2021-06-12 20:26:01 +0100 |
commit | 231bc3fc8d1902bb19b6fce39ffd72cce4b4f2c3 (patch) | |
tree | e074ea9bf53400600831215822a848fe27bfac55 | |
parent | Have verify return its expression, might be useful (diff) | |
download | mygrate-231bc3fc8d1902bb19b6fce39ffd72cce4b4f2c3.tar.bz2 mygrate-231bc3fc8d1902bb19b6fce39ffd72cce4b4f2c3.tar.xz mygrate-231bc3fc8d1902bb19b6fce39ffd72cce4b4f2c3.zip |
Avoid direct use of runtime_error in MySQL stuff
Adds proper exception which extends it and gets the MySQL error message.
-rw-r--r-- | lib/input/mysqlBindings.h | 2 | ||||
-rw-r--r-- | lib/input/mysqlConn.cpp | 14 | ||||
-rw-r--r-- | lib/input/mysqlConn.h | 5 | ||||
-rw-r--r-- | lib/input/mysqlRecordSet.cpp | 12 | ||||
-rw-r--r-- | lib/input/mysqlStmt.cpp | 7 | ||||
-rw-r--r-- | lib/input/replStream.cpp | 2 | ||||
-rw-r--r-- | lib/input/replStream.h | 2 | ||||
-rw-r--r-- | test/test-mysql.cpp | 6 |
8 files changed, 29 insertions, 21 deletions
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<MYSQL_BIND> binds; std::vector<BingingData> 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 <vector> 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<std::runtime_error>(!mysql_set_character_set(this, "utf8"), "Set character set"); + verify<MySQLErr>(!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<std::runtime_error>(!mysql_query(this, q), q); + verify<MySQLErr>(!mysql_query(this, q), q, this); } void MySQLConn::query(const char * const q, const std::initializer_list<DbValue> & vs) { StmtPtr stmt {mysql_stmt_init(this), &mysql_stmt_close}; - verify<std::runtime_error>(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q); + verify<MySQLErr>(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q, this); verify<std::logic_error>(mysql_stmt_param_count(stmt.get()) == vs.size(), "Param count mismatch"); Bindings b {vs}; - verify<std::runtime_error>(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); - verify<std::runtime_error>(!mysql_stmt_execute(stmt.get()), q); + verify<std::logic_error>(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); + verify<MySQLErr>(!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 <cstdint> #include <dbTypes.h> @@ -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<std::runtime_error>(fieldDefs, "Fetch fields"); + const auto fieldDefs = verify<MySQLErr>(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<std::runtime_error>(!mysql_stmt_bind_result(stmt.get(), fields.data()), "Store result error"); - verify<std::runtime_error>(!mysql_stmt_store_result(stmt.get()), "Store result error"); + verify<MySQLErr>(!mysql_stmt_bind_result(stmt.get(), fields.data()), "Store result error", stmt->mysql); + verify<MySQLErr>(!mysql_stmt_store_result(stmt.get()), "Store result error", stmt->mysql); stmtres = {stmt.get(), mysql_stmt_free_result}; - verify<std::runtime_error>(!mysql_stmt_fetch(stmt.get()), "Fetch"); + verify<MySQLErr>(!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 <cstring> #include <helpers.h> @@ -10,15 +11,15 @@ namespace MyGrate::Input { MySQLPrepStmt::MySQLPrepStmt(const char * const q, MYSQL * c) : stmt {mysql_stmt_init(c), &mysql_stmt_close} { - verify<std::runtime_error>(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q); + verify<MySQLErr>(!mysql_stmt_prepare(stmt.get(), q, strlen(q)), q, c); } void MySQLPrepStmt::execute(const std::initializer_list<DbValue> & vs) { Bindings b {vs}; - verify<std::runtime_error>(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); - verify<std::runtime_error>(!mysql_stmt_execute(stmt.get()), "Prepared statement execute"); + verify<std::logic_error>(!mysql_stmt_bind_param(stmt.get(), b.binds.data()), "Param count mismatch"); + verify<MySQLErr>(!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<std::runtime_error>(!mariadb_rpl_open(rpl.get()), "Failed to mariadb_rpl_open"); + verify<MySQLErr>(!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); diff --git a/test/test-mysql.cpp b/test/test-mysql.cpp index de9dd83..d91f54e 100644 --- a/test/test-mysql.cpp +++ b/test/test-mysql.cpp @@ -26,18 +26,18 @@ BOOST_AUTO_TEST_CASE(simple) BOOST_CHECK_THROW(([]() { MyGrate::Input::MySQLConn {SERVER, USER, "badpass", PORT}; }()), - std::runtime_error); + MyGrate::Input::MySQLErr); MyGrate::Input::MySQLConn c {SERVER, USER, PASSWORD, PORT}; BOOST_CHECK_NO_THROW(c.query("SET @var = ''")); BOOST_CHECK_NO_THROW(c.query("SET @var = 'something'")); - BOOST_CHECK_THROW(c.query("SET @var = "), std::runtime_error); + BOOST_CHECK_THROW(c.query("SET @var = "), MyGrate::Input::MySQLErr); BOOST_CHECK_THROW(c.query("SET @var = ?", {}), std::logic_error); BOOST_CHECK_NO_THROW(c.query("SET @var = ''", {})); BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {1})); BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {"string_view"})); BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {nullptr})); BOOST_CHECK_NO_THROW(c.query("SET @var = ?", {1.2})); - BOOST_CHECK_THROW(c.query("SET @var = ?", {MyGrate::Time {}}), std::runtime_error); + BOOST_CHECK_THROW(c.query("SET @var = ?", {MyGrate::Time {}}), std::logic_error); } using SomeSelect = MyGrate::DbStmt<"SELECT * FROM foo">; |