#include "Pgsql_Transaction.h"

#include "Pgsql_Connection.h"
#include <boost/assert.hpp>

namespace Pgsql {

	Transaction Transaction::startTransaction(Connection &conn)
	{
		conn.query("BEGIN");
		return Transaction(&conn);
	}

	Transaction::~Transaction()
	{
		if (m_conn && !m_committed && !m_rolledback) {
			m_conn->query("ROLLBACK");
		}
	}

	void Transaction::rollback()
	{
		m_conn->query("ROLLBACK");
		m_rolledback = true;
	}

	void Transaction::commit()
	{
		m_conn->query("COMMIT");
		m_committed = true;
	}

	Canceller Transaction::getCancel()
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->getCancel();
	}

	std::string Transaction::getErrorMessage() const
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->getErrorMessage();
	}

	Result Transaction::query(const char * command)
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->query(command);
	}

	Result Transaction::query(const QString &command)
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->query(command);
	}

	Result Transaction::queryParam(const char * command, const Params &params)
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->queryParam(command, params);
	}

	Result Transaction::queryParam(const QString &command, const Params &params)
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->queryParam(command, params);
	}

    void Transaction::sendQuery(const char * query)
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

        m_conn->sendQuery(query);
	}

    void Transaction::sendQuery(const std::string &command)
	{
        sendQuery(command.c_str());
	}

    void Transaction::sendQuery(const QString &command)
	{
        sendQuery(command.toUtf8().data());
	}

    void Transaction::sendQueryParams(const char * command, const Params &params)
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

        m_conn->sendQueryParams(command, params);
	}

	std::shared_ptr<Result> Transaction::getResult()
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->getResult();
	}

	bool Transaction::consumeInput()
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->consumeInput();
	}

	bool Transaction::isBusy()
	{
		BOOST_ASSERT(m_conn != nullptr);
		BOOST_ASSERT(m_committed == false);
		BOOST_ASSERT(m_rolledback == false);

		return m_conn->isBusy();
	}

	std::string Transaction::escapeLiteral(const std::string_view &literal)
	{
		BOOST_ASSERT(m_conn != nullptr);

		return m_conn->escapeLiteral(literal);
	}

	QString Transaction::escapeLiteral(const QString &literal)
	{
		BOOST_ASSERT(m_conn != nullptr);

		return m_conn->escapeLiteral(literal);
	}

	std::string Transaction::escapeIdentifier(const std::string_view &ident)
	{
		BOOST_ASSERT(m_conn != nullptr);

		return m_conn->escapeIdentifier(ident);
	}

	QString Transaction::escapeIdentifier(const QString &ident)
	{
		BOOST_ASSERT(m_conn != nullptr);

		return m_conn->escapeIdentifier(ident);
	}


	QString Transaction::getDBName() const
	{
		BOOST_ASSERT(m_conn != nullptr);

		return m_conn->getDBName();
	}

} // end of namespace Pgsql
