Explorar el Código

Initial commit

JDierkse hace 5 años
commit
ac07fbf306

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+*.o.*
+*.d.*
+*.a.*
+.*.swp
+.AppleDouble
+lib
+Libraries

+ 3 - 0
.gitmodules

@@ -0,0 +1,3 @@
+[submodule "Makefiles"]
+	path = Makefiles
+	url = https://gogs.dierkse.nl/JDierkse/Makefiles.git

+ 1 - 0
Makefile

@@ -0,0 +1 @@
+Makefiles/Makefile

+ 6 - 0
Makefile.conf

@@ -0,0 +1,6 @@
+#
+# Makefile.conf
+#
+
+CFLAGS += -I$(ROOTPATH) -I$(ROOTPATH)/include -I$(ROOTPATH)/Libraries/Logging/include
+DEBUGDIR := .debug

+ 12 - 0
Makefile.target

@@ -0,0 +1,12 @@
+#
+# Makefile.target
+#
+
+MySQL.a.$(ARCH) : $(OBJECTS)
+	$(call build_target_library_arch,$@,$^)
+MySQL.a:
+	$(call build_target,$@)
+
+.DEFAULT_GOAL := MySQL.a
+
+TARGETS += MySQL.a

+ 1 - 0
Makefiles

@@ -0,0 +1 @@
+Subproject commit 61894c4588eb2b85e342a6f923eeb7ac97c3fe64

+ 1 - 0
MySQL/Makefile

@@ -0,0 +1 @@
+../Makefile

+ 46 - 0
MySQL/MySQLClient.cpp

@@ -0,0 +1,46 @@
+#include "MySQLClient.h"
+#include "MySQLClientImpl.h"
+
+
+namespace MySQL {
+
+MySQLClient::MySQLClient() :
+	m_pMySQLClientImpl(new MySQLClientImpl())
+{
+}
+
+MySQLClient::~MySQLClient()
+{
+}
+
+void MySQLClient::Connect(const std::string& hostname, const std::string& username, const std::string& password)
+{
+	m_pMySQLClientImpl->Connect(hostname, username, password);
+}
+
+void MySQLClient::Connect(const std::string& hostname, const std::string& username, const std::string& password, const std::string& database)
+{
+	m_pMySQLClientImpl->Connect(hostname, username, password, database);
+}
+
+void MySQLClient::Disconnect()
+{
+	m_pMySQLClientImpl->Disconnect();
+}
+
+std::string MySQLClient::Database() const
+{
+	return m_pMySQLClientImpl->Database();
+}
+
+void MySQLClient::Execute(const std::string& query) const
+{
+	m_pMySQLClientImpl->Execute(query);
+}
+
+MySQLResultSet MySQLClient::ExecuteQuery(const std::string& query) const
+{
+	return MySQLResultSet(m_pMySQLClientImpl->ExecuteQuery(query));
+}
+
+} // namespace MySQL

+ 123 - 0
MySQL/MySQLClientImpl.cpp

@@ -0,0 +1,123 @@
+#include "MySQLClientImpl.h"
+#include "MySQLResultSetImpl.h"
+#include "Logging.h"
+#include <sstream>
+
+
+namespace MySQL {
+
+MySQLClientImpl::MySQLClientImpl() :
+	m_connected(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)
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	try
+	{
+		if (m_pConnection)
+			Disconnect();
+
+		std::stringstream ss;
+		ss << "tcp://" << hostname << ":3306";
+
+		m_pConnection = std::shared_ptr<sql::Connection>(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());
+	}
+}
+
+void MySQLClientImpl::Connect(const std::string& hostname, const std::string& username, const std::string& password, const std::string& database)
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	try
+	{
+		if (m_pConnection)
+			Disconnect();
+
+		std::stringstream ss;
+		ss << "tcp://" << hostname << ":3306/" << database;
+
+		m_pConnection = std::shared_ptr<sql::Connection>(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());
+	}
+}
+
+void MySQLClientImpl::Disconnect()
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	m_pConnection.reset();
+	m_database = "";
+	m_connected = false;
+}
+
+std::string MySQLClientImpl::Database() const
+{
+	if (!m_connected)
+		return std::string();
+	return m_database;
+}
+
+void MySQLClientImpl::Execute(const std::string& query) const
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	if (!m_connected)
+		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;
+		Logging::Log(Logging::Severity::Error, ss.str());
+	}
+}
+
+std::shared_ptr<MySQLResultSetImpl> MySQLClientImpl::ExecuteQuery(const std::string& query) const
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	if (!m_connected)
+		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;
+		Logging::Log(Logging::Severity::Error, ss.str());
+	}
+
+	return std::make_shared<MySQLResultSetImpl>(nullptr);
+}
+
+} // namespace MySQL

+ 42 - 0
MySQL/MySQLClientImpl.h

@@ -0,0 +1,42 @@
+#ifndef MYSQL_MYSQLCLIENTIMPL_H
+#define MYSQL_MYSQLCLIENTIMPL_H
+
+#include "MySQLResultSetImpl.h"
+#include <mysql_connection.h>
+#include <mysql_driver.h>
+#include <cppconn/driver.h>
+#include <cppconn/exception.h>
+#include <cppconn/statement.h>
+#include <cppconn/prepared_statement.h>
+#include <mutex>
+#include <string>
+
+
+namespace MySQL {
+
+class MySQLClientImpl
+{
+public:
+	MySQLClientImpl();
+	~MySQLClientImpl();
+
+	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();
+
+	std::string Database() const;
+
+	void Execute(const std::string& query) const;
+	std::shared_ptr<MySQLResultSetImpl> ExecuteQuery(const std::string& query) const;
+
+private:
+	mutable std::mutex m_mutex;
+	bool m_connected;
+	std::string m_database;
+	sql::mysql::MySQL_Driver* m_pDriver;
+	std::shared_ptr<sql::Connection> m_pConnection;
+};
+
+} // namespace MySQL
+
+#endif // MYSQL_MYSQLCLIENTIMPL_H

+ 306 - 0
MySQL/MySQLResultSet.cpp

@@ -0,0 +1,306 @@
+#include "MySQLResultSet.h"
+#include "MySQLResultSetImpl.h"
+
+
+namespace MySQL {
+
+MySQLResultSet::MySQLResultSet() :
+	m_pMySQLResultSetImpl(new MySQLResultSetImpl())
+{
+}
+
+MySQLResultSet::MySQLResultSet(std::shared_ptr<MySQLResultSetImpl> pMySQLResultSetImpl) :
+	m_pMySQLResultSetImpl(pMySQLResultSetImpl)
+{
+}
+
+MySQLResultSet::~MySQLResultSet()
+{
+}
+
+bool MySQLResultSet::Absolute(int row)
+{
+	return m_pMySQLResultSetImpl->Absolute(row);
+}
+
+void MySQLResultSet::AfterLast()
+{
+	m_pMySQLResultSetImpl->AfterLast();
+}
+
+void MySQLResultSet::BeforeFirst()
+{
+	m_pMySQLResultSetImpl->BeforeFirst();
+}
+
+void MySQLResultSet::CancelRowUpdates()
+{
+	m_pMySQLResultSetImpl->CancelRowUpdates();
+}
+
+void MySQLResultSet::ClearWarnings()
+{
+	m_pMySQLResultSetImpl->ClearWarnings();
+}
+
+void MySQLResultSet::Close()
+{
+	m_pMySQLResultSetImpl->Close();
+}
+
+uint32_t MySQLResultSet::FindColumn(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->FindColumn(columnLabel);
+}
+
+bool MySQLResultSet::First()
+{
+	return m_pMySQLResultSetImpl->First();
+}
+
+std::istream* MySQLResultSet::Blob(uint32_t columnIndex)  const
+{
+	return m_pMySQLResultSetImpl->Blob(columnIndex);
+}
+
+std::istream* MySQLResultSet::Blob(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->Blob(columnLabel);
+}
+
+bool MySQLResultSet::Boolean(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->Boolean(columnIndex);
+}
+
+bool MySQLResultSet::Boolean(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->Boolean(columnLabel);
+}
+
+int MySQLResultSet::Concurrency()
+{
+	return m_pMySQLResultSetImpl->Concurrency();
+}
+
+std::string MySQLResultSet::CursorName()
+{
+	return m_pMySQLResultSetImpl->CursorName();
+}
+
+long double MySQLResultSet::Double(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->Double(columnIndex);
+}
+
+long double MySQLResultSet::Double(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->Double(columnLabel);
+}
+
+int MySQLResultSet::FetchDirection()
+{
+	return m_pMySQLResultSetImpl->FetchDirection();
+}
+
+size_t MySQLResultSet::FetchSize()
+{
+	return m_pMySQLResultSetImpl->FetchSize();
+}
+
+int MySQLResultSet::Holdability()
+{
+	return m_pMySQLResultSetImpl->Holdability();
+}
+
+int32_t MySQLResultSet::Int(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->Int(columnIndex);
+}
+
+int32_t MySQLResultSet::Int(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->Int(columnLabel);
+}
+
+uint32_t MySQLResultSet::UInt(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->UInt(columnIndex);
+}
+
+uint32_t MySQLResultSet::UInt(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->UInt(columnLabel);
+}
+
+int64_t MySQLResultSet::Int64(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->Int64(columnIndex);
+}
+
+int64_t MySQLResultSet::Int64(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->Int64(columnLabel);
+}
+
+uint64_t MySQLResultSet::UInt64(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->UInt64(columnIndex);
+}
+
+uint64_t MySQLResultSet::UInt64(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->UInt64(columnLabel);
+}
+
+MySQLResultSetMetaData MySQLResultSet::MetaData() const
+{
+	return MySQLResultSetMetaData(m_pMySQLResultSetImpl->MetaData());
+}
+
+size_t MySQLResultSet::Row() const
+{
+	return m_pMySQLResultSetImpl->Row();
+}
+/*
+RowID* MySQLResultSet::RowId(uint32_t columnIndex)
+{
+	return m_pMySQLResultSetImpl->RowId(columnIndex);
+}
+
+RowID* MySQLResultSet::RowId(const std::string & columnLabel)
+{
+	return m_pMySQLResultSetImpl->RowId(columnLabel);
+}
+
+const Statement* MySQLResultSet::Statement() const
+{
+	return m_pMySQLResultSetImpl->Statement();
+}
+*/
+std::string MySQLResultSet::String(uint32_t columnIndex)  const
+{
+	return m_pMySQLResultSetImpl->String(columnIndex);
+}
+
+std::string MySQLResultSet::String(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->String(columnLabel);
+}
+/*
+enum_type MySQLResultSet::Type() const
+{
+	return m_pMySQLResultSetImpl->Type();
+}
+*/
+void MySQLResultSet::Warnings()
+{
+	m_pMySQLResultSetImpl->Warnings();
+}
+
+void MySQLResultSet::InsertRow()
+{
+	m_pMySQLResultSetImpl->InsertRow();
+}
+
+bool MySQLResultSet::IsAfterLast() const
+{
+	return m_pMySQLResultSetImpl->IsAfterLast();
+}
+
+bool MySQLResultSet::IsBeforeFirst() const
+{
+	return m_pMySQLResultSetImpl->IsBeforeFirst();
+}
+
+bool MySQLResultSet::IsClosed() const
+{
+	return m_pMySQLResultSetImpl->IsClosed();
+}
+
+bool MySQLResultSet::IsFirst() const
+{
+	return m_pMySQLResultSetImpl->IsFirst();
+}
+
+bool MySQLResultSet::IsLast() const
+{
+	return m_pMySQLResultSetImpl->IsLast();
+}
+
+bool MySQLResultSet::IsNull(uint32_t columnIndex) const
+{
+	return m_pMySQLResultSetImpl->IsNull(columnIndex);
+}
+
+bool MySQLResultSet::IsNull(const std::string& columnLabel) const
+{
+	return m_pMySQLResultSetImpl->IsNull(columnLabel);
+}
+
+bool MySQLResultSet::Last()
+{
+	return m_pMySQLResultSetImpl->Last();
+}
+
+bool MySQLResultSet::Next()
+{
+	return m_pMySQLResultSetImpl->Next();
+}
+
+void MySQLResultSet::MoveToCurrentRow()
+{
+	m_pMySQLResultSetImpl->MoveToCurrentRow();
+}
+
+void MySQLResultSet::MoveToInsertRow()
+{
+	m_pMySQLResultSetImpl->MoveToInsertRow();
+}
+
+bool MySQLResultSet::Previous()
+{
+	return m_pMySQLResultSetImpl->Previous();
+}
+
+void MySQLResultSet::RefreshRow()
+{
+	m_pMySQLResultSetImpl->RefreshRow();
+}
+
+bool MySQLResultSet::Relative(int rows)
+{
+	return m_pMySQLResultSetImpl->Relative(rows);
+}
+
+bool MySQLResultSet::RowDeleted()
+{
+	return m_pMySQLResultSetImpl->RowDeleted();
+}
+
+bool MySQLResultSet::RowInserted()
+{
+	return m_pMySQLResultSetImpl->RowInserted();
+}
+
+bool MySQLResultSet::RowUpdated()
+{
+	return m_pMySQLResultSetImpl->RowUpdated();
+}
+
+void MySQLResultSet::FetchSize(size_t rows)
+{
+	return m_pMySQLResultSetImpl->FetchSize(rows);
+}
+
+size_t MySQLResultSet::RowsCount() const
+{
+	return m_pMySQLResultSetImpl->RowsCount();
+}
+
+bool MySQLResultSet::WasNull() const
+{
+	return m_pMySQLResultSetImpl->WasNull();
+}
+
+} // namespace MySQL

+ 478 - 0
MySQL/MySQLResultSetImpl.cpp

