#include "connection.h" #include "error.h" #include "selectcommand.h" #include "modifycommand.h" #include "reflection.h" class Opts { public: Opts() { port = 3306; } std::string server; std::string user; std::string password; std::string database; unsigned int port; std::string unix_socket; static Reflector::Vars vars; }; Reflector::Vars Opts::vars = { Map(Opts, server), Map(Opts, user), Map(Opts, password), Map(Opts, database), Map(Opts, unix_socket), Map(Opts, port), }; MySQL::Connection::Connection(const std::string & str) : txDepth(0), rolledback(false) { Opts o(Reflector::NameValueNew(str)); mysql_init(&conn); if (mysql_real_connect(&conn, o.server.c_str(), o.user.c_str(), o.password.c_str(), o.database.c_str(), o.port, o.unix_socket.c_str(), CLIENT_LOCAL_FILES | CLIENT_MULTI_STATEMENTS) == NULL) { throw ConnectionError(); } if (mysql_set_character_set(&conn, "utf8")) { throw ConnectionError(); } } MySQL::Connection::~Connection() { mysql_close(&conn); } void MySQL::Connection::finish() const { if (txDepth != 0) { rollbackTx(); throw Error("Transaction still open"); } } int MySQL::Connection::beginTx() const { if (txDepth == 0) { checkResult(mysql_autocommit(&conn, 0), true); rolledback = false; } return ++txDepth; } int MySQL::Connection::commitTx() const { if (rolledback) { return rollbackTx(); } if (--txDepth == 0) { checkResult(mysql_commit(&conn), true); } return txDepth; } int MySQL::Connection::rollbackTx() const { if (--txDepth == 0) { checkResult(mysql_rollback(&conn), true); } else { rolledback = true; } return txDepth; } bool MySQL::Connection::inTx() const { return txDepth; } DB::BulkDeleteStyle MySQL::Connection::bulkDeleteStyle() const { return DB::BulkDeleteUsingUsingAlias; } DB::BulkUpdateStyle MySQL::Connection::bulkUpdateStyle() const { return DB::BulkUpdateUsingJoin; } void MySQL::Connection::ping() const { checkResult(mysql_ping(&conn), true); } DB::SelectCommand * MySQL::Connection::newSelectCommand(const std::string & sql) const { return new SelectCommand(this, sql); } DB::ModifyCommand * MySQL::Connection::newModifyCommand(const std::string & sql) const { return new ModifyCommand(this, sql); } void MySQL::Connection::checkResult(my_bool actual, my_bool expected) const { if (actual != expected) { throw Error(mysql_error(&conn)); } } void MySQL::Connection::beginBulkUpload(const char * table, const char * extra) const { (void)table; (void)extra; } void MySQL::Connection::endBulkUpload(const char * msg) const { (void)msg; } size_t MySQL::Connection::bulkUploadData(const char * data, size_t len) const { (void)data; return len; }