197 lines
5.0 KiB
C++
197 lines
5.0 KiB
C++
#include "MySQLClientImpl.h"
|
|
#include "MySQLResultSetImpl.h"
|
|
#include <Logging.h>
|
|
#include <sstream>
|
|
|
|
|
|
namespace MySQL {
|
|
|
|
MySQLClientImpl::MySQLClientImpl() :
|
|
m_connected(false),
|
|
m_automaticReconnect(false),
|
|
m_pDriver(sql::mysql::get_mysql_driver_instance())
|
|
{
|
|
}
|
|
|
|
MySQLClientImpl::~MySQLClientImpl()
|
|
{
|
|
}
|
|
|
|
void MySQLClientImpl::Connect(const std::string& hostname, const std::string& username, const std::string& password, bool automaticReconnect)
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
m_hostname = hostname;
|
|
m_username = username;
|
|
m_password = password;
|
|
m_database = "";
|
|
m_automaticReconnect = automaticReconnect;
|
|
InternalConnect();
|
|
}
|
|
|
|
void MySQLClientImpl::Connect(const std::string& hostname, const std::string& username, const std::string& password, const std::string& database, bool automaticReconnect)
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
m_hostname = hostname;
|
|
m_username = username;
|
|
m_password = password;
|
|
m_database = database;
|
|
m_automaticReconnect = automaticReconnect;
|
|
InternalConnect();
|
|
}
|
|
|
|
void MySQLClientImpl::Disconnect()
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
InternalDisconnect();
|
|
}
|
|
|
|
void MySQLClientImpl::Reconnect(bool automaticReconnect)
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
InternalDisconnect();
|
|
m_automaticReconnect = automaticReconnect;
|
|
InternalConnect();
|
|
}
|
|
|
|
bool MySQLClientImpl::Connected() const
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
return m_connected;
|
|
}
|
|
|
|
std::string MySQLClientImpl::Database() const
|
|
{
|
|
if (!m_connected)
|
|
return std::string();
|
|
return m_database;
|
|
}
|
|
|
|
void MySQLClientImpl::Execute(const std::string& query)
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
if (!m_connected)
|
|
{
|
|
if (m_automaticReconnect)
|
|
InternalConnect();
|
|
else
|
|
throw std::runtime_error("MySQLClientImpl::ExecuteQuery() - Not connected to a Database Server");
|
|
}
|
|
|
|
try
|
|
{
|
|
std::unique_ptr<sql::Statement> statement(m_pConnection->createStatement());
|
|
statement->execute(query);
|
|
}
|
|
catch (sql::SQLException &e)
|
|
{
|
|
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();
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
std::stringstream ss;
|
|
ss << "MySQLClientImpl::Execute() - Error: " << e.what() << std::endl;
|
|
ss << "Query: " << query << std::endl;
|
|
Logging::Log(Logging::Severity::Error, ss.str());
|
|
InternalDisconnect();
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<MySQLResultSetImpl> MySQLClientImpl::ExecuteQuery(const std::string& query)
|
|
{
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
if (!m_connected)
|
|
{
|
|
if (m_automaticReconnect)
|
|
InternalConnect();
|
|
else
|
|
throw std::runtime_error("MySQLClientImpl::ExecuteQuery() - Not connected to a Database Server");
|
|
}
|
|
|
|
try
|
|
{
|
|
std::unique_ptr<sql::Statement> statement(m_pConnection->createStatement());
|
|
std::shared_ptr<sql::ResultSet> pResult(statement->executeQuery(query));
|
|
return std::make_shared<MySQLResultSetImpl>(pResult);
|
|
}
|
|
catch (sql::SQLException &e)
|
|
{
|
|
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();
|
|
}
|
|
catch (const std::exception& e)
|
|
{
|
|
std::stringstream ss;
|
|
ss << "MySQLClientImpl::ExecuteQuery() - Error: " << e.what() << std::endl;
|
|
ss << "Query: " << query << std::endl;
|
|
Logging::Log(Logging::Severity::Error, ss.str());
|
|
InternalDisconnect();
|
|
}
|
|
|
|
return std::make_shared<MySQLResultSetImpl>(nullptr);
|
|
}
|
|
|
|
void MySQLClientImpl::InternalConnect()
|
|
{
|
|
try
|
|
{
|
|
if (m_pConnection)
|
|
InternalDisconnect();
|
|
|
|
std::string database;
|
|
if (!m_database.empty())
|
|
database = m_database;
|
|
else
|
|
database = "information_schema";
|
|
|
|
sql::ConnectOptionsMap options;
|
|
options["hostName"] = m_hostname;
|
|
options["userName"] = m_username;
|
|
options["password"] = m_password;
|
|
options["schema"] = database;
|
|
options["port"] = 3306;
|
|
options["OPT_RECONNECT"] = m_automaticReconnect;
|
|
|
|
m_pConnection = std::shared_ptr<sql::Connection>(m_pDriver->connect(options));
|
|
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();
|
|
}
|
|
catch (const std::exception& 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_connected = false;
|
|
}
|
|
|
|
} // namespace MySQL
|