Improved support from removing rows in crud tabs.
It can handle now complex selections and reports back errors encountered when removing the rows fails.
This commit is contained in:
parent
950fea873c
commit
62c6ad5bfb
10 changed files with 365 additions and 116 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#include "Pgsql_Connection.h"
|
||||
#include "Pgsql_declare.h"
|
||||
#include "Pgsql_PgException.h"
|
||||
#include "Pgsql_Params.h"
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
|
@ -107,6 +108,7 @@ std::string Connection::getErrorMessage() const
|
|||
Result Connection::query(const char * command)
|
||||
{
|
||||
PGresult *result = PQexec(conn, command);
|
||||
throwError(result);
|
||||
return Result(result);
|
||||
}
|
||||
|
||||
|
|
@ -114,6 +116,7 @@ Result Connection::queryParam(const char * command, const Params ¶ms)
|
|||
{
|
||||
PGresult *result = PQexecParams(conn, command, params.size(), params.types(),
|
||||
params.values(), params.lengths(), params.formats(), 0);
|
||||
throwError(result);
|
||||
return Result(result);
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +145,7 @@ std::shared_ptr<Result> Connection::getResult()
|
|||
{
|
||||
PGresult *r = PQgetResult(conn);
|
||||
if (r) {
|
||||
throwError(r);
|
||||
return std::make_shared<Result>(r);
|
||||
}
|
||||
else {
|
||||
|
|
@ -225,3 +229,32 @@ QString Connection::getDBName() const
|
|||
{
|
||||
return QString::fromUtf8(PQdb(conn));
|
||||
}
|
||||
|
||||
void Connection::throwError(PGresult *result) const
|
||||
{
|
||||
auto state = PQresultStatus(result);
|
||||
if (state == PGRES_BAD_RESPONSE) {
|
||||
// communication problem
|
||||
}
|
||||
else if (state == PGRES_FATAL_ERROR) {
|
||||
auto details = Pgsql::ErrorDetails::createErrorDetailsFromPGresult(result);
|
||||
throw PgResultError(details);
|
||||
}
|
||||
}
|
||||
|
||||
//PGRES_EMPTY_QUERY = 0, /* empty query string was executed */
|
||||
//PGRES_COMMAND_OK, /* a query command that doesn't return
|
||||
// * anything was executed properly by the
|
||||
// * backend */
|
||||
//PGRES_TUPLES_OK, /* a query command that returns tuples was
|
||||
// * executed properly by the backend, PGresult
|
||||
// * contains the result tuples */
|
||||
//PGRES_COPY_OUT, /* Copy Out data transfer in progress */
|
||||
//PGRES_COPY_IN, /* Copy In data transfer in progress */
|
||||
//PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the
|
||||
// * backend */
|
||||
//PGRES_NONFATAL_ERROR, /* notice or warning message */
|
||||
//PGRES_FATAL_ERROR, /* query failed */
|
||||
//PGRES_COPY_BOTH, /* Copy In/Out data transfer in progress */
|
||||
//PGRES_SINGLE_TUPLE /* single tuple from larger resultset */
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ namespace Pgsql {
|
|||
PGconn *conn = nullptr;
|
||||
std::function<void(const PGresult *)> notifyReceiver;
|
||||
|
||||
void throwError(PGresult *result) const;
|
||||
static void notifyReceiveFunc(void *arg, const PGresult *result);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,54 @@
|
|||
#include "Pgsql_PgException.h"
|
||||
#include "Pgsql_PgException.h"
|
||||
|
||||
namespace Pgsql {
|
||||
|
||||
ResultCode::ResultCode(std::string result_code)
|
||||
: m_resultCode(std::move(result_code))
|
||||
{
|
||||
assert(m_resultCode.length() == 5);
|
||||
}
|
||||
|
||||
std::string ResultCode::getClass() const
|
||||
{
|
||||
return m_resultCode.substr(1,2);
|
||||
}
|
||||
|
||||
/** Helper to easily check the class of the error
|
||||
*
|
||||
*/
|
||||
bool ResultCode::isClass(const std::string_view cls)
|
||||
{
|
||||
return m_resultCode.compare(1, 2, cls);
|
||||
}
|
||||
|
||||
const std::string& ResultCode::getSpecific() const
|
||||
{
|
||||
return m_resultCode;
|
||||
}
|
||||
|
||||
|
||||
PgException::PgException(const char *msg)
|
||||
: std::runtime_error(msg)
|
||||
{}
|
||||
|
||||
PgException::PgException(std::string msg)
|
||||
: std::runtime_error(msg)
|
||||
{}
|
||||
|
||||
|
||||
PgResultError::PgResultError(const Pgsql::ErrorDetails &details)
|
||||
: PgException(details.errorMessage)
|
||||
, m_details(details)
|
||||
{}
|
||||
|
||||
ResultCode PgResultError::getResultCode() const
|
||||
{
|
||||
return ResultCode(m_details.state);
|
||||
}
|
||||
|
||||
const Pgsql::ErrorDetails& PgResultError::details() const
|
||||
{
|
||||
return m_details;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef PGEXCEPTION_H
|
||||
#define PGEXCEPTION_H
|
||||
|
||||
#include "Pgsql_ErrorDetails.h"
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
|
@ -9,68 +10,39 @@ namespace Pgsql {
|
|||
|
||||
class ResultCode {
|
||||
public:
|
||||
explicit ResultCode(std::string result_code)
|
||||
: m_resultCode(std::move(result_code))
|
||||
{
|
||||
assert(m_resultCode.length() == 5);
|
||||
}
|
||||
|
||||
std::string getClass() const
|
||||
{
|
||||
return m_resultCode.substr(1,2);
|
||||
}
|
||||
|
||||
/** Helper to easily check the class of the error
|
||||
*
|
||||
*/
|
||||
bool isClass(const std::string_view cls)
|
||||
{
|
||||
return m_resultCode.compare(1, 2, cls);
|
||||
}
|
||||
|
||||
const std::string& getSpecific() const
|
||||
{
|
||||
return m_resultCode;
|
||||
}
|
||||
explicit ResultCode(std::string result_code);
|
||||
std::string getClass() const;
|
||||
bool isClass(const std::string_view cls);
|
||||
const std::string& getSpecific() const;
|
||||
private:
|
||||
std::string m_resultCode;
|
||||
};
|
||||
|
||||
class PgException: public std::runtime_error {
|
||||
public:
|
||||
PgException(const char *msg)
|
||||
: std::runtime_error(msg)
|
||||
{}
|
||||
PgException(std::string msg)
|
||||
: std::runtime_error(msg)
|
||||
{}
|
||||
|
||||
|
||||
PgException(const char *msg);
|
||||
PgException(std::string msg);
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class PgResultError: public PgException {
|
||||
public:
|
||||
PgResultError(std::string msg, std::string result_code)
|
||||
: PgException(std::move(msg))
|
||||
, m_resultCode(result_code)
|
||||
{}
|
||||
|
||||
ResultCode getResultCode() const { return m_resultCode; }
|
||||
PgResultError(const Pgsql::ErrorDetails &details);
|
||||
ResultCode getResultCode() const;
|
||||
const Pgsql::ErrorDetails& details() const;
|
||||
private:
|
||||
ResultCode m_resultCode;
|
||||
Pgsql::ErrorDetails m_details;
|
||||
};
|
||||
|
||||
class PgConnectionError: public PgResultError {
|
||||
public:
|
||||
PgConnectionError(const std::string &msg, std::string result_code)
|
||||
: PgResultError(msg, std::move(result_code))
|
||||
{}
|
||||
// class PgConnectionError: public PgException {
|
||||
// public:
|
||||
// PgConnectionError(const std::string &msg, std::string result_code)
|
||||
// : PgResultError(msg, std::move(result_code))
|
||||
// {}
|
||||
|
||||
private:
|
||||
// private:
|
||||
|
||||
};
|
||||
// };
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue