pgLab/pglablib/PgDatabaseCatalog.cpp

283 lines
6.3 KiB
C++
Raw Normal View History

#include "PgDatabaseCatalog.h"
#include "ASyncDBConnection.h"
#include "PgAmContainer.h"
#include "PgAttributeContainer.h"
#include "PgAuthIdContainer.h"
#include "PgClassContainer.h"
#include "PgConstraintContainer.h"
#include "PgDatabaseContainer.h"
2017-12-17 11:28:20 +01:00
#include "PgIndexContainer.h"
#include "PgNamespaceContainer.h"
2018-09-02 10:30:30 +00:00
#include "PgTablespaceContainer.h"
#include "PgTriggerContainer.h"
#include "PgTypeContainer.h"
#include "Pgsql_Connection.h"
#include "Pgsql_oids.h"
#include <QThread>
#include <boost/timer/timer.hpp>
#include <boost/chrono/system_clocks.hpp>
using namespace Pgsql;
QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid)
{
QString name;
auto auth_ids = cat.authIds();
if (auth_ids) {
const PgAuthId& auth_id = auth_ids->getByKey(oid);
if (auth_id.valid()) {
name = auth_id.name;
}
}
return name;
}
QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{
QString name = getRoleNameFromOid(cat, oid);
return name;
}
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{
QString result;
auto nss = cat.namespaces();
auto ns = nss->getByKey(oid);
result = ns.name; //QString("ns %1").arg(oid);
return result;
}
QString getClassDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{
QString result;
auto l = cat.classes();
auto e = l->getByKey(oid);
result = e.name;
return result;
}
QString getIndexDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{
QString result;
// auto l = cat.indexes();
// auto e = l->getByKey(oid);
// if (e)
result = getClassDisplayString(cat, oid);
return result;
}
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
{
// TODO load list and lookup name
2018-09-02 10:30:30 +00:00
if (oid == 0) {
auto dbname = cat.getDBName();
oid = cat.databases()->getByName(dbname).tablespace;
auto ts = cat.tablespaces()->getByKey(oid);
return ts.name + " (inherited)";
}
else {
auto ts = cat.tablespaces()->getByKey(oid);
return ts.name;
2018-09-02 10:30:30 +00:00
}
}
QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid, int32_t typmod)
{
if (oid == 0) {
return QString();
}
auto tc = cat.types();
auto t = tc->getByKey(oid);
if (t.oid == InvalidOid) {
return "(invalid/unknown)";
}
QString s;
if (t.category == TypCategory::Array) {
// auto et = tc->getByKey(t.elem);
// s = et.name;
s = getTypeDisplayString(cat, t.elem, typmod);
s += "[]";
}
else {
s = t.name;
switch (oid) {
case varchar_oid:
case char_oid:
case text_oid:
if (typmod > 4)
s += QString::asprintf("(%d)", typmod-4);
break;
case numeric_oid:
if (typmod > 4) {
int prec = (typmod - 4) / 65536;
int scale = (typmod - 4) % 65536;
if (scale > 0)
s += QString::asprintf("(%d,%d)", prec, scale);
else
s += QString::asprintf("(%d)", prec);
}
break;
}
}
return s;
}
PgDatabaseCatalog::PgDatabaseCatalog()
{
}
PgDatabaseCatalog::~PgDatabaseCatalog()
{
}
void PgDatabaseCatalog::loadAll(Pgsql::Connection &conn,
std::function<bool(int, int)> progress_callback)
{
loadInfo(conn);
const int count = 12;
2018-01-08 20:45:52 +01:00
int n = 0;
if (progress_callback && !progress_callback(++n, count))
2018-01-08 20:45:52 +01:00
return;
load2(m_namespaces, conn);
2018-09-02 10:30:30 +00:00
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_tablespaces, conn);
if (progress_callback && !progress_callback(++n, count))
2018-01-08 20:45:52 +01:00
return;
load2(m_classes, conn); // needs namespaces
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_attributes, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_authIds, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_constraints, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_databases, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_indexes, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_ams, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_triggers, conn);
if (progress_callback && !progress_callback(++n, count))
return;
load2(m_types, conn);
progress_callback && progress_callback(++n, count);
refreshed(this, All);
}
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();
2018-09-02 10:30:30 +00:00
m_dbName = conn.getDBName();
}
void load(Pgsql::Connection &conn, IPgContainter &pg_cont)
{
2017-12-28 09:20:42 +01:00
//QThread::msleep(400);
std::string q = pg_cont.getLoadQuery();
Pgsql::Result result = conn.query(q.c_str());
if (result && result.resultStatus() == PGRES_TUPLES_OK) {
2018-01-08 20:45:52 +01:00
//boost::timer::auto_cpu_timer t;
pg_cont.load(result);
}
else {
auto details = result.diagDetails();
if (details.state == "42501") { // permission denied
// ignore this for now
}
else {
throw std::runtime_error("Query failed\n" + details.errorMessage);
}
}
}
const QString& PgDatabaseCatalog::serverVersionString() const
{
return m_serverVersionString;
}
int PgDatabaseCatalog::serverVersion() const
{
return m_serverVersion;
}
std::shared_ptr<const PgAttributeContainer> PgDatabaseCatalog::attributes() const
{
return m_attributes;
}
std::shared_ptr<const PgAuthIdContainer> PgDatabaseCatalog::authIds() const
{
return m_authIds;
}
std::shared_ptr<const PgClassContainer> PgDatabaseCatalog::classes() const
{
return m_classes;
}
std::shared_ptr<const PgConstraintContainer> PgDatabaseCatalog::constraints() const
{
return m_constraints;
}
std::shared_ptr<const PgDatabaseContainer> PgDatabaseCatalog::databases() const
{
return m_databases;
}
2017-12-17 11:28:20 +01:00
std::shared_ptr<const PgIndexContainer> PgDatabaseCatalog::indexes() const
{
return m_indexes;
}
std::shared_ptr<const PgAmContainer> PgDatabaseCatalog::ams() const
{
return m_ams;
}
std::shared_ptr<const PgNamespaceContainer> PgDatabaseCatalog::namespaces() const
{
return m_namespaces;
}
2018-09-02 10:30:30 +00:00
std::shared_ptr<const PgTablespaceContainer> PgDatabaseCatalog::tablespaces() const
{
return m_tablespaces;
}
std::shared_ptr<const PgTriggerContainer> PgDatabaseCatalog::triggers() const
{
return m_triggers;
}
std::shared_ptr<const PgTypeContainer> PgDatabaseCatalog::types() const
{
return m_types;
}