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;
int frozenxid;
int minmxid;
QString acl;
QString options;
std::vector<QString> acl;
std::vector<QString> options;
bool operator==(Oid _oid) const { return oid == _oid; }
bool operator==(const QString &n) const { return name == n; }

View file

@ -3,6 +3,7 @@
#include "Pgsql_Col.h"
#include "PgDatabaseCatalog.h"
#include "PgNamespaceContainer.h"
#include <iterator>
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<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 ns = cat->namespaces()->getByKey(v.relnamespace);

View file

@ -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<bool(int, int)> 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<const PgNamespaceContainer> PgDatabaseCatalog::namespaces() cons
return m_namespaces;
}
std::shared_ptr<const PgTablespaceContainer> PgDatabaseCatalog::tablespaces() const
{
return m_tablespaces;
}
std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const
{
return m_types;

View file

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

View file

@ -18,7 +18,6 @@ public:
virtual std::string getLoadQuery() const override;
virtual void load(const Pgsql::Result &res) override;
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 \
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

View file

@ -263,3 +263,8 @@ void Connection::notifyReceiveFunc(void *arg, const PGresult *result)
Connection *c = reinterpret_cast<Connection *>(arg);
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);
std::string escapeIdentifier(const std::string_view &ident);
QString escapeIdentifier(const QString &ident);
QString getDBName() const;
private:
PGconn *conn = nullptr;
std::function<void(const PGresult *)> notifyReceiver;

View file

@ -177,6 +177,13 @@ namespace Pgsql {
static Oid elem() { return timestamptz_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 <>
// class OidFor<> {
// public: