#include "PgDatabaseCatalog.h" #include "ASyncDBConnection.h" #include "PgAmContainer.h" #include "PgAttributeContainer.h" #include "PgAuthIdContainer.h" #include "PgClassContainer.h" #include "PgConstraintContainer.h" #include "PgDatabaseContainer.h" #include "PgIndexContainer.h" #include "PgNamespaceContainer.h" #include "PgTablespaceContainer.h" #include "PgTriggerContainer.h" #include "PgTypeContainer.h" #include "PgProcContainer.h" #include "PgCollationContainer.h" #include "PgInheritsContainer.h" #include "Pgsql_Connection.h" #include "Pgsql_oids.h" #include #include #include 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) { name = auth_id->name; } } return name; } QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid) { QString name = getRoleNameFromOid(cat, oid); return name; } QString getClassDisplayString(const PgDatabaseCatalog &cat, Oid oid) { QString result; auto l = cat.classes(); auto e = l->getByKey(oid); if (e) result = e->objectName(); 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 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; } } 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 == nullptr) { 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->objectName(); 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 progress_callback) { loadInfo(conn); const int count = 12; int n = 0; if (progress_callback && !progress_callback(++n, count)) return; // First load server objects load2(m_authIds, conn); if (progress_callback && !progress_callback(++n, count)) return; load2(m_tablespaces, conn); if (progress_callback && !progress_callback(++n, count)) return; load2(m_databases, conn); if (progress_callback && !progress_callback(++n, count)) return; // Load database objects load2(m_namespaces, conn); if (progress_callback && !progress_callback(++n, count)) return; load2(m_collations, conn); if (progress_callback && !progress_callback(++n, count)) 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_constraints, 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); if (progress_callback && !progress_callback(++n, count)) return; load2(m_procs, conn); if (progress_callback && !progress_callback(++n, count)) return; load2(m_inherits, 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(); m_dbName = conn.getDBName(); } void load(Pgsql::Connection &conn, IPgContainer &pg_cont) { //QThread::msleep(400); std::string q = pg_cont.getLoadQuery(); Pgsql::Result result = conn.query(q.c_str()); if (result && result.resultStatus() == PGRES_TUPLES_OK) { //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 PgDatabaseCatalog::attributes() const { return m_attributes; } std::shared_ptr PgDatabaseCatalog::authIds() const { return m_authIds; } std::shared_ptr PgDatabaseCatalog::classes() const { return m_classes; } std::shared_ptr PgDatabaseCatalog::constraints() const { return m_constraints; } std::shared_ptr PgDatabaseCatalog::databases() const { return m_databases; } std::shared_ptr PgDatabaseCatalog::indexes() const { return m_indexes; } std::shared_ptr PgDatabaseCatalog::ams() const { return m_ams; } std::shared_ptr PgDatabaseCatalog::namespaces() const { return m_namespaces; } std::shared_ptr PgDatabaseCatalog::tablespaces() const { return m_tablespaces; } std::shared_ptr PgDatabaseCatalog::triggers() const { return m_triggers; } std::shared_ptr PgDatabaseCatalog::types() const { return m_types; } std::shared_ptr PgDatabaseCatalog::procs() const { return m_procs; } std::shared_ptr PgDatabaseCatalog::collations() const { return m_collations; } std::shared_ptr PgDatabaseCatalog::inherits() const { return m_inherits; }