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.
This commit is contained in:
eelke 2018-08-27 21:14:57 +02:00
parent 7630723b69
commit 0cef509771
13 changed files with 128 additions and 10 deletions

View file

@ -51,8 +51,8 @@ public:
bool ispopulated; bool ispopulated;
int frozenxid; int frozenxid;
int minmxid; int minmxid;
QString acl; std::vector<QString> acl;
QString options; std::vector<QString> options;
bool operator==(Oid _oid) const { return oid == _oid; } bool operator==(Oid _oid) const { return oid == _oid; }
bool operator==(const QString &n) const { return name == n; } bool operator==(const QString &n) const { return name == n; }

View file

@ -3,6 +3,7 @@
#include "Pgsql_Col.h" #include "Pgsql_Col.h"
#include "PgDatabaseCatalog.h" #include "PgDatabaseCatalog.h"
#include "PgNamespaceContainer.h" #include "PgNamespaceContainer.h"
#include <iterator>
std::string PgClassContainer::getLoadQuery() const 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 col >> v.oid >> v.name >> v.relnamespace >> v.type >> v.oftype
>> v.owner >> v.am >> v.filenode >> v.tablespace >> v.pages_est >> v.owner >> v.am >> v.filenode >> v.tablespace >> v.pages_est
>> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence >> v.tuples_est >> v.toastrelid >> v.isshared >> v.persistence
>> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid >> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid;
>> v.acl >> v.options;
col.getAsArray<QString>(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore);
col.getAsArray<QString>(std::back_inserter(v.options), Pgsql::NullHandling::Ignore);
auto cat = m_catalogue.lock(); auto cat = m_catalogue.lock();
auto ns = cat->namespaces()->getByKey(v.relnamespace); auto ns = cat->namespaces()->getByKey(v.relnamespace);

View file