@@ -0,0 +1,478 @@
+#include "MySQLResultSetImpl.h"
+#include "MySQLResultSetMetaDataImpl.h"
+#include <stdexcept>
+#include <sstream>
+
+
+namespace MySQL {
+
+MySQLResultSetImpl::MySQLResultSetImpl()
+{
+}
+
+MySQLResultSetImpl::MySQLResultSetImpl(const std::shared_ptr<sql::ResultSet>& pResultSet) :
+	m_pResultSet(pResultSet)
+{
+}
+
+MySQLResultSetImpl::~MySQLResultSetImpl()
+{
+}
+
+bool MySQLResultSetImpl::Absolute(int row)
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->absolute(row);
+}
+
+void MySQLResultSetImpl::AfterLast()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->afterLast();
+}
+
+void MySQLResultSetImpl::BeforeFirst()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->beforeFirst();
+}
+
+void MySQLResultSetImpl::CancelRowUpdates()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->cancelRowUpdates();
+}
+
+void MySQLResultSetImpl::ClearWarnings()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->clearWarnings();
+}
+
+void MySQLResultSetImpl::Close()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->close();
+}
+
+uint32_t MySQLResultSetImpl::FindColumn(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->findColumn(columnLabel);
+}
+
+bool MySQLResultSetImpl::First()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->first();
+}
+
+std::istream* MySQLResultSetImpl::Blob(uint32_t columnIndex)  const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getBlob(columnIndex);
+}
+
+std::istream* MySQLResultSetImpl::Blob(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getBlob(columnLabel);
+}
+
+bool MySQLResultSetImpl::Boolean(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getBoolean(columnIndex);
+}
+
+bool MySQLResultSetImpl::Boolean(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getBoolean(columnLabel);
+}
+
+int MySQLResultSetImpl::Concurrency()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getConcurrency();
+}
+
+std::string MySQLResultSetImpl::CursorName()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getCursorName();
+}
+
+long double MySQLResultSetImpl::Double(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getDouble(columnIndex);
+}
+
+long double MySQLResultSetImpl::Double(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getDouble(columnLabel);
+}
+
+int MySQLResultSetImpl::FetchDirection()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getFetchDirection();
+}
+
+size_t MySQLResultSetImpl::FetchSize()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getFetchSize();
+}
+
+int MySQLResultSetImpl::Holdability()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getHoldability();
+}
+
+int32_t MySQLResultSetImpl::Int(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getInt(columnIndex);
+}
+
+int32_t MySQLResultSetImpl::Int(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getInt(columnLabel);
+}
+
+uint32_t MySQLResultSetImpl::UInt(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getUInt(columnIndex);
+}
+
+uint32_t MySQLResultSetImpl::UInt(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getUInt(columnLabel);
+}
+
+int64_t MySQLResultSetImpl::Int64(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getInt64(columnIndex);
+}
+
+int64_t MySQLResultSetImpl::Int64(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getInt64(columnLabel);
+}
+
+uint64_t MySQLResultSetImpl::UInt64(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getUInt64(columnIndex);
+}
+
+uint64_t MySQLResultSetImpl::UInt64(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getUInt64(columnLabel);
+}
+
+std::shared_ptr<MySQLResultSetMetaDataImpl> MySQLResultSetImpl::MetaData() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return std::make_shared<MySQLResultSetMetaDataImpl>(m_pResultSet->getMetaData());
+}
+
+size_t MySQLResultSetImpl::Row() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getRow();
+}
+/*
+RowID* MySQLResultSetImpl::RowId(uint32_t columnIndex)
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getRowId(columnIndex);
+}
+
+RowID* MySQLResultSetImpl::RowId(const std::string & columnLabel)
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getRowId(columnLabel);
+}
+
+const Statement* Statement() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getStatement();
+}
+*/
+std::string MySQLResultSetImpl::String(uint32_t columnIndex)  const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getString(columnIndex);
+}
+
+std::string MySQLResultSetImpl::String(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getString(columnLabel);
+}
+/*
+enum_type MySQLResultSetImpl::Type() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->getType();
+}
+*/
+void MySQLResultSetImpl::Warnings()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->getWarnings();
+}
+
+void MySQLResultSetImpl::InsertRow()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->insertRow();
+}
+
+bool MySQLResultSetImpl::IsAfterLast() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isAfterLast();
+}
+
+bool MySQLResultSetImpl::IsBeforeFirst() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isBeforeFirst();
+}
+
+bool MySQLResultSetImpl::IsClosed() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isClosed();
+}
+
+bool MySQLResultSetImpl::IsFirst() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isFirst();
+}
+
+bool MySQLResultSetImpl::IsLast() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isLast();
+}
+
+bool MySQLResultSetImpl::IsNull(uint32_t columnIndex) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isNull(columnIndex);
+}
+
+bool MySQLResultSetImpl::IsNull(const std::string& columnLabel) const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->isNull(columnLabel);
+}
+
+bool MySQLResultSetImpl::Last()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->last();
+}
+
+bool MySQLResultSetImpl::Next()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->next();
+}
+
+void MySQLResultSetImpl::MoveToCurrentRow()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->moveToCurrentRow();
+}
+
+void MySQLResultSetImpl::MoveToInsertRow()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->moveToInsertRow();
+}
+
+bool MySQLResultSetImpl::Previous()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->previous();
+}
+
+void MySQLResultSetImpl::RefreshRow()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->refreshRow();
+}
+
+bool MySQLResultSetImpl::Relative(int rows)
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->relative(rows);
+}
+
+bool MySQLResultSetImpl::RowDeleted()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->rowDeleted();
+}
+
+bool MySQLResultSetImpl::RowInserted()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->rowInserted();
+}
+
+bool MySQLResultSetImpl::RowUpdated()
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->rowUpdated();
+}
+
+void MySQLResultSetImpl::FetchSize(size_t rows)
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	m_pResultSet->setFetchSize(rows);
+}
+
+size_t MySQLResultSetImpl::RowsCount() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->rowsCount();
+}
+
+bool MySQLResultSetImpl::WasNull() const
+{
+	if (!m_pResultSet)
+		throw std::runtime_error("Empty Result");
+
+	return m_pResultSet->wasNull();
+}
+
+} // namespace MySQL

+ 85 - 0
MySQL/MySQLResultSetImpl.h

@@ -0,0 +1,85 @@
+#ifndef MYSQL_MYSQLRESULTSETIMPL_H
+#define MYSQL_MYSQLRESULTSETIMPL_H
+
+#include "MySQLResultSetMetaDataImpl.h"
+#include <cppconn/resultset.h>
+#include <stdint.h>
+#include <memory>
+#include <string>
+
+
+namespace MySQL {
+
+class MySQLResultSetImpl
+{
+public:
+	MySQLResultSetImpl();
+	explicit MySQLResultSetImpl(const std::shared_ptr<sql::ResultSet>& pResultSet);
+	~MySQLResultSetImpl();
+
+public:
+	bool Absolute(int row);
+	void AfterLast();
+	void BeforeFirst();
+	void CancelRowUpdates();
+	void ClearWarnings();
+	void Close();
+	uint32_t FindColumn(const std::string& columnLabel) const;
+	bool First();
+	std::istream* Blob(uint32_t columnIndex)  const;
+	std::istream* Blob(const std::string& columnLabel) const;
+	bool Boolean(uint32_t columnIndex) const;
+	bool Boolean(const std::string& columnLabel) const;
+	int Concurrency();
+	std::string CursorName();
+	long double Double(uint32_t columnIndex) const;
+	long double Double(const std::string& columnLabel) const;
+	int FetchDirection();
+	size_t FetchSize();
+	int Holdability();
+	int32_t Int(uint32_t columnIndex) const;
+	int32_t Int(const std::string& columnLabel) const;
+	uint32_t UInt(uint32_t columnIndex) const;
+	uint32_t UInt(const std::string& columnLabel) const;
+	int64_t Int64(uint32_t columnIndex) const;
+	int64_t Int64(const std::string& columnLabel) const;
+	uint64_t UInt64(uint32_t columnIndex) const;
+	uint64_t UInt64(const std::string& columnLabel) const;
+	std::shared_ptr<MySQLResultSetMetaDataImpl> MetaData() const;
+	size_t Row() const;
+	//RowID* RowId(uint32_t columnIndex);
+	//RowID* RowId(const std::string & columnLabel);
+	//const Statement* Statement() const;
+	std::string String(uint32_t columnIndex)  const;
+	std::string String(const std::string& columnLabel) const;
+	//enum_type Type() const;
+	void Warnings();
+	void InsertRow();
+	bool IsAfterLast() const;
+	bool IsBeforeFirst() const;
+	bool IsClosed() const;
+	bool IsFirst() const;
+	bool IsLast() const;
+	bool IsNull(uint32_t columnIndex) const;
+	bool IsNull(const std::string& columnLabel) const;
+	bool Last();
+	bool Next();
+	void MoveToCurrentRow();
+	void MoveToInsertRow();
+	bool Previous();
+	void RefreshRow();
+	bool Relative(int rows);
+	bool RowDeleted();
+	bool RowInserted();
+	bool RowUpdated();
+	void FetchSize(size_t rows);
+	size_t RowsCount() const;
+	bool WasNull() const;
+
+private:
+	std::shared_ptr<sql::ResultSet> m_pResultSet;
+};
+
+} // namespace MySQL
+
+#endif // MYSQL_MYSQLRESULTSETIMPL_H

+ 131 - 0
MySQL/MySQLResultSetMetaData.cpp

@@ -0,0 +1,131 @@
+#include "MySQLResultSetMetaData.h"
+#include "MySQLResultSetMetaDataImpl.h"
+
+
+namespace MySQL {
+
+MySQLResultSetMetaData::MySQLResultSetMetaData() :
+	m_pMySQLResultSetMetaDataImpl(new MySQLResultSetMetaDataImpl())
+{
+}
+
+MySQLResultSetMetaData::MySQLResultSetMetaData(std::shared_ptr<MySQLResultSetMetaDataImpl> pMySQLResultSetMetaDataImpl) :
+	m_pMySQLResultSetMetaDataImpl(pMySQLResultSetMetaDataImpl)
+{
+}
+
+MySQLResultSetMetaData::~MySQLResultSetMetaData()
+{
+}
+
+std::string MySQLResultSetMetaData::CatalogName(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->CatalogName(column);
+}
+
+uint32_t MySQLResultSetMetaData::ColumnCount()
+{
+	return m_pMySQLResultSetMetaDataImpl->ColumnCount();
+}
+
+uint32_t MySQLResultSetMetaData::ColumnDisplaySize(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->ColumnDisplaySize(column);
+}
+
+std::string MySQLResultSetMetaData::ColumnLabel(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->ColumnLabel(column);
+}
+
+std::string MySQLResultSetMetaData::ColumnName(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->ColumnName(column);
+}
+
+int MySQLResultSetMetaData::ColumnType(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->ColumnType(column);
+}
+
+std::string MySQLResultSetMetaData::ColumnTypeName(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->ColumnTypeName(column);
+}
+
+uint32_t MySQLResultSetMetaData::Precision(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Precision(column);
+}
+
+uint32_t MySQLResultSetMetaData::Scale(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Scale(column);
+}
+
+std::string MySQLResultSetMetaData::SchemaName(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->SchemaName(column);
+}
+
+std::string MySQLResultSetMetaData::TableName(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->TableName(column);
+}
+
+bool MySQLResultSetMetaData::AutoIncrement(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->AutoIncrement(column);
+}
+
+bool MySQLResultSetMetaData::CaseSensitive(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->CaseSensitive(column);
+}
+
+bool MySQLResultSetMetaData::Currency(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Currency(column);
+}
+
+bool MySQLResultSetMetaData::DefinitelyWritable(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->DefinitelyWritable(column);
+}
+
+int MySQLResultSetMetaData::Nullable(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Nullable(column);
+}
+
+bool MySQLResultSetMetaData::Numeric(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Numeric(column);
+}
+
+bool MySQLResultSetMetaData::ReadOnly(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->ReadOnly(column);
+}
+
+bool MySQLResultSetMetaData::Searchable(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Searchable(column);
+}
+
+bool MySQLResultSetMetaData::Signed(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Signed(column);
+}
+
+bool MySQLResultSetMetaData::Writable(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Writable(column);
+}
+
+bool MySQLResultSetMetaData::Zerofill(uint32_t column)
+{
+	return m_pMySQLResultSetMetaDataImpl->Zerofill(column);
+}
+
+} // namespace MySQL

+ 196 - 0
MySQL/MySQLResultSetMetaDataImpl.cpp

@@ -0,0 +1,196 @@
+#include "MySQLResultSetMetaDataImpl.h"
+#include <stdexcept>
+
+
+namespace MySQL {
+
+MySQLResultSetMetaDataImpl::MySQLResultSetMetaDataImpl()
+{
+}
+
+MySQLResultSetMetaDataImpl::MySQLResultSetMetaDataImpl(sql::ResultSetMetaData* pResultSetMetaData) :
+	m_pResultSetMetaData(pResultSetMetaData)
+{
+}
+
+MySQLResultSetMetaDataImpl::~MySQLResultSetMetaDataImpl()
+{
+}
+
+std::string MySQLResultSetMetaDataImpl::CatalogName(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getCatalogName(column);
+}
+
+uint32_t MySQLResultSetMetaDataImpl::ColumnCount()
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getColumnCount();
+}
+
+uint32_t MySQLResultSetMetaDataImpl::ColumnDisplaySize(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getColumnDisplaySize(column);
+}
+
+std::string MySQLResultSetMetaDataImpl::ColumnLabel(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getColumnLabel(column);
+}
+
+std::string MySQLResultSetMetaDataImpl::ColumnName(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getColumnName(column);
+}
+
+int MySQLResultSetMetaDataImpl::ColumnType(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getColumnType(column);
+}
+
+std::string MySQLResultSetMetaDataImpl::ColumnTypeName(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getColumnTypeName(column);
+}
+
+uint32_t MySQLResultSetMetaDataImpl::Precision(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getPrecision(column);
+}
+
+uint32_t MySQLResultSetMetaDataImpl::Scale(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getScale(column);
+}
+
+std::string MySQLResultSetMetaDataImpl::SchemaName(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getSchemaName(column);
+}
+
+std::string MySQLResultSetMetaDataImpl::TableName(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->getTableName(column);
+}
+
+bool MySQLResultSetMetaDataImpl::AutoIncrement(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isAutoIncrement(column);
+}
+
+bool MySQLResultSetMetaDataImpl::CaseSensitive(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isCaseSensitive(column);
+}
+
+bool MySQLResultSetMetaDataImpl::Currency(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isCurrency(column);
+}
+
+bool MySQLResultSetMetaDataImpl::DefinitelyWritable(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isDefinitelyWritable(column);
+}
+
+int MySQLResultSetMetaDataImpl::Nullable(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isNullable(column);
+}
+
+bool MySQLResultSetMetaDataImpl::Numeric(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isNumeric(column);
+}
+
+bool MySQLResultSetMetaDataImpl::ReadOnly(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isReadOnly(column);
+}
+
+bool MySQLResultSetMetaDataImpl::Searchable(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isSearchable(column);
+}
+
+bool MySQLResultSetMetaDataImpl::Signed(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isSigned(column);
+}
+
+bool MySQLResultSetMetaDataImpl::Writable(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isWritable(column);
+}
+
+bool MySQLResultSetMetaDataImpl::Zerofill(uint32_t column)
+{
+	if (!m_pResultSetMetaData)
+		throw std::runtime_error("No Metadata for Result");
+
+	return m_pResultSetMetaData->isZerofill(column);
+}
+
+} // namespace MySQL

