From 3bc5964793f1700551b7db8107a939c98f1d1be1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 13 Jun 2021 21:29:25 +0100 Subject: Add transaction support --- lib/dbConn.cpp | 18 ++++++++++++++++++ lib/dbConn.h | 22 ++++++++++++++++++++++ lib/input/mysqlConn.cpp | 20 ++++++++++++++++++++ lib/input/mysqlConn.h | 4 ++++ lib/output/pq/pqConn.cpp | 18 ++++++++++++++++++ lib/output/pq/pqConn.h | 4 ++++ 6 files changed, 86 insertions(+) create mode 100644 lib/dbConn.cpp diff --git a/lib/dbConn.cpp b/lib/dbConn.cpp new file mode 100644 index 0000000..380910a --- /dev/null +++ b/lib/dbConn.cpp @@ -0,0 +1,18 @@ +#include "dbConn.h" + +namespace MyGrate { + Tx::Tx(DbConn * c) : conn {c} + { + conn->beginTx(); + } + + Tx::~Tx() + { + if (std::uncaught_exceptions()) { + conn->rollbackTx(); + } + else { + conn->commitTx(); + } + } +} diff --git a/lib/dbConn.h b/lib/dbConn.h index 3f14dcb..ffdd2e0 100644 --- a/lib/dbConn.h +++ b/lib/dbConn.h @@ -24,6 +24,28 @@ namespace MyGrate { virtual void query(const char * const, const std::initializer_list &) = 0; virtual DbPrepStmtPtr prepare(const char * const, std::size_t nParams) = 0; + + virtual void beginTx() = 0; + virtual void commitTx() = 0; + virtual void rollbackTx() = 0; + }; + + class Tx { + public: + explicit Tx(DbConn *); + Tx(const Tx &) = delete; + Tx(Tx &&) = delete; + ~Tx(); + + template + auto + operator()(C && callback) + { + return callback(); + } + + private: + DbConn * conn; }; } diff --git a/lib/input/mysqlConn.cpp b/lib/input/mysqlConn.cpp index 362f9ea..99c2891 100644 --- a/lib/input/mysqlConn.cpp +++ b/lib/input/mysqlConn.cpp @@ -52,4 +52,24 @@ namespace MyGrate::Input { { return std::make_unique(q, this); } + + void + MySQLConn::beginTx() + { + verify(!mysql_autocommit(this, false), "Auto commit off", this); + } + + void + MySQLConn::commitTx() + { + verify(!mysql_commit(this), "Commit", this); + verify(!mysql_autocommit(this, true), "Auto commit on", this); + } + + void + MySQLConn::rollbackTx() + { + verify(!mysql_rollback(this), "Rollback", this); + verify(!mysql_autocommit(this, true), "Auto commit on", this); + } } diff --git a/lib/input/mysqlConn.h b/lib/input/mysqlConn.h index dfb408f..bd53616 100644 --- a/lib/input/mysqlConn.h +++ b/lib/input/mysqlConn.h @@ -29,6 +29,10 @@ namespace MyGrate::Input { void query(const char * const q, const std::initializer_list &) override; DbPrepStmtPtr prepare(const char * const, std::size_t) override; + + void beginTx() override; + void commitTx() override; + void rollbackTx() override; }; } diff --git a/lib/output/pq/pqConn.cpp b/lib/output/pq/pqConn.cpp index 309b704..ba95cad 100644 --- a/lib/output/pq/pqConn.cpp +++ b/lib/output/pq/pqConn.cpp @@ -43,6 +43,24 @@ namespace MyGrate::Output::Pq { return std::make_unique(q, n, this); } + void + PqConn::beginTx() + { + query("BEGIN"); + } + + void + PqConn::commitTx() + { + query("COMMIT"); + } + + void + PqConn::rollbackTx() + { + query("ROLLBACK"); + } + void PqConn::notice_processor(void * p, const char * n) { diff --git a/lib/output/pq/pqConn.h b/lib/output/pq/pqConn.h index 6db9bcf..3b27f97 100644 --- a/lib/output/pq/pqConn.h +++ b/lib/output/pq/pqConn.h @@ -32,6 +32,10 @@ namespace MyGrate::Output::Pq { DbPrepStmtPtr prepare(const char * const, std::size_t nParams) override; + void beginTx() override; + void commitTx() override; + void rollbackTx() override; + const std::string connstr; private: -- cgit v1.2.3