From 0cef5097717e910665d1184dbcc45a5a22eacdd9 Mon Sep 17 00:00:00 2001 From: eelke Date: Mon, 27 Aug 2018 21:14:57 +0200 Subject: [PATCH] Correct tablespace names are now shown in the list of tables. Slightly more complex then you may expect because the tablespace specified by the tables tends to be oid 0 which means the default tablespace is used. However this does not mean pg_default, it means the tablespace as defined as standard in the database definition. So we need to know what the current dbname is retrieve it's details from the catalog and retrieve that tablespace to know what to show for an oid of 0. --- pglablib/PgClass.h | 4 ++-- pglablib/PgClassContainer.cpp | 7 +++++-- pglablib/PgDatabaseCatalog.cpp | 21 ++++++++++++++++++--- pglablib/PgDatabaseCatalog.h | 6 ++++++ pglablib/PgDatabaseContainer.h | 1 - pglablib/PgTablespace.cpp | 4 ++++ pglablib/PgTablespace.h | 24 ++++++++++++++++++++++++ pglablib/PgTablespaceContainer.cpp | 25 +++++++++++++++++++++++++ pglablib/PgTablespaceContainer.h | 24 ++++++++++++++++++++++++ pglablib/pglablib.pro | 8 ++++++-- pgsql/Pgsql_Connection.cpp | 5 +++++ pgsql/Pgsql_Connection.h | 2 ++ pgsql/Pgsql_oids.h | 7 +++++++ 13 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 pglablib/PgTablespace.cpp create mode 100644 pglablib/PgTablespace.h create mode 100644 pglablib/PgTablespaceContainer.cpp create mode 100644 pglablib/PgTablespaceContainer.h diff --git a/pglablib/PgClass.h b/pglablib/PgClass.h index 82f86b0..6ee7984 100644 --- a/pglablib/PgClass.h +++ b/pglablib/PgClass.h @@ -51,8 +51,8 @@ public: bool ispopulated; int frozenxid; int minmxid; - QString acl; - QString options; + std::vector acl; + std::vector options; bool operator==(Oid _oid) const { return oid == _oid; } bool operator==(const QString &n) const { return name == n; } diff --git a/pglablib/PgClassContainer.cpp b/pglablib/PgClassContainer.cpp index 2accb33..701dc68 100644 --- a/pglablib/PgClassContainer.cpp +++ b/pglablib/PgClassContainer.cpp @@ -3,6 +3,7 @@ #include "Pgsql_Col.h" #include "PgDatabaseCatalog.h" #include "PgNamespaceContainer.h" +#include std::string PgClassContainer::getLoadQuery() const { @@ -21,8 +22,10 @@ PgClass PgClassContainer::loadElem(const Pgsql::Row &row) 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; + >> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid; + + col.getAsArray(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore); + col.getAsArray(std::back_inserter(v.options), Pgsql::NullHandling::Ignore); auto cat = m_catalogue.lock(); auto ns = cat->namespaces()->getByKey(v.relnamespace); diff --git a/pglablib/PgDatabaseCatalog.cpp b/pglablib/PgDatabaseCatalog.cpp index e2eff8b..007fa2b 100644 --- a/pglablib/PgDatabaseCatalog.cpp +++ b/pglablib/PgDatabaseCatalog.cpp @@ -9,6 +9,7 @@ #include "PgDatabaseContainer.h" #include "PgIndexContainer.h" #include "PgNamespaceContainer.h" +#include "PgTablespaceContainer.h" #include "PgTypeContainer.h" #include "Pgsql_Connection.h" #include "Pgsql_oids.h" @@ -36,7 +37,6 @@ QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid) { QString name = getRoleNameFromOid(cat, oid); return name; -// return QString("%1 (%2)").arg(name).arg(oid); } QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid) @@ -71,7 +71,12 @@ QString getIndexDisplayString(const PgDatabaseCatalog &cat, Oid oid) QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid) { // TODO load list and lookup name - return QString("ts %1").arg(oid); + if (oid == 0) { + auto dbname = cat.getDBName(); + oid = cat.databases()->getByName(dbname).tablespace; + } + auto ts = cat.tablespaces()->getByKey(oid); + return ts.name; } QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid, int32_t typmod) @@ -129,11 +134,14 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn, std::function progress_callback) { loadInfo(conn); - const int count = 10; + const int count = 11; int n = 0; if (progress_callback && !progress_callback(++n, count)) return; load2(m_namespaces, conn); + if (progress_callback && !progress_callback(++n, count)) + return; + load2(m_tablespaces, conn); if (progress_callback && !progress_callback(++n, count)) return; load2(m_classes, conn); // needs namespaces @@ -172,6 +180,8 @@ void PgDatabaseCatalog::loadInfo(Pgsql::Connection &conn) if (r && r.resultStatus() == PGRES_TUPLES_OK) if (r.rows() == 1) m_serverVersionString = r.get(0, 0).asQString(); + + m_dbName = conn.getDBName(); } void load(Pgsql::Connection &conn, IPgContainter &pg_cont) @@ -245,6 +255,11 @@ std::shared_ptr PgDatabaseCatalog::namespaces() cons return m_namespaces; } +std::shared_ptr PgDatabaseCatalog::tablespaces() const +{ + return m_tablespaces; +} + std::shared_ptr PgDatabaseCatalog::types() const { return m_types; diff --git a/pglablib/PgDatabaseCatalog.h b/pglablib/PgDatabaseCatalog.h index 1389322..ca1869c 100644 --- a/pglablib/PgDatabaseCatalog.h +++ b/pglablib/PgDatabaseCatalog.h @@ -21,6 +21,7 @@ class PgDatabaseContainer; class PgIndexContainer; class PgNamespaceContainer; class PgAmContainer; +class PgTablespaceContainer; class PgTypeContainer; class PgDatabaseCatalog: public std::enable_shared_from_this { @@ -37,6 +38,7 @@ public: const QString& serverVersionString() const; int serverVersion() const; + const QString& getDBName() const { return m_dbName; } std::shared_ptr attributes() const; std::shared_ptr authIds() const; @@ -46,10 +48,13 @@ public: std::shared_ptr indexes() const; std::shared_ptr ams() const; std::shared_ptr namespaces() const; + std::shared_ptr tablespaces() const; std::shared_ptr types() const; + private: QString m_serverVersionString; int m_serverVersion; + QString m_dbName; std::shared_ptr m_attributes; std::shared_ptr m_authIds; @@ -59,6 +64,7 @@ private: std::shared_ptr m_indexes; std::shared_ptr m_ams; std::shared_ptr m_namespaces; + std::shared_ptr m_tablespaces; std::shared_ptr m_types; template diff --git a/pglablib/PgDatabaseContainer.h b/pglablib/PgDatabaseContainer.h index 2cf856a..e7bcf1f 100644 --- a/pglablib/PgDatabaseContainer.h +++ b/pglablib/PgDatabaseContainer.h @@ -18,7 +18,6 @@ public: virtual std::string getLoadQuery() const override; virtual void load(const Pgsql::Result &res) override; - private: }; diff --git a/pglablib/PgTablespace.cpp b/pglablib/PgTablespace.cpp new file mode 100644 index 0000000..48709aa --- /dev/null +++ b/pglablib/PgTablespace.cpp @@ -0,0 +1,4 @@ +#include "PgTablespace.h" + +PgTablespace::PgTablespace() +{} diff --git a/pglablib/PgTablespace.h b/pglablib/PgTablespace.h new file mode 100644 index 0000000..cf50c64 --- /dev/null +++ b/pglablib/PgTablespace.h @@ -0,0 +1,24 @@ +#ifndef PGTABLESPACE_H +#define PGTABLESPACE_H + +#include +#include +#include + +class PgTablespace { +public: + Oid oid = InvalidOid; + QString name; + Oid owner = InvalidOid; + std::vector acl; + std::vector options; + + PgTablespace(); + + 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 PgTablespace &rhs) const { return oid < rhs.oid; } +}; + +#endif // PGTABLESPACE_H diff --git a/pglablib/PgTablespaceContainer.cpp b/pglablib/PgTablespaceContainer.cpp new file mode 100644 index 0000000..092056e --- /dev/null +++ b/pglablib/PgTablespaceContainer.cpp @@ -0,0 +1,25 @@ +#include "PgTablespaceContainer.h" +#include "Pgsql_Connection.h" +#include "Pgsql_Col.h" +#include "Pgsql_declare.h" +#include "PgDatabaseCatalog.h" +#include + +std::string PgTablespaceContainer::getLoadQuery() const +{ + return +R"__SQL__( +SELECT oid, spcname, spcowner, spcacl, spcoptions +FROM pg_tablespace +)__SQL__"; +} + +PgTablespace PgTablespaceContainer::loadElem(const Pgsql::Row &row) +{ + Pgsql::Col col(row); + PgTablespace v; + col >> v.oid >> v.name >> v.owner; + col.getAsArray(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore); + col.getAsArray(std::back_inserter(v.options), Pgsql::NullHandling::Ignore); + return v; +} diff --git a/pglablib/PgTablespaceContainer.h b/pglablib/PgTablespaceContainer.h new file mode 100644 index 0000000..5f427f4 --- /dev/null +++ b/pglablib/PgTablespaceContainer.h @@ -0,0 +1,24 @@ +#ifndef PGTABLESPACECONTAINER_H +#define PGTABLESPACECONTAINER_H + +#include "PgContainer.h" +#include "PgTablespace.h" + +namespace Pgsql { + + class Result; + +} + + +class PgTablespaceContainer: public PgContainer { +public: + using PgContainer::PgContainer; + + virtual std::string getLoadQuery() const override; +protected: + PgTablespace loadElem(const Pgsql::Row &row) override; +private: +}; + +#endif // PGTABLESPACECONTAINER_H diff --git a/pglablib/pglablib.pro b/pglablib/pglablib.pro index 3e33c70..8c4047c 100644 --- a/pglablib/pglablib.pro +++ b/pglablib/pglablib.pro @@ -55,7 +55,9 @@ SOURCES += \ QueryGenerator.cpp \ PgAm.cpp \ PgAmContainer.cpp \ - PgObject.cpp + PgObject.cpp \ + PgTablespace.cpp \ + PgTablespaceContainer.cpp HEADERS += \ Pglablib.h \ @@ -88,7 +90,9 @@ HEADERS += \ QueryGenerator.h \ PgAm.h \ PgAmContainer.h \ - PgObject.h + PgObject.h \ + PgTablespace.h \ + PgTablespaceContainer.h unix { target.path = /usr/lib diff --git a/pgsql/Pgsql_Connection.cpp b/pgsql/Pgsql_Connection.cpp index 728e18d..db22689 100644 --- a/pgsql/Pgsql_Connection.cpp +++ b/pgsql/Pgsql_Connection.cpp @@ -263,3 +263,8 @@ void Connection::notifyReceiveFunc(void *arg, const PGresult *result) Connection *c = reinterpret_cast(arg); c->notifyReceiver(result); } + +QString Connection::getDBName() const +{ + return QString::fromUtf8(PQdb(conn)); +} diff --git a/pgsql/Pgsql_Connection.h b/pgsql/Pgsql_Connection.h index c9fd189..bbe34de 100644 --- a/pgsql/Pgsql_Connection.h +++ b/pgsql/Pgsql_Connection.h @@ -124,6 +124,8 @@ namespace Pgsql { QString escapeLiteral(const QString &literal); std::string escapeIdentifier(const std::string_view &ident); QString escapeIdentifier(const QString &ident); + + QString getDBName() const; private: PGconn *conn = nullptr; std::function notifyReceiver; diff --git a/pgsql/Pgsql_oids.h b/pgsql/Pgsql_oids.h index 295ef5c..4be5687 100644 --- a/pgsql/Pgsql_oids.h +++ b/pgsql/Pgsql_oids.h @@ -177,6 +177,13 @@ namespace Pgsql { static Oid elem() { return timestamptz_oid; } static Oid array() { return timestamptz_array_oid; } }; + + template <> + class OidFor { + public: + static Oid elem() { return text_oid; } + static Oid array() { return text_array_oid; } + }; // template <> // class OidFor<> { // public: