Created Pgsql::Transaction class for handling of transactions. It auto rollsback if no commit has been done.
Also moved some code out of the connection files to their own files.
This commit is contained in:
parent
255b2ec970
commit
e32c82ac6f
12 changed files with 394 additions and 130 deletions
43
pgsql/Pgsql_Canceller.cpp
Normal file
43
pgsql/Pgsql_Canceller.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "Pgsql_Canceller.h"
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
|
||||||
|
Canceller::Canceller(PGcancel *c)
|
||||||
|
: m_cancel(c)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Canceller::Canceller(Canceller&& rhs)
|
||||||
|
: m_cancel(rhs.m_cancel)
|
||||||
|
{
|
||||||
|
rhs.m_cancel = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Canceller& Canceller::operator=(Canceller&& rhs)
|
||||||
|
{
|
||||||
|
if (m_cancel) {
|
||||||
|
PQfreeCancel(m_cancel);
|
||||||
|
}
|
||||||
|
m_cancel = rhs.m_cancel;
|
||||||
|
rhs.m_cancel = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Canceller::~Canceller()
|
||||||
|
{
|
||||||
|
if (m_cancel) {
|
||||||
|
PQfreeCancel(m_cancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Canceller::cancel(std::string *error)
|
||||||
|
{
|
||||||
|
const int errbuf_size = 256;
|
||||||
|
char errbuf[errbuf_size];
|
||||||
|
bool res = PQcancel(m_cancel, errbuf, errbuf_size);
|
||||||
|
if (!res && error) {
|
||||||
|
*error = errbuf;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
pgsql/Pgsql_Canceller.h
Normal file
28
pgsql/Pgsql_Canceller.h
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef PGSQL_CANCELLER_H
|
||||||
|
#define PGSQL_CANCELLER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <libpq-fe.h>
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
|
||||||
|
/** \brief Wrapper for a cancel object from libpq.
|
||||||
|
*/
|
||||||
|
class Canceller {
|
||||||
|
public:
|
||||||
|
Canceller() = default;
|
||||||
|
Canceller(PGcancel *c);
|
||||||
|
Canceller(const Canceller&) = delete;
|
||||||
|
Canceller& operator=(const Canceller&) = delete;
|
||||||
|
Canceller(Canceller&& rhs);
|
||||||
|
Canceller& operator=(Canceller&& rhs);
|
||||||
|
~Canceller();
|
||||||
|
|
||||||
|
bool cancel(std::string *error);
|
||||||
|
private:
|
||||||
|
PGcancel *m_cancel = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PGSQL_CANCELLER_H
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
#include "Pgsql_Col.h"
|
|
||||||
|
|
||||||
|
|
@ -7,49 +7,6 @@
|
||||||
|
|
||||||
using namespace Pgsql;
|
using namespace Pgsql;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Canceller::Canceller(PGcancel *c)
|
|
||||||
: m_cancel(c)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Canceller::Canceller(Canceller&& rhs)
|
|
||||||
: m_cancel(rhs.m_cancel)
|
|
||||||
{
|
|
||||||
rhs.m_cancel = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Canceller& Canceller::operator=(Canceller&& rhs)
|
|
||||||
{
|
|
||||||
if (m_cancel) {
|
|
||||||
PQfreeCancel(m_cancel);
|
|
||||||
}
|
|
||||||
m_cancel = rhs.m_cancel;
|
|
||||||
rhs.m_cancel = nullptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Canceller::~Canceller()
|
|
||||||
{
|
|
||||||
if (m_cancel) {
|
|
||||||
PQfreeCancel(m_cancel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Canceller::cancel(std::string *error)
|
|
||||||
{
|
|
||||||
const int errbuf_size = 256;
|
|
||||||
char errbuf[errbuf_size];
|
|
||||||
bool res = PQcancel(m_cancel, errbuf, errbuf_size);
|
|
||||||
if (!res && error) {
|
|
||||||
*error = errbuf;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Connection::Connection() = default;
|
Connection::Connection() = default;
|
||||||
|
|
||||||
Connection::~Connection()
|
Connection::~Connection()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
#include <cassert>
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -12,6 +11,7 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "Pgsql_Canceller.h"
|
||||||
#include "Pgsql_Result.h"
|
#include "Pgsql_Result.h"
|
||||||
|
|
||||||
namespace Pgsql {
|
namespace Pgsql {
|
||||||
|
|
@ -28,23 +28,6 @@ namespace Pgsql {
|
||||||
class Result;
|
class Result;
|
||||||
class Params;
|
class Params;
|
||||||
|
|
||||||
/** \brief Wrapper for a cancel object from libpq.
|
|
||||||
*/
|
|
||||||
class Canceller {
|
|
||||||
public:
|
|
||||||
Canceller() = default;
|
|
||||||
Canceller(PGcancel *c);
|
|
||||||
Canceller(const Canceller&) = delete;
|
|
||||||
Canceller& operator=(const Canceller&) = delete;
|
|
||||||
Canceller(Canceller&& rhs);
|
|
||||||
Canceller& operator=(Canceller&& rhs);
|
|
||||||
~Canceller();
|
|
||||||
|
|
||||||
bool cancel(std::string *error);
|
|
||||||
private:
|
|
||||||
PGcancel *m_cancel = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \brief Class for connecting to the database.
|
/** \brief Class for connecting to the database.
|
||||||
*
|
*
|
||||||
* The class isolates the programmer from the worst C style parts
|
* The class isolates the programmer from the worst C style parts
|
||||||
|
|
@ -87,6 +70,7 @@ namespace Pgsql {
|
||||||
int socket();
|
int socket();
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
Canceller getCancel();
|
Canceller getCancel();
|
||||||
|
|
||||||
std::string getErrorMessage() const;
|
std::string getErrorMessage() const;
|
||||||
|
|
|
||||||
46
pgsql/Pgsql_ErrorDetails.cpp
Normal file
46
pgsql/Pgsql_ErrorDetails.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "Pgsql_ErrorDetails.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void set_stdstring_with_charptr(std::string &s, const char *p)
|
||||||
|
{
|
||||||
|
if (p) {
|
||||||
|
s = p;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // einde unnamed namespace
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
|
||||||
|
ErrorDetails ErrorDetails::createErrorDetailsFromPGresult(const PGresult *result)
|
||||||
|
{
|
||||||
|
|
||||||
|
ErrorDetails r;
|
||||||
|
set_stdstring_with_charptr(r.errorMessage, PQresultErrorMessage(result));
|
||||||
|
set_stdstring_with_charptr(r.state, PQresultErrorField(result, PG_DIAG_SQLSTATE)); ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
|
||||||
|
set_stdstring_with_charptr(r.severity, PQresultErrorField(result, PG_DIAG_SEVERITY));
|
||||||
|
set_stdstring_with_charptr(r.messagePrimary, PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY));
|
||||||
|
set_stdstring_with_charptr(r.messageDetail, PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL));
|
||||||
|
set_stdstring_with_charptr(r.messageHint, PQresultErrorField(result, PG_DIAG_MESSAGE_HINT));
|
||||||
|
const char * p = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
|
||||||
|
r.statementPosition = p != nullptr ? atoi(p) : -1; ///< First character is one, measured in characters not bytes!
|
||||||
|
p = PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION);
|
||||||
|
r.internalPosition = p != nullptr ? atoi(p) : -1;
|
||||||
|
set_stdstring_with_charptr(r.internalQuery, PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY));
|
||||||
|
set_stdstring_with_charptr(r.context, PQresultErrorField(result, PG_DIAG_CONTEXT));
|
||||||
|
set_stdstring_with_charptr(r.schemaName, PQresultErrorField(result, PG_DIAG_SCHEMA_NAME));
|
||||||
|
set_stdstring_with_charptr(r.tableName, PQresultErrorField(result, PG_DIAG_TABLE_NAME));
|
||||||
|
set_stdstring_with_charptr(r.columnName, PQresultErrorField(result, PG_DIAG_COLUMN_NAME));
|
||||||
|
set_stdstring_with_charptr(r.datatypeName, PQresultErrorField(result, PG_DIAG_DATATYPE_NAME));
|
||||||
|
set_stdstring_with_charptr(r.constraintName, PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME));
|
||||||
|
set_stdstring_with_charptr(r.sourceFile, PQresultErrorField(result, PG_DIAG_SOURCE_FILE));
|
||||||
|
set_stdstring_with_charptr(r.sourceLine, PQresultErrorField(result, PG_DIAG_SOURCE_LINE));
|
||||||
|
set_stdstring_with_charptr(r.sourceFunction, PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
pgsql/Pgsql_ErrorDetails.h
Normal file
35
pgsql/Pgsql_ErrorDetails.h
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef PGSQL_ERRORDETAILS_H
|
||||||
|
#define PGSQL_ERRORDETAILS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <libpq-fe.h>
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
|
||||||
|
class ErrorDetails {
|
||||||
|
public:
|
||||||
|
static ErrorDetails createErrorDetailsFromPGresult(const PGresult *res);
|
||||||
|
|
||||||
|
std::string errorMessage;
|
||||||
|
std::string state; ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
|
||||||
|
std::string severity;
|
||||||
|
std::string messagePrimary;
|
||||||
|
std::string messageDetail;
|
||||||
|
std::string messageHint;
|
||||||
|
int statementPosition; ///< First character is one, measured in characters not bytes!
|
||||||
|
int internalPosition;
|
||||||
|
std::string internalQuery;
|
||||||
|
std::string context;
|
||||||
|
std::string schemaName;
|
||||||
|
std::string tableName;
|
||||||
|
std::string columnName;
|
||||||
|
std::string datatypeName;
|
||||||
|
std::string constraintName;
|
||||||
|
std::string sourceFile;
|
||||||
|
std::string sourceLine;
|
||||||
|
std::string sourceFunction;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PGSQL_ERRORDETAILS_H
|
||||||
|
|
@ -2,46 +2,6 @@
|
||||||
|
|
||||||
using namespace Pgsql;
|
using namespace Pgsql;
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void set_stdstring_with_charptr(std::string &s, const char *p)
|
|
||||||
{
|
|
||||||
if (p) {
|
|
||||||
s = p;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
s.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // einde unnamed namespace
|
|
||||||
|
|
||||||
ErrorDetails ErrorDetails::createErrorDetailsFromPGresult(const PGresult *result)
|
|
||||||
{
|
|
||||||
|
|
||||||
ErrorDetails r;
|
|
||||||
set_stdstring_with_charptr(r.errorMessage, PQresultErrorMessage(result));
|
|
||||||
set_stdstring_with_charptr(r.state, PQresultErrorField(result, PG_DIAG_SQLSTATE)); ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
|
|
||||||
set_stdstring_with_charptr(r.severity, PQresultErrorField(result, PG_DIAG_SEVERITY));
|
|
||||||
set_stdstring_with_charptr(r.messagePrimary, PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY));
|
|
||||||
set_stdstring_with_charptr(r.messageDetail, PQresultErrorField(result, PG_DIAG_MESSAGE_DETAIL));
|
|
||||||
set_stdstring_with_charptr(r.messageHint, PQresultErrorField(result, PG_DIAG_MESSAGE_HINT));
|
|
||||||
const char * p = PQresultErrorField(result, PG_DIAG_STATEMENT_POSITION);
|
|
||||||
r.statementPosition = p != nullptr ? atoi(p) : -1; ///< First character is one, measured in characters not bytes!
|
|
||||||
p = PQresultErrorField(result, PG_DIAG_INTERNAL_POSITION);
|
|
||||||
r.internalPosition = p != nullptr ? atoi(p) : -1;
|
|
||||||
set_stdstring_with_charptr(r.internalQuery, PQresultErrorField(result, PG_DIAG_INTERNAL_QUERY));
|
|
||||||
set_stdstring_with_charptr(r.context, PQresultErrorField(result, PG_DIAG_CONTEXT));
|
|
||||||
set_stdstring_with_charptr(r.schemaName, PQresultErrorField(result, PG_DIAG_SCHEMA_NAME));
|
|
||||||
set_stdstring_with_charptr(r.tableName, PQresultErrorField(result, PG_DIAG_TABLE_NAME));
|
|
||||||
set_stdstring_with_charptr(r.columnName, PQresultErrorField(result, PG_DIAG_COLUMN_NAME));
|
|
||||||
set_stdstring_with_charptr(r.datatypeName, PQresultErrorField(result, PG_DIAG_DATATYPE_NAME));
|
|
||||||
set_stdstring_with_charptr(r.constraintName, PQresultErrorField(result, PG_DIAG_CONSTRAINT_NAME));
|
|
||||||
set_stdstring_with_charptr(r.sourceFile, PQresultErrorField(result, PG_DIAG_SOURCE_FILE));
|
|
||||||
set_stdstring_with_charptr(r.sourceLine, PQresultErrorField(result, PG_DIAG_SOURCE_LINE));
|
|
||||||
set_stdstring_with_charptr(r.sourceFunction, PQresultErrorField(result, PG_DIAG_SOURCE_FUNCTION));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result::Result(PGresult *res)
|
Result::Result(PGresult *res)
|
||||||
: result(res)
|
: result(res)
|
||||||
|
|
|
||||||
|
|
@ -2,33 +2,10 @@
|
||||||
#define PGSQL_RESULT_H
|
#define PGSQL_RESULT_H
|
||||||
|
|
||||||
#include "Pgsql_Row.h"
|
#include "Pgsql_Row.h"
|
||||||
|
#include "Pgsql_ErrorDetails.h"
|
||||||
|
|
||||||
namespace Pgsql {
|
namespace Pgsql {
|
||||||
|
|
||||||
class ErrorDetails {
|
|
||||||
public:
|
|
||||||
static ErrorDetails createErrorDetailsFromPGresult(const PGresult *res);
|
|
||||||
|
|
||||||
std::string errorMessage;
|
|
||||||
std::string state; ///< PG_DIAG_SQLSTATE Error code as listed in https://www.postgresql.org/docs/9.5/static/errcodes-appendix.html
|
|
||||||
std::string severity;
|
|
||||||
std::string messagePrimary;
|
|
||||||
std::string messageDetail;
|
|
||||||
std::string messageHint;
|
|
||||||
int statementPosition; ///< First character is one, measured in characters not bytes!
|
|
||||||
int internalPosition;
|
|
||||||
std::string internalQuery;
|
|
||||||
std::string context;
|
|
||||||
std::string schemaName;
|
|
||||||
std::string tableName;
|
|
||||||
std::string columnName;
|
|
||||||
std::string datatypeName;
|
|
||||||
std::string constraintName;
|
|
||||||
std::string sourceFile;
|
|
||||||
std::string sourceLine;
|
|
||||||
std::string sourceFunction;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \brief Non-copyable but movable wrapper for a postgresql result.
|
/** \brief Non-copyable but movable wrapper for a postgresql result.
|
||||||
*
|
*
|
||||||
* This class makes sure the result is removed from memory. It also supplies an iterator for the
|
* This class makes sure the result is removed from memory. It also supplies an iterator for the
|
||||||
|
|
|
||||||
178
pgsql/Pgsql_Transaction.cpp
Normal file
178
pgsql/Pgsql_Transaction.cpp
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
#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 ¶ms)
|
||||||
|
{
|
||||||
|
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 ¶ms)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_conn != nullptr);
|
||||||
|
BOOST_ASSERT(m_committed == false);
|
||||||
|
BOOST_ASSERT(m_rolledback == false);
|
||||||
|
|
||||||
|
return m_conn->queryParam(command, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Transaction::sendQuery(const char * query)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_conn != nullptr);
|
||||||
|
BOOST_ASSERT(m_committed == false);
|
||||||
|
BOOST_ASSERT(m_rolledback == false);
|
||||||
|
|
||||||
|
return m_conn->sendQuery(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Transaction::sendQuery(const std::string &command)
|
||||||
|
{
|
||||||
|
return sendQuery(command.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Transaction::sendQuery(const QString &command)
|
||||||
|
{
|
||||||
|
return sendQuery(command.toUtf8().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Transaction::sendQueryParams(const char * command, const Params ¶ms)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(m_conn != nullptr);
|
||||||
|
BOOST_ASSERT(m_committed == false);
|
||||||
|
BOOST_ASSERT(m_rolledback == false);
|
||||||
|
|
||||||
|
return 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
|
||||||
53
pgsql/Pgsql_Transaction.h
Normal file
53
pgsql/Pgsql_Transaction.h
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef PGSQL_TRANSACTION_H
|
||||||
|
#define PGSQL_TRANSACTION_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <string>
|
||||||
|
#include "Pgsql_Canceller.h"
|
||||||
|
|
||||||
|
namespace Pgsql {
|
||||||
|
|
||||||
|
class Result;
|
||||||
|
class Params;
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
|
||||||
|
class Transaction {
|
||||||
|
public:
|
||||||
|
static Transaction startTransaction(Connection &conn);
|
||||||
|
~Transaction();
|
||||||
|
void rollback();
|
||||||
|
void commit();
|
||||||
|
Canceller getCancel();
|
||||||
|
std::string getErrorMessage() const;
|
||||||
|
Result query(const char * command);
|
||||||
|
Result query(const QString &command);
|
||||||
|
Result queryParam(const char * command, const Params ¶ms);
|
||||||
|
Result queryParam(const QString &command, const Params ¶ms);
|
||||||
|
bool sendQuery(const char * query);
|
||||||
|
bool sendQuery(const std::string &command);
|
||||||
|
bool sendQuery(const QString &command);
|
||||||
|
bool sendQueryParams(const char * command, const Params ¶ms);
|
||||||
|
std::shared_ptr<Result> getResult();
|
||||||
|
bool consumeInput();
|
||||||
|
bool isBusy();
|
||||||
|
std::string escapeLiteral(const std::string_view &literal);
|
||||||
|
QString escapeLiteral(const QString &literal);
|
||||||
|
std::string escapeIdentifier(const std::string_view &ident);
|
||||||
|
QString escapeIdentifier(const QString &ident);
|
||||||
|
QString getDBName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Connection *m_conn = nullptr;
|
||||||
|
bool m_committed = false;
|
||||||
|
bool m_rolledback = false;
|
||||||
|
|
||||||
|
Transaction(Connection *conn)
|
||||||
|
: m_conn(conn)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PGSQL_TRANSACTION_H
|
||||||
|
|
@ -35,9 +35,11 @@ SOURCES += Pgsql_Connection.cpp \
|
||||||
Pgsql_Result.cpp \
|
Pgsql_Result.cpp \
|
||||||
Pgsql_Row.cpp \
|
Pgsql_Row.cpp \
|
||||||
Pgsql_Value.cpp \
|
Pgsql_Value.cpp \
|
||||||
Pgsql_Col.cpp \
|
|
||||||
ArrayParser.cpp \
|
ArrayParser.cpp \
|
||||||
Pgsql_oids.cpp
|
Pgsql_oids.cpp \
|
||||||
|
Pgsql_Transaction.cpp \
|
||||||
|
Pgsql_ErrorDetails.cpp \
|
||||||
|
Pgsql_Canceller.cpp
|
||||||
|
|
||||||
HEADERS += Pgsql_Connection.h \
|
HEADERS += Pgsql_Connection.h \
|
||||||
Pgsql_Params.h \
|
Pgsql_Params.h \
|
||||||
|
|
@ -49,7 +51,10 @@ HEADERS += Pgsql_Connection.h \
|
||||||
Pgsql_Col.h \
|
Pgsql_Col.h \
|
||||||
ArrayParser.h \
|
ArrayParser.h \
|
||||||
Pgsql_oids.h \
|
Pgsql_oids.h \
|
||||||
SqlGenerator.h
|
SqlGenerator.h \
|
||||||
|
Pgsql_Transaction.h \
|
||||||
|
Pgsql_ErrorDetails.h \
|
||||||
|
Pgsql_Canceller.h
|
||||||
|
|
||||||
#FORMS +=
|
#FORMS +=
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue