diff options
Diffstat (limited to 'lib/input')
| -rw-r--r-- | lib/input/mysqlConn.cpp | 78 | ||||
| -rw-r--r-- | lib/input/mysqlConn.h | 8 | 
2 files changed, 84 insertions, 2 deletions
| diff --git a/lib/input/mysqlConn.cpp b/lib/input/mysqlConn.cpp index 3a2c9f4..179f9d5 100644 --- a/lib/input/mysqlConn.cpp +++ b/lib/input/mysqlConn.cpp @@ -1,9 +1,18 @@  #include "mysqlConn.h"  #include "helpers.h" +#include <cstddef> +#include <cstring> +#include <dbTypes.h> +#include <memory>  #include <mysql.h> +#include <mysql_types.h>  #include <stdexcept> +#include <variant> +#include <vector>  namespace MyGrate::Input { +	using StmtPtr = std::unique_ptr<MYSQL_STMT, decltype(&mysql_stmt_close)>; +  	MySQLConn::MySQLConn(  			const char * const host, const char * const user, const char * const pass, unsigned short port) :  		st_mysql {} @@ -26,4 +35,73 @@ namespace MyGrate::Input {  	{  		verify<std::runtime_error>(!mysql_query(this, q), q);  	} + +	struct Bindings { +		// NOLINTNEXTLINE(hicpp-explicit-conversions) +		explicit Bindings(const std::initializer_list<DbValue> & vs) +		{ +			binds.reserve(vs.size()); +			extras.reserve(vs.size()); +			for (const auto & v : vs) { +				std::visit(*this, v); +			} +		} +		template<std::integral T> +		void +		operator()(const T & v) +		{ +			auto & b = binds.emplace_back(); +			b.buffer_type = MySQL::CType<T>::type; +			b.buffer = const_cast<T *>(&v); +			b.is_unsigned = std::unsigned_integral<T>; +		} +		template<std::floating_point T> +		void +		operator()(const T & v) +		{ +			auto & b = binds.emplace_back(); +			b.buffer_type = MySQL::CType<T>::type; +			b.buffer = const_cast<T *>(&v); +		} +		template<Viewable T> +		void +		operator()(const T & v) +		{ +			auto & b = binds.emplace_back(); +			b.buffer_type = MySQL::CType<T>::type; +			b.buffer = const_cast<typename T::value_type *>(v.data()); +			b.length = &extras.emplace_back(v.size(), 0).len; +		} +		void +		operator()(const std::nullptr_t &) +		{ +			auto & b = binds.emplace_back(); +			b.buffer = nullptr; +			b.is_null = &extras.emplace_back(0, 1).null; +		} +		template<typename T> +		void +		operator()(const T &) +		{ +			throw std::runtime_error("Not implemented"); +		} +		struct extra { +			explicit extra(unsigned long l, my_bool n = 0) : len {l}, null {n} { } +			unsigned long len; +			my_bool null; +		}; +		std::vector<MYSQL_BIND> binds; +		std::vector<extra> extras; +	}; + +	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<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); +	}  } diff --git a/lib/input/mysqlConn.h b/lib/input/mysqlConn.h index 2f57f33..9e4ec25 100644 --- a/lib/input/mysqlConn.h +++ b/lib/input/mysqlConn.h @@ -1,15 +1,19 @@  #ifndef MYGRATE_INPUT_MYSQLCONN_H  #define MYGRATE_INPUT_MYSQLCONN_H +#include <dbConn.h> +#include <dbTypes.h> +#include <initializer_list>  #include <mysql.h>  namespace MyGrate::Input { -	class MySQLConn : public MYSQL { +	class MySQLConn : public MYSQL, public DbConn {  	public:  		MySQLConn(const char * const host, const char * const user, const char * const pass, unsigned short port);  		~MySQLConn(); -		void query(const char * const); +		void query(const char * const) override; +		void query(const char * const q, const std::initializer_list<DbValue> &) override;  	};  } | 
