Renamed PgsqlDatabaseCatalogue to PgDatabaseCatalogue so name is consistend

with other related classes.
This commit is contained in:
Eelke Klein 2017-08-26 11:44:40 +02:00
parent 52442a145d
commit 243f1c0a42
21 changed files with 491 additions and 61 deletions

5
BUILD
View file

@ -4,6 +4,7 @@ If it doesn't detect Qt CMAKE_PREFIX_PATH needs to be set
export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu/qt5/mkspecs/features/data/cmake
Dependencies:
- boost (asio, system, ???)
- Botan-2
- libpq
- Qt5
@ -11,3 +12,7 @@ Dependencies:
- jsoncpp (included)
On ubuntu
sudo apt install libpq-dev libboost1.63-all-dev

View file

@ -90,11 +90,11 @@ add_executable(pglab
pglab/PgAuthIdContainer.cpp
pglab/PgAuthId.cpp
pglab/PgClass.cpp
pglab/PgDatabaseCatalogue.cpp
pglab/PgDatabaseContainer.cpp
pglab/PgDatabase.cpp
pglab/PgNamespace.cpp
pglab/PgsqlConn.cpp
pglab/PgsqlDatabaseCatalogue.cpp
pglab/Pgsql_Params.cpp
pglab/Pgsql_Result.cpp
pglab/Pgsql_Row.cpp

View file

@ -170,7 +170,8 @@ void BackupDialog::on_btnStart_clicked()
{
ui->stdOutput->clear();
QString program = R"-(C:\Prog\bigsql\pg96\bin\pg_dump.exe)-";
//QString program = R"-(C:\Prog\bigsql\pg96\bin\pg_dump.exe)-";
QString program = "/usr/bin/pg_dump";
QStringList arguments;
setParams(arguments);
@ -228,11 +229,11 @@ void BackupDialog::on_btnStart_clicked()
// We use the systemEnvironment as a sane default. Then we let the connection overwrite all PG variables in it.
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
m_config.writeToEnvironment(env);
env.insert("SESSIONNAME", "Console");
//env.insert("SESSIONNAME", "Console");
auto p = new QProcess(this);
ConnectTo(p);
p->setProcessEnvironment(env);
#ifdef _WIN32
#ifdef WIN32
p->setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
{
args->flags |= CREATE_NEW_CONSOLE;

View file

@ -1,5 +1,5 @@
#include "DatabasesTableModel.h"
#include "PgsqlDatabaseCatalogue.h"
#include "DatabasesTableModel.h"
#include "PgDatabaseCatalogue.h"
#include "PgDatabaseContainer.h"
#include "PgAuthIdContainer.h"
@ -8,7 +8,7 @@ DatabasesTableModel::DatabasesTableModel(QObject *parent)
{
}
void DatabasesTableModel::setDatabaseList(const PgsqlDatabaseCatalogue* cat)
void DatabasesTableModel::setDatabaseList(const PgDatabaseCatalogue* cat)
{
beginResetModel();
m_catalog = cat;

View file

@ -1,10 +1,10 @@
#ifndef DATABASESTABLEMODEL_H
#ifndef DATABASESTABLEMODEL_H
#define DATABASESTABLEMODEL_H
#include <QAbstractTableModel>
class PgDatabaseContainer;
class PgsqlDatabaseCatalogue;
class PgDatabaseCatalogue;
/** Class for displaying the list of databases of a server in a QTableView
*
@ -22,7 +22,7 @@ public:
explicit DatabasesTableModel(QObject *parent);
void setDatabaseList(const PgsqlDatabaseCatalogue* cat);
void setDatabaseList(const PgDatabaseCatalogue* cat);
// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
@ -34,7 +34,7 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
private:
const PgsqlDatabaseCatalogue *m_catalog = nullptr;
const PgDatabaseCatalogue *m_catalog = nullptr;
const PgDatabaseContainer *m_databases = nullptr;
};

View file

@ -1,5 +1,5 @@
#include "OpenDatabase.h"
#include "PgsqlDatabaseCatalogue.h"
#include "OpenDatabase.h"
#include "PgDatabaseCatalogue.h"
#include "PgsqlConn.h"
#include "TypeSelectionItemModel.h"
@ -17,7 +17,7 @@ Expected<OpenDatabase*> OpenDatabase::createOpenDatabase(const ConnectionConfig
OpenDatabase::OpenDatabase(const ConnectionConfig& cfg, QObject *parent)
: QObject(parent)
, m_config(cfg)
, m_catalogue(new PgsqlDatabaseCatalogue)
, m_catalogue(new PgDatabaseCatalogue)
{
}
@ -37,7 +37,7 @@ bool OpenDatabase::Init()
return true;
}
PgsqlDatabaseCatalogue* OpenDatabase::catalogue()
PgDatabaseCatalogue* OpenDatabase::catalogue()
{
return m_catalogue;
}

View file

@ -1,11 +1,11 @@
#ifndef OPENDATABASE_H
#ifndef OPENDATABASE_H
#define OPENDATABASE_H
#include <QObject>
#include "ConnectionConfig.h"
#include "Expected.h"
class PgsqlDatabaseCatalogue;
class PgDatabaseCatalogue;
class TypeSelectionItemModel;
/** Instances of this class represent a single database on which atleast one
@ -21,7 +21,7 @@ public:
OpenDatabase& operator=(const OpenDatabase &) = delete;
~OpenDatabase();
PgsqlDatabaseCatalogue* catalogue();
PgDatabaseCatalogue* catalogue();
TypeSelectionItemModel* typeSelectionModel();
signals:
@ -29,7 +29,7 @@ public slots:
private:
ConnectionConfig m_config;
PgsqlDatabaseCatalogue *m_catalogue;
PgDatabaseCatalogue *m_catalogue;
TypeSelectionItemModel *m_typeSelectionModel = nullptr;

View file

@ -1,8 +1,8 @@
#include "PgAuthIdContainer.h"
#include "PgAuthIdContainer.h"
#include "PgsqlConn.h"
#include "PgsqlDatabaseCatalogue.h"
#include "PgDatabaseCatalogue.h"
PgAuthIdContainer::PgAuthIdContainer(PgsqlDatabaseCatalogue *cat)
PgAuthIdContainer::PgAuthIdContainer(PgDatabaseCatalogue *cat)
: PgContainer<PgAuthId>(cat)
{}

View file

@ -1,4 +1,4 @@
#ifndef PGAUTHIDCONTAINER_H
#ifndef PGAUTHIDCONTAINER_H
#define PGAUTHIDCONTAINER_H
#include <vector>
@ -14,7 +14,7 @@ namespace Pgsql {
class PgAuthIdContainer: public PgContainer<PgAuthId> {
public:
explicit PgAuthIdContainer(PgsqlDatabaseCatalogue *cat);
explicit PgAuthIdContainer(PgDatabaseCatalogue *cat);
std::string getLoadQuery() const;
void load(const Pgsql::Result &res);

View file

@ -1,18 +1,18 @@
#ifndef PGCONTAINER_H
#ifndef PGCONTAINER_H
#define PGCONTAINER_H
#include <QString>
#include <vector>
#include <libpq-fe.h>
class PgsqlDatabaseCatalogue;
class PgDatabaseCatalogue;
template<typename T>
class PgContainer {
public:
using t_Container = std::vector<T>; ///< Do not assume it will stay a vector only expect bidirectional access
explicit PgContainer(PgsqlDatabaseCatalogue *cat)
explicit PgContainer(PgDatabaseCatalogue *cat)
: m_catalogue(cat)
{}
@ -60,7 +60,7 @@ public:
return m_container.at(idx);
}
protected:
PgsqlDatabaseCatalogue *m_catalogue;
PgDatabaseCatalogue *m_catalogue;
t_Container m_container;
private:
T m_invalidInstance;

View file

@ -1,11 +1,11 @@
#include "PgsqlDatabaseCatalogue.h"
#include "PgDatabaseCatalogue.h"
#include "PgTypeContainer.h"
#include "PgDatabaseContainer.h"
#include "PgAuthIdContainer.h"
#include "PgsqlConn.h"
QString getRoleNameFromOid(const PgsqlDatabaseCatalogue *cat, Oid oid)
QString getRoleNameFromOid(const PgDatabaseCatalogue *cat, Oid oid)
{
QString name;
const PgAuthIdContainer *auth_ids = cat->authIds();
@ -18,23 +18,23 @@ QString getRoleNameFromOid(const PgsqlDatabaseCatalogue *cat, Oid oid)
return name;
}
PgsqlDatabaseCatalogue::PgsqlDatabaseCatalogue()
PgDatabaseCatalogue::PgDatabaseCatalogue()
{
}
PgsqlDatabaseCatalogue::~PgsqlDatabaseCatalogue()
PgDatabaseCatalogue::~PgDatabaseCatalogue()
{
delete m_types;
}
void PgsqlDatabaseCatalogue::loadAll(Pgsql::Connection &conn)
void PgDatabaseCatalogue::loadAll(Pgsql::Connection &conn)
{
loadTypes(conn);
loadDatabases(conn);
loadAuthIds(conn);
}
void PgsqlDatabaseCatalogue::loadInfo(Pgsql::Connection &conn)
void PgDatabaseCatalogue::loadInfo(Pgsql::Connection &conn)
{
Pgsql::Result r = conn.query("SHOW server_version_num");
if (r && r.resultStatus() == PGRES_TUPLES_OK)
@ -47,7 +47,7 @@ void PgsqlDatabaseCatalogue::loadInfo(Pgsql::Connection &conn)
m_serverVersionString = r.get(0, 0).asQString();
}
void PgsqlDatabaseCatalogue::loadTypes(Pgsql::Connection &conn)
void PgDatabaseCatalogue::loadTypes(Pgsql::Connection &conn)
{
if (m_types == nullptr)
m_types = new PgTypeContainer(this);
@ -61,7 +61,7 @@ void PgsqlDatabaseCatalogue::loadTypes(Pgsql::Connection &conn)
}
void PgsqlDatabaseCatalogue::loadDatabases(Pgsql::Connection &conn)
void PgDatabaseCatalogue::loadDatabases(Pgsql::Connection &conn)
{
if (m_databases == nullptr)
m_databases = new PgDatabaseContainer(this);
@ -75,7 +75,7 @@ void PgsqlDatabaseCatalogue::loadDatabases(Pgsql::Connection &conn)
throw std::runtime_error("Query failed");
}
void PgsqlDatabaseCatalogue::loadAuthIds(Pgsql::Connection &conn)
void PgDatabaseCatalogue::loadAuthIds(Pgsql::Connection &conn)
{
if (m_authIds == nullptr)
m_authIds = new PgAuthIdContainer(this);
@ -88,27 +88,27 @@ void PgsqlDatabaseCatalogue::loadAuthIds(Pgsql::Connection &conn)
throw std::runtime_error("Query failed");
}
const QString& PgsqlDatabaseCatalogue::serverVersionString() const
const QString& PgDatabaseCatalogue::serverVersionString() const
{
return m_serverVersionString;
}
int PgsqlDatabaseCatalogue::serverVersion() const
int PgDatabaseCatalogue::serverVersion() const
{
return m_serverVersion;
}
const PgTypeContainer* PgsqlDatabaseCatalogue::types() const
const PgTypeContainer* PgDatabaseCatalogue::types() const
{
return m_types;
}
const PgDatabaseContainer *PgsqlDatabaseCatalogue::databases() const
const PgDatabaseContainer *PgDatabaseCatalogue::databases() const
{
return m_databases;
}
const PgAuthIdContainer *PgsqlDatabaseCatalogue::authIds() const
const PgAuthIdContainer *PgDatabaseCatalogue::authIds() const
{
return m_authIds;
}

View file

@ -15,13 +15,13 @@ class PgTypeContainer;
class PgDatabaseContainer;
class PgAuthIdContainer;
class PgsqlDatabaseCatalogue {
class PgDatabaseCatalogue {
public:
PgsqlDatabaseCatalogue();
PgsqlDatabaseCatalogue(const PgsqlDatabaseCatalogue&) = delete;
PgsqlDatabaseCatalogue& operator = (const PgsqlDatabaseCatalogue&) = delete;
PgDatabaseCatalogue();
PgDatabaseCatalogue(const PgDatabaseCatalogue&) = delete;
PgDatabaseCatalogue& operator = (const PgDatabaseCatalogue&) = delete;
~PgsqlDatabaseCatalogue();
~PgDatabaseCatalogue();
void loadAll(Pgsql::Connection &conn);
@ -44,6 +44,6 @@ private:
PgAuthIdContainer *m_authIds = nullptr;
};
QString getRoleNameFromOid(const PgsqlDatabaseCatalogue *cat, Oid oid);
QString getRoleNameFromOid(const PgDatabaseCatalogue *cat, Oid oid);
#endif // PGSQLDATABASECATALOGUE_H

View file

@ -1,7 +1,7 @@
#include "PgDatabaseContainer.h"
#include "PgDatabaseContainer.h"
#include "PgsqlConn.h"
PgDatabaseContainer::PgDatabaseContainer(PgsqlDatabaseCatalogue *cat)
PgDatabaseContainer::PgDatabaseContainer(PgDatabaseCatalogue *cat)
: PgContainer<PgDatabase>(cat)
{}

View file

@ -1,4 +1,4 @@
#ifndef PGDATABASECONTAINER_H
#ifndef PGDATABASECONTAINER_H
#define PGDATABASECONTAINER_H
#include <vector>
@ -14,7 +14,7 @@ namespace Pgsql {
class PgDatabaseContainer: public PgContainer<PgDatabase> {
public:
explicit PgDatabaseContainer(PgsqlDatabaseCatalogue *cat);
explicit PgDatabaseContainer(PgDatabaseCatalogue *cat);
std::string getLoadQuery() const;
void load(const Pgsql::Result &res);

View file

@ -1,8 +1,8 @@
#include "PgTypeContainer.h"
#include "PgTypeContainer.h"
#include "PgsqlConn.h"
#include <algorithm>
PgTypeContainer::PgTypeContainer(PgsqlDatabaseCatalogue *cat)
PgTypeContainer::PgTypeContainer(PgDatabaseCatalogue *cat)
: PgContainer<PgType>(cat)
{}

View file

@ -1,4 +1,4 @@
#ifndef PGTYPECONTAINER_H
#ifndef PGTYPECONTAINER_H
#define PGTYPECONTAINER_H
#include <vector>
@ -15,7 +15,7 @@ class PgTypeContainer: public PgContainer<PgType> {
public:
// using t_Types = std::vector<PgType>; ///< Do not assume it will stay a vector only expect bidirectional access
explicit PgTypeContainer(PgsqlDatabaseCatalogue *cat);
explicit PgTypeContainer(PgDatabaseCatalogue *cat);
// t_Types::const_iterator begin() const { return m_types.begin(); }
// t_Types::const_iterator end() const { return m_types.end(); }

206
pglab/Pgsql_Connection.cpp Normal file
View file

@ -0,0 +1,206 @@
#include "PgsqlConn.h"
#include "Pgsql_declare.h"
#include "Pgsql_Params.h"
#include <stdexcept>
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()
{
close();
}
Connection::Connection(Connection &&rhs)
: conn(rhs.conn)
{
rhs.conn = nullptr;
}
Connection& Connection::operator=(Connection &&rhs)
{
close();
conn = rhs.conn;
rhs.conn = nullptr;
return *this;
}
void Connection::close()
{
if (conn) {
PQfinish(conn);
conn = nullptr;
}
}
Canceller Connection::getCancel()
{
Canceller c(PQgetCancel(conn));
return c;
}
bool Connection::connect(const char *params)
{
bool result = false;
conn = PQconnectdb(params);
if (conn) {
ConnStatusType status = PQstatus(conn);
result = (status == CONNECTION_OK);
}
return result;
}
bool Connection::connect(const char *const * keywords, const char* const * values, int expand_dbname)
{
bool result = false;
conn = PQconnectdbParams(keywords, values, expand_dbname);
if (conn) {
ConnStatusType status = PQstatus(conn);
result = (status == CONNECTION_OK);
}
return result;
}
bool Connection::connectStart(const char* params)
{
conn = PQconnectStart(params);
return conn != nullptr;
}
bool Connection::connectStart(const char * const *keywords,
const char * const *values)
{
conn = PQconnectStartParams(keywords, values, 0);
return conn != nullptr;
}
PostgresPollingStatusType Connection::connectPoll()
{
return PQconnectPoll(conn);
}
ConnStatusType Connection::status()
{
return PQstatus(conn);
}
int Connection::socket()
{
return PQsocket(conn);
}
std::string Connection::getErrorMessage() const
{
std::string result;
if (conn) {
result = PQerrorMessage(conn);
}
else {
result = "no connection";
}
return result;
}
Result Connection::query(const char * command)
{
PGresult *result = PQexec(conn, command);
return Result(result);
}
bool Connection::sendQuery(const char *query)
{
int res = PQsendQuery(conn, query);
return res == 1;
}
bool Connection::sendQueryParams(const char * command, const Params &params)
{
int res = PQsendQueryParams(conn, command, params.size(), params.types(),
params.values(), params.lengths(), params.formats(),
0); // text format
return res == 1;
}
std::shared_ptr<Result> Connection::getResult()
{
PGresult *r = PQgetResult(conn);
if (r) {
return std::make_shared<Result>(r);
}
else {
return nullptr;
}
}
bool Connection::consumeInput()
{
int res = PQconsumeInput(conn);
return res == 1;
}
bool Connection::isBusy()
{
int res = PQisBusy(conn);
return res == 1;
}
void Connection::setNoticeReceiver(std::function<void(const PGresult *)> callback)
{
notifyReceiver = callback;
PQsetNoticeReceiver(conn,
Connection::notifyReceiveFunc
, reinterpret_cast<void*>(this));
}
void Connection::notifyReceiveFunc(void *arg, const PGresult *result)
{
Connection *c = reinterpret_cast<Connection *>(arg);
c->notifyReceiver(result);
}

217
pglab/Pgsql_Connection.h Normal file
View file

@ -0,0 +1,217 @@
#pragma once
#include <functional>
#include <string>
#include <libpq-fe.h>
#include <cassert>
#include <QString>
#include <vector>
#include <codecvt>
#include <memory>
#include <fmt/format.h>
#include "Pgsql_Result.h"
namespace Pgsql {
class Connection;
/*
This library has multiple layers.
Layer 1 delivers lowlevel C++ wrappers for the basic libpq functionality. Adding
automatic resource management.
*/
// class ConnectionParams {
// public:
// std::string host;
// std::string hostaddr;
// unsigned short port = 5432;
// std::string dbname;
// std::string user;
// std::string password;
// int connect_timeout = -1; ///< -1 omit (ie uses default)
// std::string application_name;
// };
class Result;
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.
*
* The class isolates the programmer from the worst C style parts
* of the libpq API but is mostly a very thin wrapper.
*/
class Connection {
public:
Connection();
~Connection();
Connection(const Connection &rhs) = delete;
Connection& operator=(const Connection &rhs) = delete;
Connection(Connection &&rhs);
Connection& operator=(Connection &&rhs);
// void connect(const ConnectionParams &params);
bool connect(const char *params);
bool connect(const QString &params)
{
return connect(params.toUtf8().data());
}
bool connect(const char *const * keywords, const char* const * values, int expand_dbname);
bool connectStart(const char *params);
bool connectStart(const std::string &params)
{
return connectStart(params.c_str());
}
bool connectStart(const QString &params)
{
return connectStart(params.toUtf8().data());
}
bool connectStart(const char * const *keywords,
const char * const *values);
PostgresPollingStatusType connectPoll();
ConnStatusType status();
int socket();
void close();
Canceller getCancel();
std::string getErrorMessage() const;
Result query(const char * command);
Result query(const QString &command)
{
return query(command.toUtf8().data());
}
bool sendQuery(const char * query);
bool sendQuery(const std::string &command)
{
return sendQuery(command.c_str());
}
bool sendQuery(const QString &command)
{
return sendQuery(command.toUtf8().data());
}
bool sendQueryParams(const char * command, const Params &params);
std::shared_ptr<Result> getResult();
bool consumeInput();
bool isBusy();
void setNoticeReceiver(std::function<void(const PGresult *)> callback);
private:
PGconn *conn = nullptr;
std::function<void(const PGresult *)> notifyReceiver;
static void notifyReceiveFunc(void *arg, const PGresult *result);
};
// class Field {
// public:
// std::string getName() const;
// private:
// //Tuples tuples;
// int field;
// //
// };
// class Tuples {
// public:
// int getRowCount() const;
// int getColCount() const;
// Field getField(const std::string &fname);
// Field getField(const int idx);
// class const_iterator {
// public:
// const_iterator& operator++();
// };
// void rewind();
// };
// class OkResult: public Result {
// public:
// /** If the result is a data result then returns an interface for processing this data.
// The returned interface remains valid as long as this OkResult exists.
// */
// Tuples* hasTuples();
// };
// class ErrorResult: public Result {
//
// };
// class ITransaction {
// public:
//
// Canceller Query(std::string query,
// std::function<void(OkResult)> on_success,
// std::function<void()> on_cancelled,
// std::function<void(ErrorResult)> on_error);
//
// Canceller Query(std::string query,
// std::function<void(OkResult)> on_success,
// std::function<void()> on_cancelled,
// std::function<void(ErrorResult)> on_error);
//
//
// void Rollback(
// std::function<void(OkResult)> on_success,
// std::function<void(ErrorResult)> on_error);
// void Commit(
// std::function<void(OkResult)> on_success,
// std::function<void()> on_cancelled,
// std::function<void(ErrorResult)> on_error);
//
// };
}

View file

@ -41,7 +41,8 @@ namespace Pgsql {
{
s = static_cast<T>(v);
}
} // end namespace Pgsql
#endif // PGSQL_VALUE_H

View file

@ -1,4 +1,4 @@
#include "QueryTab.h"
#include "QueryTab.h"
#include "ui_QueryTab.h"
#include "SqlSyntaxHighlighter.h"
@ -17,7 +17,7 @@
#include "MainWindow.h"
#include "OpenDatabase.h"
#include "PgTypeContainer.h"
#include "PgsqlDatabaseCatalogue.h"
#include "PgDatabaseCatalogue.h"
#include "util.h"
#include "GlobalIoService.h"

View file

@ -1,9 +1,9 @@
#include "ServerWindow.h"
#include "ServerWindow.h"
#include "ui_ServerWindow.h"
#include "OpenDatabase.h"
#include "DatabasesTableModel.h"
#include "RolesTableModel.h"
#include "PgsqlDatabaseCatalogue.h"
#include "PgDatabaseCatalogue.h"
ServerWindow::ServerWindow(MasterController *master, QWidget *parent)
: ASyncWindow(parent)