From 6466062cc8175eeae6f439bfc7e111fa2a1f9634 Mon Sep 17 00:00:00 2001 From: eelke Date: Sun, 10 Dec 2017 10:35:46 +0100 Subject: [PATCH] pg_classes can be loaded now, used in TablesTableModel for overview of tables in database. --- pglab/DatabasesTableModel.cpp | 6 +- pglab/DatabasesTableModel.h | 6 +- pglab/OpenDatabase.cpp | 6 +- pglab/OpenDatabase.h | 6 +- pglab/PgAuthIdContainer.cpp | 2 +- pglab/PgClass.cpp | 49 +++++- pglab/PgClass.h | 57 +++++-- pglab/PgClassContainer.cpp | 33 ++++ pglab/PgClassContainer.h | 24 +++ pglab/PgContainer.h | 6 +- pglab/PgDatabaseCatalog.cpp | 151 ++++++++++++++++++ ...atabaseCatalogue.h => PgDatabaseCatalog.h} | 24 +-- pglab/PgDatabaseCatalogue.cpp | 114 ------------- pglab/PgDatabaseContainer.cpp | 14 -- pglab/PgDatabaseContainer.h | 1 - pglab/QueryParamListController.cpp | 2 +- pglab/QueryTab.cpp | 2 +- pglab/ServerWindow.cpp | 2 +- pglab/TablesTableModel.cpp | 121 ++++++++++++++ pglab/TablesTableModel.h | 46 ++++++ pglab/pglab.pro | 12 +- pgsql/Pgsql_Value.cpp | 11 ++ pgsql/Pgsql_Value.h | 2 + 23 files changed, 524 insertions(+), 173 deletions(-) create mode 100644 pglab/PgClassContainer.cpp create mode 100644 pglab/PgClassContainer.h create mode 100644 pglab/PgDatabaseCatalog.cpp rename pglab/{PgDatabaseCatalogue.h => PgDatabaseCatalog.h} (58%) delete mode 100644 pglab/PgDatabaseCatalogue.cpp create mode 100644 pglab/TablesTableModel.cpp create mode 100644 pglab/TablesTableModel.h diff --git a/pglab/DatabasesTableModel.cpp b/pglab/DatabasesTableModel.cpp index 61ffa86..2cc3e5b 100644 --- a/pglab/DatabasesTableModel.cpp +++ b/pglab/DatabasesTableModel.cpp @@ -1,5 +1,5 @@ #include "DatabasesTableModel.h" -#include "PgDatabaseCatalogue.h" +#include "PgDatabaseCatalog.h" #include "PgDatabaseContainer.h" #include "PgAuthIdContainer.h" #include "ResultTableModelUtil.h" @@ -11,7 +11,7 @@ DatabasesTableModel::DatabasesTableModel(QObject *parent) { } -void DatabasesTableModel::setDatabaseList(std::shared_ptr cat) +void DatabasesTableModel::setDatabaseList(std::shared_ptr cat) { beginResetModel(); m_catalog = cat; @@ -115,7 +115,7 @@ QVariant DatabasesTableModel::getData(const QModelIndex &index) const v = db.name; break; case DbaCol: - v = getRoleDisplayString(m_catalog, db.dba); + v = getRoleDisplayString(*m_catalog, db.dba); break; case EncodingCol: // todo lookup encoding name diff --git a/pglab/DatabasesTableModel.h b/pglab/DatabasesTableModel.h index 38ce8df..a19c9e1 100644 --- a/pglab/DatabasesTableModel.h +++ b/pglab/DatabasesTableModel.h @@ -5,7 +5,7 @@ #include class PgDatabaseContainer; -class PgDatabaseCatalogue; +class PgDatabaseCatalog; /** Class for displaying the list of databases of a server in a QTableView * @@ -23,7 +23,7 @@ public: explicit DatabasesTableModel(QObject *parent); - void setDatabaseList(std::shared_ptr cat); + void setDatabaseList(std::shared_ptr cat); // Header: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; @@ -36,7 +36,7 @@ public: virtual QVariant getData(const QModelIndex &index) const override; private: - std::shared_ptr m_catalog; + std::shared_ptr m_catalog; std::shared_ptr m_databases; }; diff --git a/pglab/OpenDatabase.cpp b/pglab/OpenDatabase.cpp index f6fac02..30dc611 100644 --- a/pglab/OpenDatabase.cpp +++ b/pglab/OpenDatabase.cpp @@ -1,5 +1,5 @@ #include "OpenDatabase.h" -#include "PgDatabaseCatalogue.h" +#include "PgDatabaseCatalog.h" #include "Pgsql_Connection.h" #include "TypeSelectionItemModel.h" @@ -19,7 +19,7 @@ Expected OpenDatabase::createOpenDatabase(const ConnectionConfig OpenDatabase::OpenDatabase(const ConnectionConfig& cfg, QObject *parent) : QObject(parent) , m_config(cfg) - , m_catalogue(std::make_shared()) + , m_catalogue(std::make_shared()) { } @@ -39,7 +39,7 @@ bool OpenDatabase::Init() return false; } -std::shared_ptr OpenDatabase::catalogue() +std::shared_ptr OpenDatabase::catalogue() { return m_catalogue; } diff --git a/pglab/OpenDatabase.h b/pglab/OpenDatabase.h index 919c9d5..d2b43db 100644 --- a/pglab/OpenDatabase.h +++ b/pglab/OpenDatabase.h @@ -6,7 +6,7 @@ #include "Expected.h" #include -class PgDatabaseCatalogue; +class PgDatabaseCatalog; class TypeSelectionItemModel; /** Instances of this class represent a single database on which atleast one @@ -22,7 +22,7 @@ public: OpenDatabase& operator=(const OpenDatabase &) = delete; ~OpenDatabase(); - std::shared_ptr catalogue(); + std::shared_ptr catalogue(); TypeSelectionItemModel* typeSelectionModel(); signals: @@ -30,7 +30,7 @@ public slots: private: ConnectionConfig m_config; - std::shared_ptr m_catalogue; + std::shared_ptr m_catalogue; TypeSelectionItemModel *m_typeSelectionModel = nullptr; diff --git a/pglab/PgAuthIdContainer.cpp b/pglab/PgAuthIdContainer.cpp index 8ab9626..cdeebbe 100644 --- a/pglab/PgAuthIdContainer.cpp +++ b/pglab/PgAuthIdContainer.cpp @@ -1,6 +1,6 @@ #include "PgAuthIdContainer.h" #include "Pgsql_Connection.h" -#include "PgDatabaseCatalogue.h" +#include "PgDatabaseCatalog.h" std::string PgAuthIdContainer::getLoadQuery() const { diff --git a/pglab/PgClass.cpp b/pglab/PgClass.cpp index c4d74ed..3be7f23 100644 --- a/pglab/PgClass.cpp +++ b/pglab/PgClass.cpp @@ -1,3 +1,50 @@ #include "PgClass.h" -PgClass::PgClass() = default; +void operator<<(RelPersistence &s, const Pgsql::Value &v) +{ + //s = static_cast(v); + const char *c = v.c_str(); + switch (*c) { + case 'p': + s = RelPersistence::Permanent; + break; + case 'u': + s = RelPersistence::Unlogged; + break; + case 't': + s = RelPersistence::Temporary; + break; + } +} + +void operator<<(RelKind &s, const Pgsql::Value &v) +{ + //s = static_cast(v); + const char *c = v.c_str(); + switch (*c) { + case 'r': + s = RelKind::Table; + break; + case 'i': + s = RelKind::Index; + break; + case 'S': + s = RelKind::Sequence; + break; + case 'v': + s = RelKind::View; + break; + case 'm': + s = RelKind::MaterializedView; + break; + case 'c': + s = RelKind::Composite; + break; + case 't': + s = RelKind::Toast; + break; + case 'f': + s = RelKind::ForeignTable; + break; + } +} diff --git a/pglab/PgClass.h b/pglab/PgClass.h index 05f0c64..5c4c9e4 100644 --- a/pglab/PgClass.h +++ b/pglab/PgClass.h @@ -1,25 +1,60 @@ #ifndef PGCLASS_H #define PGCLASS_H +#include "Pgsql_Value.h" #include #include +enum class RelPersistence { + Permanent, // p + Unlogged, // u + Temporary // t +}; + +void operator<<(RelPersistence &s, const Pgsql::Value &v); + +enum class RelKind { + Table, // r + Index, // i + Sequence, // S + View, // v + MaterializedView, // m + Composite, // c + Toast, // t + ForeignTable // f +}; + +void operator<<(RelKind &s, const Pgsql::Value &v); + class PgClass { public: - PgClass(); Oid oid = InvalidOid; - QString relname; + QString name; Oid relnamespace = InvalidOid; - Oid reltype = InvalidOid; - Oid reloftype = InvalidOid; - Oid relowner = InvalidOid; - Oid relam = InvalidOid; - Oid relfilename = InvalidOid; - Oid reltablespace = InvalidOid; - int relpages_est = 0; - float reltuples_est = 0; - int relallvisible = 0; + Oid type = InvalidOid; + Oid oftype = InvalidOid; + Oid owner = InvalidOid; + Oid am = InvalidOid; + Oid filenode = InvalidOid; + Oid tablespace = InvalidOid; + int pages_est = 0; + float tuples_est = 0.0f; + Oid toastrelid = InvalidOid; + bool isshared = false; + RelPersistence persistence; + RelKind kind; + bool hasoids = false; + bool ispopulated; + int frozenxid; + int minmxid; + QString acl; + QString options; + + bool operator==(Oid _oid) const { return oid == _oid; } + bool operator==(const QString &n) const { return name == n; } + bool operator<(Oid _oid) const { return oid < _oid; } + bool operator<(const PgClass &rhs) const { return oid < rhs.oid; } }; diff --git a/pglab/PgClassContainer.cpp b/pglab/PgClassContainer.cpp new file mode 100644 index 0000000..bc21080 --- /dev/null +++ b/pglab/PgClassContainer.cpp @@ -0,0 +1,33 @@ +#include "PgClassContainer.h" +#include "Pgsql_Connection.h" +#include "Pgsql_Col.h" + +std::string PgClassContainer::getLoadQuery() const +{ + return "SELECT oid, relname, relnamespace, reltype, reloftype, " + " relowner, relam, relfilenode, reltablespace, relpages, " + " reltuples, reltoastrelid, relisshared, relpersistence, " + " relkind, relhasoids, relispopulated, relfrozenxid, relrelminmxid " + " relacl, reloptions \n" + "FROM pg_catalog.pg_class"; +} + +void PgClassContainer::load(const Pgsql::Result &res) +{ + const int n_rows = res.rows(); + m_container.clear(); + m_container.reserve(n_rows); + for (auto row : res) { + Pgsql::Col col(row); + PgClass v; + col >> v.oid >> v.name >> v.relnamespace >> v.type >> v.oftype + >> v.owner >> v.am >> v.filenode >> v.tablespace >> v.pages_est + >> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence + >> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid + >> v.acl >> v.options; + + m_container.push_back(v); + } + std::sort(m_container.begin(), m_container.end()); + +} diff --git a/pglab/PgClassContainer.h b/pglab/PgClassContainer.h new file mode 100644 index 0000000..60b5f37 --- /dev/null +++ b/pglab/PgClassContainer.h @@ -0,0 +1,24 @@ +#ifndef PGCLASSCONTAINER_H +#define PGCLASSCONTAINER_H + +#include "PgContainer.h" +#include "PgClass.h" + +namespace Pgsql { + + class Result; + +} + + +class PgClassContainer: public PgContainer { +public: + using PgContainer::PgContainer; + + virtual std::string getLoadQuery() const override; + virtual void load(const Pgsql::Result &res) override; + +private: +}; + +#endif // PGCLASSCONTAINER_H diff --git a/pglab/PgContainer.h b/pglab/PgContainer.h index 201dfa4..6acece7 100644 --- a/pglab/PgContainer.h +++ b/pglab/PgContainer.h @@ -8,7 +8,7 @@ #include -class PgDatabaseCatalogue; +class PgDatabaseCatalog; class IPgContainter { public: @@ -23,7 +23,7 @@ class PgContainer: public IPgContainter { public: using t_Container = std::vector; ///< Do not assume it will stay a vector only expect bidirectional access - explicit PgContainer(std::weak_ptr cat) + explicit PgContainer(std::weak_ptr cat) : m_catalogue(cat) {} @@ -72,7 +72,7 @@ public: return m_container.at(idx); } protected: - std::weak_ptr m_catalogue; + std::weak_ptr m_catalogue; t_Container m_container; private: T m_invalidInstance; diff --git a/pglab/PgDatabaseCatalog.cpp b/pglab/PgDatabaseCatalog.cpp new file mode 100644 index 0000000..339e30e --- /dev/null +++ b/pglab/PgDatabaseCatalog.cpp @@ -0,0 +1,151 @@ +#include "PgDatabaseCatalog.h" +#include "PgTypeContainer.h" +#include "PgDatabaseContainer.h" +#include "PgAuthIdContainer.h" +#include "PgClassContainer.h" +#include "Pgsql_Connection.h" + + +QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid) +{ + QString name; + auto auth_ids = cat.authIds(); + if (auth_ids) { + const PgAuthId& auth_id = auth_ids->getByOid(oid); + if (auth_id.valid()) { + name = auth_id.name; + } + } + return name; +} + +QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid) +{ + QString name = getRoleNameFromOid(cat, oid); + return QString("%1 (%2)").arg(name).arg(oid); +} + +QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid) +{ + //QString name; +// auto c = cat.(); +// if (auth_ids) { +// const PgAuthId& auth_id = auth_ids->getByOid(oid); +// if (auth_id.valid()) { +// name = auth_id.name; +// } +// } + //return name; + // TODO load list and lookup name + return QString("ns %1").arg(oid); + +} + +QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid) +{ + // TODO load list and lookup name + return QString("ts %1").arg(oid); +} + + +PgDatabaseCatalog::PgDatabaseCatalog() +{ +} + +PgDatabaseCatalog::~PgDatabaseCatalog() +{ +} + +void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn) +{ + loadTypes(conn); + loadDatabases(conn); + loadAuthIds(conn); + loadClasses(conn); +} + +void PgDatabaseCatalog::loadInfo(Pgsql::Connection &conn) +{ + Pgsql::Result r = conn.query("SHOW server_version_num"); + if (r && r.resultStatus() == PGRES_TUPLES_OK) + if (r.rows() == 1) + m_serverVersion << r.get(0, 0); + + r = conn.query("SELECT version()"); + if (r && r.resultStatus() == PGRES_TUPLES_OK) + if (r.rows() == 1) + m_serverVersionString = r.get(0, 0).asQString(); +} + +void load(Pgsql::Connection &conn, IPgContainter &pg_cont) +{ + std::string q = pg_cont.getLoadQuery(); + Pgsql::Result result = conn.query(q.c_str()); + if (result && result.resultStatus() == PGRES_TUPLES_OK) + pg_cont.load(result); + else + throw std::runtime_error("Query failed"); + +} + +void PgDatabaseCatalog::loadTypes(Pgsql::Connection &conn) +{ + if (!m_types) + m_types = std::make_shared(shared_from_this()); + + load(conn, *m_types); +} + +void PgDatabaseCatalog::loadDatabases(Pgsql::Connection &conn) +{ + if (!m_databases) + m_databases = std::make_shared(shared_from_this()); + + load(conn, *m_databases); +} + +void PgDatabaseCatalog::loadAuthIds(Pgsql::Connection &conn) +{ + if (!m_authIds) + m_authIds = std::make_shared(shared_from_this()); + + load(conn, *m_authIds); +} + +void PgDatabaseCatalog::loadClasses(Pgsql::Connection &conn) +{ + if (!m_classes) + m_classes = std::make_shared(shared_from_this()); + + load(conn, *m_classes); +} + +const QString& PgDatabaseCatalog::serverVersionString() const +{ + return m_serverVersionString; +} + +int PgDatabaseCatalog::serverVersion() const +{ + return m_serverVersion; +} + +std::shared_ptr PgDatabaseCatalog::types() const +{ + return m_types; +} + +std::shared_ptr PgDatabaseCatalog::databases() const +{ + return m_databases; +} + +std::shared_ptr PgDatabaseCatalog::authIds() const +{ + return m_authIds; +} + +std::shared_ptr PgDatabaseCatalog::classes() const +{ + return m_classes; +} diff --git a/pglab/PgDatabaseCatalogue.h b/pglab/PgDatabaseCatalog.h similarity index 58% rename from pglab/PgDatabaseCatalogue.h rename to pglab/PgDatabaseCatalog.h index 5d17792..cdf80b7 100644 --- a/pglab/PgDatabaseCatalogue.h +++ b/pglab/PgDatabaseCatalog.h @@ -12,17 +12,18 @@ namespace Pgsql { } -class PgTypeContainer; -class PgDatabaseContainer; class PgAuthIdContainer; +class PgClassContainer; +class PgDatabaseContainer; +class PgTypeContainer; -class PgDatabaseCatalogue: public std::enable_shared_from_this { +class PgDatabaseCatalog: public std::enable_shared_from_this { public: - PgDatabaseCatalogue(); - PgDatabaseCatalogue(const PgDatabaseCatalogue&) = delete; - PgDatabaseCatalogue& operator = (const PgDatabaseCatalogue&) = delete; + PgDatabaseCatalog(); + PgDatabaseCatalog(const PgDatabaseCatalog&) = delete; + PgDatabaseCatalog& operator = (const PgDatabaseCatalog&) = delete; - ~PgDatabaseCatalogue(); + ~PgDatabaseCatalog(); void loadAll(Pgsql::Connection &conn); @@ -30,6 +31,7 @@ public: void loadTypes(Pgsql::Connection &conn); void loadDatabases(Pgsql::Connection &conn); void loadAuthIds(Pgsql::Connection &conn); + void loadClasses(Pgsql::Connection &conn); const QString& serverVersionString() const; int serverVersion() const; @@ -37,16 +39,20 @@ public: std::shared_ptr types() const; std::shared_ptr databases() const; std::shared_ptr authIds() const; + std::shared_ptr classes() const; private: QString m_serverVersionString; int m_serverVersion; std::shared_ptr m_types; std::shared_ptr m_databases; std::shared_ptr m_authIds; + std::shared_ptr m_classes; }; -QString getRoleNameFromOid(std::shared_ptr cat, Oid oid); -QString getRoleDisplayString(std::shared_ptr cat, Oid oid); +QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid); +QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid); +QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid); +QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid); #endif // PGSQLDATABASECATALOGUE_H diff --git a/pglab/PgDatabaseCatalogue.cpp b/pglab/PgDatabaseCatalogue.cpp deleted file mode 100644 index 3777f39..0000000 --- a/pglab/PgDatabaseCatalogue.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "PgDatabaseCatalogue.h" -#include "PgTypeContainer.h" -#include "PgDatabaseContainer.h" -#include "PgAuthIdContainer.h" -#include "Pgsql_Connection.h" - - -QString getRoleNameFromOid(std::shared_ptr cat, Oid oid) -{ - QString name; - auto auth_ids = cat->authIds(); - if (auth_ids) { - const PgAuthId& auth_id = auth_ids->getByOid(oid); - if (auth_id.valid()) { - name = auth_id.name; - } - } - return name; -} - -QString getRoleDisplayString(std::shared_ptr cat, Oid oid) -{ - QString name = getRoleNameFromOid(cat, oid); - return QString("%1 (%2)").arg(name).arg(oid); -} - - -PgDatabaseCatalogue::PgDatabaseCatalogue() -{ -} - -PgDatabaseCatalogue::~PgDatabaseCatalogue() -{ -} - -void PgDatabaseCatalogue::loadAll(Pgsql::Connection &conn) -{ - loadTypes(conn); - loadDatabases(conn); - loadAuthIds(conn); -} - -void PgDatabaseCatalogue::loadInfo(Pgsql::Connection &conn) -{ - Pgsql::Result r = conn.query("SHOW server_version_num"); - if (r && r.resultStatus() == PGRES_TUPLES_OK) - if (r.rows() == 1) - m_serverVersion << r.get(0, 0); - - r = conn.query("SELECT version()"); - if (r && r.resultStatus() == PGRES_TUPLES_OK) - if (r.rows() == 1) - m_serverVersionString = r.get(0, 0).asQString(); -} - -void load(Pgsql::Connection &conn, IPgContainter &pg_cont) -{ - std::string q = pg_cont.getLoadQuery(); - Pgsql::Result result = conn.query(q.c_str()); - if (result && result.resultStatus() == PGRES_TUPLES_OK) - pg_cont.load(result); - else - throw std::runtime_error("Query failed"); - -} - -void PgDatabaseCatalogue::loadTypes(Pgsql::Connection &conn) -{ - if (!m_types) - m_types = std::make_shared(shared_from_this()); - - load(conn, *m_types); -} - -void PgDatabaseCatalogue::loadDatabases(Pgsql::Connection &conn) -{ - if (!m_databases) - m_databases = std::make_shared(shared_from_this()); - - load(conn, *m_databases); -} - -void PgDatabaseCatalogue::loadAuthIds(Pgsql::Connection &conn) -{ - if (!m_authIds) - m_authIds = std::make_shared(shared_from_this()); - - load(conn, *m_authIds); -} - -const QString& PgDatabaseCatalogue::serverVersionString() const -{ - return m_serverVersionString; -} - -int PgDatabaseCatalogue::serverVersion() const -{ - return m_serverVersion; -} - -std::shared_ptr PgDatabaseCatalogue::types() const -{ - return m_types; -} - -std::shared_ptr PgDatabaseCatalogue::databases() const -{ - return m_databases; -} - -std::shared_ptr PgDatabaseCatalogue::authIds() const -{ - return m_authIds; -} diff --git a/pglab/PgDatabaseContainer.cpp b/pglab/PgDatabaseContainer.cpp index 653c4f2..30da8b0 100644 --- a/pglab/PgDatabaseContainer.cpp +++ b/pglab/PgDatabaseContainer.cpp @@ -2,9 +2,6 @@ #include "Pgsql_Connection.h" #include "Pgsql_Col.h" -//PgDatabaseContainer::PgDatabaseContainer(PgDatabaseCatalogue *cat) -// : PgContainer(cat) -//{} std::string PgDatabaseContainer::getLoadQuery() const { @@ -20,17 +17,6 @@ void PgDatabaseContainer::load(const Pgsql::Result &res) for (auto row : res) { Pgsql::Col col(row); PgDatabase v; -// v.oid << row.get(0); // InvalidOid; -// v.name << row.get(1); -// v.dba << row.get(2); // owner? -// v.encoding << row.get(3); -// v.collate << row.get(4); -// v.ctype << row.get(5); -// v.isTemplate << row.get(6); -// v.allowConn << row.get(7); -// v.connLimit << row.get(8); -// v.tablespace << row.get(9); -// v.acl << row.get(10); col >> v.oid >> v.name >> v.dba >> v.encoding >> v.collate >> v.ctype >> v.isTemplate >> v.allowConn >> v.connLimit >> v.tablespace >> v.acl; m_container.push_back(v); diff --git a/pglab/PgDatabaseContainer.h b/pglab/PgDatabaseContainer.h index d1f41d1..2cf856a 100644 --- a/pglab/PgDatabaseContainer.h +++ b/pglab/PgDatabaseContainer.h @@ -1,7 +1,6 @@ #ifndef PGDATABASECONTAINER_H #define PGDATABASECONTAINER_H -#include #include "PgContainer.h" #include "PgDatabase.h" diff --git a/pglab/QueryParamListController.cpp b/pglab/QueryParamListController.cpp index 0906c80..e3a0263 100644 --- a/pglab/QueryParamListController.cpp +++ b/pglab/QueryParamListController.cpp @@ -1,6 +1,6 @@ #include "QueryParamListController.h" #include "OpenDatabase.h" -#include "PgDatabaseCatalogue.h" +#include "PgDatabaseCatalog.h" #include "PgTypeContainer.h" #include diff --git a/pglab/QueryTab.cpp b/pglab/QueryTab.cpp index 35547db..537c8cd 100644 --- a/pglab/QueryTab.cpp +++ b/pglab/QueryTab.cpp @@ -15,7 +15,7 @@ #include "json/json.h" #include "MainWindow.h" #include "OpenDatabase.h" -#include "PgDatabaseCatalogue.h" +#include "PgDatabaseCatalog.h" #include "QueryParamListController.h" #include "util.h" #include "GlobalIoService.h" diff --git a/pglab/ServerWindow.cpp b/pglab/ServerWindow.cpp index 0d2f6cb..f8862a2 100644 --- a/pglab/ServerWindow.cpp +++ b/pglab/ServerWindow.cpp @@ -3,7 +3,7 @@ #include "OpenDatabase.h" #include "DatabasesTableModel.h" #include "RolesTableModel.h" -#include "PgDatabaseCatalogue.h" +#include "PgDatabaseCatalog.h" ServerWindow::ServerWindow(MasterController *master, QWidget *parent) : ASyncWindow(parent) diff --git a/pglab/TablesTableModel.cpp b/pglab/TablesTableModel.cpp new file mode 100644 index 0000000..c524f9d --- /dev/null +++ b/pglab/TablesTableModel.cpp @@ -0,0 +1,121 @@ +#include "TablesTableModel.h" +#include "PgDatabaseCatalog.h" +#include "PgClass.h" +#include "PgClassContainer.h" +#include "Pgsql_declare.h" + +TablesTableModel::TablesTableModel(QObject *parent) + : BaseTableModel(parent) +{ + +} + +void TablesTableModel::setCatalog(std::shared_ptr cat) +{ + beginResetModel(); + m_catalog = cat; + + // Later afscheiden naar filter functie + auto classes = cat->classes(); + + // How many? + int n = 0; + for (const auto &e : *classes) + if (e.kind == RelKind::Table) ++n; + + m_tables.clear(); + m_tables.reserve(n); // reserve space + for (const auto &e : *classes) { + if (e.kind == RelKind::Table) { + m_tables.push_back(e); + } + } + + endResetModel(); +} + + +QVariant TablesTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + QVariant v; + if (orientation == Qt::Horizontal) { + if (role == Qt::DisplayRole) { + switch (section) { + case NameCol: + v = tr("Name"); + break; + case OwnerCol: + v = tr("Owner"); + break; + case TablespaceCol: + v = tr("Tablespace"); + break; + case OptionsCol: + v = tr("Options"); + break; + case AclCol: + v = tr("ACL"); + break; + } + } + } + return v; +} + +// Basic functionality: +int TablesTableModel::rowCount(const QModelIndex &) const +{ + return m_tables.size(); +} + +int TablesTableModel::columnCount(const QModelIndex &) const +{ + return colCount; +} + +Oid TablesTableModel::getType(int column) const +{ + Oid oid; + switch (column) { + case TablespaceCol: + case OwnerCol: + case NameCol: + case OptionsCol: + case AclCol: + default: + oid = Pgsql::VARCHAROID; + } + return oid; +} + +QVariant TablesTableModel::getData(const QModelIndex &index) const +{ + QVariant v; + const auto &t = m_tables[index.row()]; + switch (index.column()) { + case NameCol: + v = formatTableName(t); + break; + case OwnerCol: + v = getRoleDisplayString(*m_catalog, t.owner); + break; + case TablespaceCol: + v = getTablespaceDisplayString(*m_catalog, t.tablespace); + break; + case OptionsCol: + v = t.options; + break; + case AclCol: + v = t.acl; + break; + } + + return v; +} + +QString TablesTableModel::formatTableName(const PgClass &cls) const +{ + const char * format = "%2 (%1)"; + QString ns_name = getNamespaceDisplayString(*m_catalog, cls.relnamespace); + return QString(format).arg(ns_name).arg(cls.name); +} diff --git a/pglab/TablesTableModel.h b/pglab/TablesTableModel.h new file mode 100644 index 0000000..336ed68 --- /dev/null +++ b/pglab/TablesTableModel.h @@ -0,0 +1,46 @@ +#ifndef TABLESTABLEMODEL_H +#define TABLESTABLEMODEL_H + +#include "BaseTableModel.h" +#include +#include + +class PgClass; +class PgDatabaseCatalog; + +class TablesTableModel: public BaseTableModel +{ +public: + enum e_Columns : int { + NameCol, ///< either table, ns.table or table (ns) depending on settings/filters + OwnerCol, + TablespaceCol, + OptionsCol, + AclCol, + colCount }; + + TablesTableModel(QObject *parent); + + void setCatalog(std::shared_ptr cat); + + // Header: + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + + // Basic functionality: + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + +protected: + virtual Oid getType(int column) const override; + virtual QVariant getData(const QModelIndex &index) const override; + +private: + using t_Tables = std::vector; + + std::shared_ptr m_catalog; + t_Tables m_tables; + + QString formatTableName(const PgClass &cls) const; +}; + +#endif // TABLESTABLEMODEL_H diff --git a/pglab/pglab.pro b/pglab/pglab.pro index a485294..4765b73 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -42,7 +42,6 @@ SOURCES += main.cpp\ util.cpp \ DatabaseInspectorWidget.cpp \ PgType.cpp \ -PgDatabaseCatalogue.cpp \ PgTypeContainer.cpp \ TuplesResultWidget.cpp \ PgNamespace.cpp \ @@ -69,7 +68,10 @@ PgDatabaseCatalogue.cpp \ ResultTableModelUtil.cpp \ BaseTableModel.cpp \ QueryParamListController.cpp \ - TablesPage.cpp + TablesPage.cpp \ + PgClassContainer.cpp \ + TablesTableModel.cpp \ + PgDatabaseCatalog.cpp HEADERS += \ QueryResultModel.h \ @@ -85,7 +87,6 @@ HEADERS += \ util.h \ DatabaseInspectorWidget.h \ PgType.h \ -PgDatabaseCatalogue.h \ PgTypeContainer.h \ TuplesResultWidget.h \ PgNamespace.h \ @@ -113,7 +114,10 @@ PgDatabaseCatalogue.h \ ResultTableModelUtil.h \ BaseTableModel.h \ QueryParamListController.h \ - TablesPage.h + TablesPage.h \ + PgClassContainer.h \ + TablesTableModel.h \ + PgDatabaseCatalog.h FORMS += mainwindow.ui \ DatabaseWindow.ui \ diff --git a/pgsql/Pgsql_Value.cpp b/pgsql/Pgsql_Value.cpp index 26aaeb7..2bb88d6 100644 --- a/pgsql/Pgsql_Value.cpp +++ b/pgsql/Pgsql_Value.cpp @@ -70,6 +70,17 @@ Value::operator bool() const return std::strcmp(m_val, "t") == 0; } +Value::operator float() const +{ + return std::stof(m_val); +} + +Value::operator double() const +{ + return std::stod(m_val); +} + + bool Value::isString() const { return m_typ == CHAROID diff --git a/pgsql/Pgsql_Value.h b/pgsql/Pgsql_Value.h index ae06160..50a6a22 100644 --- a/pgsql/Pgsql_Value.h +++ b/pgsql/Pgsql_Value.h @@ -25,6 +25,8 @@ namespace Pgsql { operator Oid() const; operator long long() const; operator bool() const; + operator float() const; + operator double() const; bool isString() const;