+ 48 - 0
MySQL/MySQLResultSetMetaDataImpl.h

@@ -0,0 +1,48 @@
+#ifndef MYSQL_MYSQLRESULTSETMETADATAIMPL_H
+#define MYSQL_MYSQLRESULTSETMETADATAIMPL_H
+
+#include <cppconn/resultset_metadata.h>
+#include <stdint.h>
+#include <string>
+
+
+namespace MySQL {
+
+class MySQLResultSetMetaDataImpl
+{
+public:
+	MySQLResultSetMetaDataImpl();
+	explicit MySQLResultSetMetaDataImpl(sql::ResultSetMetaData* pResultSetMetaData);
+	~MySQLResultSetMetaDataImpl();
+
+public:
+	std::string CatalogName(uint32_t column);
+	uint32_t ColumnCount();
+	uint32_t ColumnDisplaySize(uint32_t column);
+	std::string ColumnLabel(uint32_t column);
+	std::string ColumnName(uint32_t column);
+	int ColumnType(uint32_t column);
+	std::string ColumnTypeName(uint32_t column);
+	uint32_t Precision(uint32_t column);
+	uint32_t Scale(uint32_t column);
+	std::string SchemaName(uint32_t column);
+	std::string TableName(uint32_t column);
+	bool AutoIncrement(uint32_t column);
+	bool CaseSensitive(uint32_t column);
+	bool Currency(uint32_t column);
+	bool DefinitelyWritable(uint32_t column);
+	int Nullable(uint32_t column);
+	bool Numeric(uint32_t column);
+	bool ReadOnly(uint32_t column);
+	bool Searchable(uint32_t column);
+	bool Signed(uint32_t column);
+	bool Writable(uint32_t column);
+	bool Zerofill(uint32_t column);
+
+private:
+	sql::ResultSetMetaData* m_pResultSetMetaData;
+};
+
+} // namespace MySQL
+
+#endif // MYSQL_MYSQLRESULTSETMETADATAIMPL_H

+ 34 - 0
include/MySQLClient.h

@@ -0,0 +1,34 @@
+#ifndef MYSQLCLIENT_H
+#define MYSQLCLIENT_H
+
+#include "MySQLResultSet.h"
+#include <memory>
+#include <string>
+
+
+namespace MySQL {
+
+class MySQLClientImpl;
+
+class MySQLClient
+{
+public:
+	MySQLClient();
+	~MySQLClient();
+
+	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();
+
+	std::string Database() const;
+
+	void Execute(const std::string& query) const;
+	MySQLResultSet ExecuteQuery(const std::string& query) const;
+
+private:
+	std::unique_ptr<MySQLClientImpl> m_pMySQLClientImpl;
+};
+
+} // namespace MySQL
+
+#endif // MYSQLCLIENT_H

+ 91 - 0
include/MySQLResultSet.h

@@ -0,0 +1,91 @@
+#ifndef MYSQLRESULTSET_H
+#define MYSQLRESULTSET_H
+
+#include "MySQLResultSetMetaData.h"
+#include <memory>
+#include <string>
+
+
+namespace MySQL {
+
+class MySQLResultSetImpl;
+
+class MySQLResultSet
+{
+public:
+	MySQLResultSet();
+	~MySQLResultSet();
+
+public:
+	bool Absolute(int row);
+	void AfterLast();
+	void BeforeFirst();
+	void CancelRowUpdates();
+	void ClearWarnings();
+	void Close();
+	uint32_t FindColumn(const std::string& columnLabel) const;
+	bool First();
+	std::istream* Blob(uint32_t columnIndex)  const;
+	std::istream* Blob(const std::string& columnLabel) const;
+	bool Boolean(uint32_t columnIndex) const;
+	bool Boolean(const std::string& columnLabel) const;
+	int Concurrency();
+	std::string CursorName();
+	long double Double(uint32_t columnIndex) const;
+	long double Double(const std::string& columnLabel) const;
+	int FetchDirection();
+	size_t FetchSize();
+	int Holdability();
+	int32_t Int(uint32_t columnIndex) const;
+	int32_t Int(const std::string& columnLabel) const;
+	uint32_t UInt(uint32_t columnIndex) const;
+	uint32_t UInt(const std::string& columnLabel) const;
+	int64_t Int64(uint32_t columnIndex) const;
+	int64_t Int64(const std::string& columnLabel) const;
+	uint64_t UInt64(uint32_t columnIndex) const;
+	uint64_t UInt64(const std::string& columnLabel) const;
+	MySQLResultSetMetaData MetaData() const;
+	size_t Row() const;
+	//RowID* RowId(uint32_t columnIndex);
+	//RowID* RowId(const std::string & columnLabel);
+	//const Statement* Statement() const;
+	std::string String(uint32_t columnIndex)  const;
+	std::string String(const std::string& columnLabel) const;
+	//enum_type Type() const;
+	void Warnings();
+	void InsertRow();
+	bool IsAfterLast() const;
+	bool IsBeforeFirst() const;
+	bool IsClosed() const;
+	bool IsFirst() const;
+	bool IsLast() const;
+	bool IsNull(uint32_t columnIndex) const;
+	bool IsNull(const std::string& columnLabel) const;
+	bool Last();
+	bool Next();
+	void MoveToCurrentRow();
+	void MoveToInsertRow();
+	bool Previous();
+	void RefreshRow();
+	bool Relative(int rows);
+	bool RowDeleted();
+	bool RowInserted();
+	bool RowUpdated();
+	void FetchSize(size_t rows);
+	size_t RowsCount() const;
+	bool WasNull() const;
+
+private:
+	MySQLResultSet(std::shared_ptr<MySQLResultSetImpl> pMySQLResultSetImpl);
+
+private:
+	friend class MySQLClient;
+	friend class MySQLClientImpl;
+
+private:
+	std::shared_ptr<MySQLResultSetImpl> m_pMySQLResultSetImpl;
+};
+
+} // namespace MySQL
+
+#endif // MYSQLRESULTSET_H

+ 56 - 0
include/MySQLResultSetMetaData.h

@@ -0,0 +1,56 @@
+#ifndef MYSQLRESULTSETMETADATA_H
+#define MYSQLRESULTSETMETADATA_H
+
+#include <memory>
+#include <string>
+
+
+namespace MySQL {
+
+class MySQLResultSet;
+class MySQLResultSetMetaDataImpl;
+
+class MySQLResultSetMetaData
+{
+public:
+	MySQLResultSetMetaData();
+	~MySQLResultSetMetaData();
+
+public:
+	std::string CatalogName(uint32_t column);
+	uint32_t ColumnCount();
+	uint32_t ColumnDisplaySize(uint32_t column);
+	std::string ColumnLabel(uint32_t column);
+	std::string ColumnName(uint32_t column);
+	int ColumnType(uint32_t column);
+	std::string ColumnTypeName(uint32_t column);
+	uint32_t Precision(uint32_t column);
+	uint32_t Scale(uint32_t column);
+	std::string SchemaName(uint32_t column);
+	std::string TableName(uint32_t column);
+	bool AutoIncrement(uint32_t column);
+	bool CaseSensitive(uint32_t column);
+	bool Currency(uint32_t column);
+	bool DefinitelyWritable(uint32_t column);
+	int Nullable(uint32_t column);
+	bool Numeric(uint32_t column);
+	bool ReadOnly(uint32_t column);
+	bool Searchable(uint32_t column);
+	bool Signed(uint32_t column);
+	bool Writable(uint32_t column);
+	bool Zerofill(uint32_t column);
+
+private:
+	MySQLResultSetMetaData(std::shared_ptr<MySQLResultSetMetaDataImpl> pMySQLResultSetMetaDataImpl);
+
+private:
+	friend class MySQLResultSet;
+	friend class MySQLResultSetMetaDataImpl;
+
+private:
+	std::shared_ptr<MySQLResultSetMetaDataImpl> m_pMySQLResultSetMetaDataImpl;
+};
+
+} // namespace MySQL
+
+#endif // MYSQLRESULTSETMETADATA_H