From 2365589910fd78ebf42345b0d091a3c0c92c7af5 Mon Sep 17 00:00:00 2001 From: JDierkse Date: Wed, 8 Apr 2020 11:13:08 +0200 Subject: [PATCH] Improve Connection / Disconnect behavior --- MySQL/MySQLClient.cpp | 10 ++++ MySQL/MySQLClientImpl.cpp | 111 ++++++++++++++++++++++++-------------- MySQL/MySQLClientImpl.h | 16 +++++- include/MySQLClient.h | 3 ++ 4 files changed, 97 insertions(+), 43 deletions(-) diff --git a/MySQL/MySQLClient.cpp b/MySQL/MySQLClient.cpp index a3678b5..31bf681 100644 --- a/MySQL/MySQLClient.cpp +++ b/MySQL/MySQLClient.cpp @@ -28,6 +28,16 @@ void MySQLClient::Disconnect() m_pMySQLClientImpl->Disconnect(); } +void MySQLClient::Reconnect() +{ + m_pMySQLClientImpl->Reconnect(); +} + +bool MySQLClient::Connected() +{ + return m_pMySQLClientImpl->Connected(); +} + std::string MySQLClient::Database() const { return m_pMySQLClientImpl->Database(); diff --git a/MySQL/MySQLClientImpl.cpp b/MySQL/MySQLClientImpl.cpp index a325540..2e516fb 100644 --- a/MySQL/MySQLClientImpl.cpp +++ b/MySQL/MySQLClientImpl.cpp @@ -19,55 +19,40 @@ MySQLClientImpl::~MySQLClientImpl() void MySQLClientImpl::Connect(const std::string& hostname, const std::string& username, const std::string& password) { std::unique_lock lock(m_mutex); - try - { - if (m_pConnection) - Disconnect(); - - std::stringstream ss; - ss << "tcp://" << hostname << ":3306"; - - m_pConnection = std::shared_ptr(m_pDriver->connect(ss.str(), username, password)); - m_database = ""; - m_connected = true; - } - catch (sql::SQLException &e) - { - std::stringstream ss; - ss << "MySQLClientImpl::Connect() - Error: " << e.what() << std::endl; - Logging::Log(Logging::Severity::Error, ss.str()); - } + m_hostname = hostname; + m_username = username; + m_password = password; + m_database = ""; + InternalConnect(); } void MySQLClientImpl::Connect(const std::string& hostname, const std::string& username, const std::string& password, const std::string& database) { std::unique_lock lock(m_mutex); - try - { - if (m_pConnection) - Disconnect(); - - std::stringstream ss; - ss << "tcp://" << hostname << ":3306/" << database; - - m_pConnection = std::shared_ptr(m_pDriver->connect(ss.str(), username, password)); - m_database = database; - m_connected = true; - } - catch (sql::SQLException &e) - { - std::stringstream ss; - ss << "MySQLClientImpl::Connect() - Error: " << e.what() << std::endl; - Logging::Log(Logging::Severity::Error, ss.str()); - } + m_hostname = hostname; + m_username = username; + m_password = password; + m_database = database; + InternalConnect(); } void MySQLClientImpl::Disconnect() { std::unique_lock lock(m_mutex); - m_pConnection.reset(); - m_database = ""; - m_connected = false; + InternalDisconnect(); +} + +void MySQLClientImpl::Reconnect() +{ + std::unique_lock lock(m_mutex); + InternalDisconnect(); + InternalConnect(); +} + +bool MySQLClientImpl::Connected() const +{ + std::unique_lock lock(m_mutex); + return m_connected; } std::string MySQLClientImpl::Database() const @@ -77,7 +62,7 @@ std::string MySQLClientImpl::Database() const return m_database; } -void MySQLClientImpl::Execute(const std::string& query) const +void MySQLClientImpl::Execute(const std::string& query) { std::unique_lock lock(m_mutex); if (!m_connected) @@ -93,11 +78,17 @@ void MySQLClientImpl::Execute(const std::string& query) const std::stringstream ss; ss << "MySQLClientImpl::Execute() - Error: " << e.what() << std::endl; ss << "Query: " << query << std::endl; + ss << "(MySQL error code: " << e.getErrorCode(); + ss << ", SQLState: " << e.getSQLState() << " )" << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); + + int errorCode = e.getErrorCode(); + if (errorCode == 2006 || errorCode == 2013) + InternalDisconnect(); } } -std::shared_ptr MySQLClientImpl::ExecuteQuery(const std::string& query) const +std::shared_ptr MySQLClientImpl::ExecuteQuery(const std::string& query) { std::unique_lock lock(m_mutex); if (!m_connected) @@ -114,10 +105,48 @@ std::shared_ptr MySQLClientImpl::ExecuteQuery(const std::str std::stringstream ss; ss << "MySQLClientImpl::ExecuteQuery() - Error: " << e.what() << std::endl; ss << "Query: " << query << std::endl; + ss << "(MySQL error code: " << e.getErrorCode(); + ss << ", SQLState: " << e.getSQLState() << " )" << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); + + int errorCode = e.getErrorCode(); + if (errorCode == 2006 || errorCode == 2013) + InternalDisconnect(); } return std::make_shared(nullptr); } +void MySQLClientImpl::InternalConnect() +{ + try + { + if (m_pConnection) + Disconnect(); + + std::stringstream ss; + ss << "tcp://" << m_hostname << ":3306"; + + if (!m_database.empty()) + ss << "/" << m_database; + + m_pConnection = std::shared_ptr(m_pDriver->connect(ss.str(), m_username, m_password)); + m_connected = true; + } + catch (sql::SQLException &e) + { + std::stringstream ss; + ss << "MySQLClientImpl::Connect() - Error: " << e.what() << std::endl; + Logging::Log(Logging::Severity::Error, ss.str()); + InternalDisconnect(); + } +} + +void MySQLClientImpl::InternalDisconnect() +{ + m_pConnection.reset(); + m_database = ""; + m_connected = false; +} + } // namespace MySQL diff --git a/MySQL/MySQLClientImpl.h b/MySQL/MySQLClientImpl.h index a6909b2..434f032 100644 --- a/MySQL/MySQLClientImpl.h +++ b/MySQL/MySQLClientImpl.h @@ -22,17 +22,29 @@ public: void Connect(const std::string& hostname, const std::string& username, const std::string& password); void Connect(const std::string& hostname, const std::string& username, const std::string& password, const std::string& database); + void Disconnect(); + void Reconnect(); + bool Connected() const; std::string Database() const; - void Execute(const std::string& query) const; - std::shared_ptr ExecuteQuery(const std::string& query) const; + void Execute(const std::string& query); + std::shared_ptr ExecuteQuery(const std::string& query); + +private: + void InternalConnect(); + void InternalDisconnect(); private: mutable std::mutex m_mutex; + bool m_connected; + std::string m_hostname; + std::string m_username; + std::string m_password; std::string m_database; + sql::mysql::MySQL_Driver* m_pDriver; std::shared_ptr m_pConnection; }; diff --git a/include/MySQLClient.h b/include/MySQLClient.h index 262286f..0e43292 100644 --- a/include/MySQLClient.h +++ b/include/MySQLClient.h @@ -18,7 +18,10 @@ public: void Connect(const std::string& hostname, const std::string& username, const std::string& password); void Connect(const std::string& hostname, const std::string& username, const std::string& password, const std::string& database); + void Disconnect(); + void Reconnect(); + bool Connected(); std::string Database() const;