@ -9,6 +9,7 @@
#include "PgDatabaseContainer.h" #include "PgDatabaseContainer.h"
#include "PgIndexContainer.h" #include "PgIndexContainer.h"
#include "PgNamespaceContainer.h" #include "PgNamespaceContainer.h"
#include "PgTablespaceContainer.h"
#include "PgTypeContainer.h" #include "PgTypeContainer.h"
#include "Pgsql_Connection.h" #include "Pgsql_Connection.h"
#include "Pgsql_oids.h" #include "Pgsql_oids.h"
@ -36,7 +37,6 @@ QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{ {
QString name = getRoleNameFromOid(cat, oid); QString name = getRoleNameFromOid(cat, oid);
return name; return name;
// return QString("%1 (%2)").arg(name).arg(oid);
} }
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid 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) QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{ {
// TODO load list and lookup name // 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) QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid, int32_t typmod)
@ -129,11 +134,14 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn,
std::function<bool(int, int)> progress_callback) std::function<bool(int, int)> progress_callback)
{ {
loadInfo(conn); loadInfo(conn);
const int count = 10; const int count = 11;
int n = 0; int n = 0;
if (progress_callback && !progress_callback(++n, count)) if (progress_callback && !progress_callback(++n, count))
return; return;
load2(m_namespaces, conn); load2(m_namespaces, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_tablespaces, conn);
if (progress_callback && !progress_callback(++n, count)) if (progress_callback && !progress_callback(++n, count))
return; return;
load2(m_classes, conn); // needs namespaces 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 && r.resultStatus() == PGRES_TUPLES_OK)
if (r.rows() == 1) if (r.rows() == 1)
m_serverVersionString = r.get(0, 0).asQString(); m_serverVersionString = r.get(0, 0).asQString();
m_dbName = conn.getDBName();
} }
void load(Pgsql::Connection &conn, IPgContainter &pg_cont) void load(Pgsql::Connection &conn, IPgContainter &pg_cont)
@ -245,6 +255,11 @@ std::shared_ptr<const PgNamespaceContainer> PgDatabaseCatalog::namespaces() cons
return m_namespaces; return m_namespaces;
} }
std::shared_ptr<const PgTablespaceContainer> PgDatabaseCatalog::tablespaces() const
{
return m_tablespaces;
}
std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const
{ {
return m_types; return m_types;

View file

@ -21,6 +21,7 @@ class PgDatabaseContainer;
class PgIndexContainer; class PgIndexContainer;
class PgNamespaceContainer; class PgNamespaceContainer;
class PgAmContainer; class PgAmContainer;
class PgTablespaceContainer;
class PgTypeContainer; class PgTypeContainer;
class PgDatabaseCatalog: public std::enable_shared_from_this<PgDatabaseCatalog> { class PgDatabaseCatalog: public std::enable_shared_from_this<PgDatabaseCatalog> {
@ -37,6 +38,7 @@ public:
const QString& serverVersionString() const; const QString& serverVersionString() const;
int serverVersion() const; int serverVersion() const;
const QString& getDBName() const { return m_dbName; }
std::shared_ptr<const PgAttributeContainer> attributes() const; std::shared_ptr<const PgAttributeContainer> attributes() const;
std::shared_ptr<const PgAuthIdContainer> authIds() const; std::shared_ptr<const PgAuthIdContainer> authIds() const;
@ -46,10 +48,13 @@ public:
std::shared_ptr<const PgIndexContainer> indexes() const; std::shared_ptr<const PgIndexContainer> indexes() const;
std::shared_ptr<const PgAmContainer> ams() const; std::shared_ptr<const PgAmContainer> ams() const;
std::shared_ptr<const PgNamespaceContainer> namespaces() const; std::shared_ptr<const PgNamespaceContainer> namespaces() const;
std::shared_ptr<const PgTablespaceContainer> tablespaces() const;
std::shared_ptr<const PgTypeContainer> types() const; std::shared_ptr<const PgTypeContainer> types() const;
private: private:
QString m_serverVersionString; QString m_serverVersionString;
int m_serverVersion; int m_serverVersion;
QString m_dbName;
std::shared_ptr<PgAttributeContainer> m_attributes; std::shared_ptr<PgAttributeContainer> m_attributes;
std::shared_ptr<PgAuthIdContainer> m_authIds; std::shared_ptr<PgAuthIdContainer> m_authIds;
@ -59,6 +64,7 @@ private:
std::shared_ptr<PgIndexContainer> m_indexes; std::shared_ptr<PgIndexContainer> m_indexes;
std::shared_ptr<PgAmContainer> m_ams; std::shared_ptr<PgAmContainer> m_ams;
std::shared_ptr<PgNamespaceContainer> m_namespaces; std::shared_ptr<PgNamespaceContainer> m_namespaces;
std::shared_ptr<PgTablespaceContainer> m_tablespaces;
std::shared_ptr<PgTypeContainer> m_types; std::shared_ptr<PgTypeContainer> m_types;
template <typename T> template <typename T>

View file

@ -18,7 +18,6 @@ public:
virtual std::string getLoadQuery() const override; virtual std::string getLoadQuery() const override;
virtual void load(const Pgsql::Result &res) override; virtual void load(const Pgsql::Result &res) override;
private: private:
}; };

View file

@ -0,0 +1,4 @@
#include "PgTablespace.h"
PgTablespace::PgTablespace()
{}

24
pglablib/PgTablespace.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef PGTABLESPACE_H
#define PGTABLESPACE_H
#include <QString>
#include <libpq-fe.h>
#include <vector>
class PgTablespace {
public:
Oid oid = InvalidOid;
QString name;
Oid owner = InvalidOid;
std::vector<QString> acl;
std::vector<QString> 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

View file

@ -0,0 +1,25 @@
#include "PgTablespaceContainer.h"
#include "Pgsql_Connection.h"
#include "Pgsql_Col.h"
#include "Pgsql_declare.h"
#include "PgDatabaseCatalog.h"
#include <iterator>
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<QString>(std::back_inserter(v.acl), Pgsql::NullHandling::Ignore);
col.getAsArray<QString>(std::back_inserter(v.options), Pgsql::NullHandling::Ignore);
return v;
}

View file

@ -0,0 +1,24 @@
#ifndef PGTABLESPACECONTAINER_H
#define PGTABLESPACECONTAINER_H
#include "PgContainer.h"
#include "PgTablespace.h"
namespace Pgsql {
class Result;
}
class PgTablespaceContainer: public PgContainer<PgTablespace> {
public:
using PgContainer<PgTablespace>::PgContainer;
virtual std::string getLoadQuery() const override;
protected:
PgTablespace loadElem(const Pgsql::Row &row) override;
private:
};
#endif // PGTABLESPACECONTAINER_H

View file

@ -55,7 +55,9 @@ SOURCES += \
QueryGenerator.cpp \ QueryGenerator.cpp \
PgAm.cpp \ PgAm.cpp \
PgAmContainer.cpp \ PgAmContainer.cpp \
PgObject.cpp PgObject.cpp \
PgTablespace.cpp \
PgTablespaceContainer.cpp
HEADERS += \ HEADERS += \
Pglablib.h \ Pglablib.h \
@ -88,7 +90,9 @@ HEADERS += \
QueryGenerator.h \ QueryGenerator.h \
PgAm.h \ PgAm.h \
PgAmContainer.h \ PgAmContainer.h \
PgObject.h PgObject.h \
PgTablespace.h \
PgTablespaceContainer.h
unix { unix {
target.path = /usr/lib target.path = /usr/lib

View file

@ -263,3 +263,8 @@ void Connection::notifyReceiveFunc(void *arg, const PGresult *result)
Connection *c = reinterpret_cast<Connection *>(arg); Connection *c = reinterpret_cast<Connection *>(arg);
c->notifyReceiver(result); c->notifyReceiver(result);
} }
QString Connection::getDBName() const
{
return QString::fromUtf8(PQdb(conn));
}

View file

@ -124,6 +124,8 @@ namespace Pgsql {
QString escapeLiteral(const QString &literal); QString escapeLiteral(const QString &literal);
std::string escapeIdentifier(const std::string_view &ident); std::string escapeIdentifier(const std::string_view &ident);
QString escapeIdentifier(const QString &ident); QString escapeIdentifier(const QString &ident);
QString getDBName() const;
private: private:
PGconn *conn = nullptr; PGconn *conn = nullptr;
std::function<void(const PGresult *)> notifyReceiver; std::function<void(const PGresult *)> notifyReceiver;

View file

@ -177,6 +177,13 @@ namespace Pgsql {
static Oid elem() { return timestamptz_oid; } static Oid elem() { return timestamptz_oid; }
static Oid array() { return timestamptz_array_oid; } static Oid array() { return timestamptz_array_oid; }
}; };
template <>
class OidFor<QString> {
public:
static Oid elem() { return text_oid; }
static Oid array() { return text_array_oid; }
};
// template <> // template <>
// class OidFor<> { // class OidFor<> {
// public: // public: