From 35813ae926697eeeb283c049b8b899498eff7f27 Mon Sep 17 00:00:00 2001 From: eelke Date: Sat, 17 Nov 2018 19:38:07 +0100 Subject: [PATCH] Added pg_proc table to the catalog. Contains the definition of functions. Also improved the loading code for some catalog tables. --- pglablib/PgClassContainer.cpp | 6 ++-- pglablib/PgConstraintContainer.cpp | 11 ++----- pglablib/PgDatabaseCatalog.cpp | 8 +++++ pglablib/PgDatabaseCatalog.h | 4 +++ pglablib/PgProc.cpp | 2 ++ pglablib/PgProc.h | 48 +++++++++++++++++++++++++++ pglablib/PgProcContainer.cpp | 52 ++++++++++++++++++++++++++++++ pglablib/PgProcContainer.h | 26 +++++++++++++++ pglablib/PgTablespaceContainer.cpp | 4 +-- pglablib/pglablib.pro | 8 +++-- 10 files changed, 152 insertions(+), 17 deletions(-) create mode 100644 pglablib/PgProc.cpp create mode 100644 pglablib/PgProc.h create mode 100644 pglablib/PgProcContainer.cpp create mode 100644 pglablib/PgProcContainer.h diff --git a/pglablib/PgClassContainer.cpp b/pglablib/PgClassContainer.cpp index 94d10b4..471535a 100644 --- a/pglablib/PgClassContainer.cpp +++ b/pglablib/PgClassContainer.cpp @@ -22,10 +22,8 @@ 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; - - col.getAsArray(std::back_inserter(v.acl), QString()); - col.getAsArray(std::back_inserter(v.options), QString()); + >> v.kind >> v.hasoids >> v.ispopulated >> v.frozenxid >> v.minmxid + >> v.acl >> v.options; auto cat = m_catalogue.lock(); auto ns = cat->namespaces()->getByKey(v.relnamespace); diff --git a/pglablib/PgConstraintContainer.cpp b/pglablib/PgConstraintContainer.cpp index 45df803..2ebd309 100644 --- a/pglablib/PgConstraintContainer.cpp +++ b/pglablib/PgConstraintContainer.cpp @@ -41,14 +41,9 @@ PgConstraint PgConstraintContainer::loadElem(const Pgsql::Row &row) col >> v.oid >> v.name >> v.connamespace >> v.type >> v.deferrable >> v.deferred >> v.validated >> v.relid >> v.typid >> v.indid >> v.frelid >> v.fupdtype >> v.fdeltype >> v.fmatchtype - >> v.islocal >> v.inhcount >> v.noinherit; - col.getAsArray(std::back_inserter(v.key), NullHandling::Ignore); - col.getAsArray(std::back_inserter(v.fkey), NullHandling::Ignore); - col.getAsArray(std::back_inserter(v.pfeqop), NullHandling::Ignore); - col.getAsArray(std::back_inserter(v.ppeqop), NullHandling::Ignore); - col.getAsArray(std::back_inserter(v.ffeqop), NullHandling::Ignore); - col.getAsArray(std::back_inserter(v.exclop), NullHandling::Ignore); - col >> v.bin >> v.src >> v.definition; + >> v.islocal >> v.inhcount >> v.noinherit + >> v.key >> v.fkey >> v.pfeqop >> v.ppeqop >> v.ffeqop >> v.exclop + >> v.bin >> v.src >> v.definition; return v; } diff --git a/pglablib/PgDatabaseCatalog.cpp b/pglablib/PgDatabaseCatalog.cpp index a90b96a..af9a5af 100644 --- a/pglablib/PgDatabaseCatalog.cpp +++ b/pglablib/PgDatabaseCatalog.cpp @@ -12,6 +12,7 @@ #include "PgTablespaceContainer.h" #include "PgTriggerContainer.h" #include "PgTypeContainer.h" +#include "PgProcContainer.h" #include "Pgsql_Connection.h" #include "Pgsql_oids.h" @@ -174,6 +175,9 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &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); progress_callback && progress_callback(++n, count); refreshed(this, All); @@ -280,3 +284,7 @@ std::shared_ptr PgDatabaseCatalog::types() const return m_types; } +std::shared_ptr PgDatabaseCatalog::procs() const +{ + return m_procs; +} diff --git a/pglablib/PgDatabaseCatalog.h b/pglablib/PgDatabaseCatalog.h index 963cd0b..b23a824 100644 --- a/pglablib/PgDatabaseCatalog.h +++ b/pglablib/PgDatabaseCatalog.h @@ -26,6 +26,7 @@ class PgAmContainer; class PgTablespaceContainer; class PgTriggerContainer; class PgTypeContainer; +class PgProcContainer; class PgDatabaseCatalog: public QObject, public std::enable_shared_from_this { Q_OBJECT @@ -55,6 +56,7 @@ public: std::shared_ptr tablespaces() const; std::shared_ptr triggers() const; std::shared_ptr types() const; + std::shared_ptr procs() const; enum RefreshFlag { Attributes = 1, @@ -68,6 +70,7 @@ public: Tablespaces = (1 << 8), Triggers = (1 << 9), Types = (1 << 10), + Proc = (1 << 11), All = 0xffffffff }; using RefreshFlags = int; @@ -90,6 +93,7 @@ private: std::shared_ptr m_tablespaces; std::shared_ptr m_triggers; std::shared_ptr m_types; + std::shared_ptr m_procs; template void load2(std::shared_ptr &ptr, Pgsql::Connection &conn) diff --git a/pglablib/PgProc.cpp b/pglablib/PgProc.cpp new file mode 100644 index 0000000..ae1947b --- /dev/null +++ b/pglablib/PgProc.cpp @@ -0,0 +1,2 @@ +#include "PgProc.h" + diff --git a/pglablib/PgProc.h b/pglablib/PgProc.h new file mode 100644 index 0000000..d6e93a8 --- /dev/null +++ b/pglablib/PgProc.h @@ -0,0 +1,48 @@ +#ifndef PGPROC_H +#define PGPROC_H + +#include +#include +#include "Pgsql_Value.h" + +class PgProc { +public: + Oid oid = InvalidOid; // oid + QString proname; // name + Oid pronamespace = InvalidOid; // oid + Oid proowner = InvalidOid; // oid + Oid prolang = InvalidOid; // oid + float procost = 0.f; // float4 + float prorows = 0.f; // float4 + Oid provariadic = InvalidOid; // oid + QString protransform; // regproc + bool proisagg = false; // bool + bool proiswindow = false; // bool + bool prosecdef = false; // bool + bool proleakproof = false; // bool + bool proisstrict = false; // bool + bool proretset = false; // bool + char provolatile = '\0'; // char + char proparallel = '\0'; // char, version >= 9.6 + int16_t pronargs = 0; // int2 + int16_t pronargdefaults = 0; // int2 + Oid prorettype = InvalidOid; // oid + std::vector proargtypes; // oid[] + std::vector proallargtypes; // oid[] + std::vector proargmodes; // char[] + std::vector proargnames; // text[] + std::optional proargdefaults; // pg_node_tree + std::vector protrftypes; // oid[], version >= 9.5 + QString prosrc; // text + QString probin; // text + std::vector proconfig; // text[] + std::vector proacl; // aclitem[] + + bool operator==(Oid _oid) const { return oid == _oid; } + bool operator==(const QString &n) const { return proname == n; } + bool operator<(Oid _oid) const { return oid < _oid; } + bool operator<(const PgProc &rhs) const { return oid < rhs.oid; } + +}; + +#endif // PGPROC_H diff --git a/pglablib/PgProcContainer.cpp b/pglablib/PgProcContainer.cpp new file mode 100644 index 0000000..9129639 --- /dev/null +++ b/pglablib/PgProcContainer.cpp @@ -0,0 +1,52 @@ +#include "PgProcContainer.h" +#include "Pgsql_Connection.h" +#include "Pgsql_Col.h" +#include "PgDatabaseCatalog.h" +#include +#include + +std::string PgProcContainer::getLoadQuery() const +{ + std::string column_list = + "oid,proname,pronamespace,proowner,prolang,procost,prorows," + "provariadic,protransform,proisagg,proiswindow,prosecdef,proleakproof," + "proisstrict,proretset,provolatile,pronargs,pronargdefaults,prorettype," + "proargtypes,proallargtypes,proargmodes,proargnames,proargdefaults," + "prosrc,probin,proconfig,proacl"; + auto cat = m_catalogue.lock(); + int ver = cat->serverVersion(); + if (ver >= 90500) { + column_list += ",protrftypes"; + } + else if (cat->serverVersion() >= 90600) { + column_list += ",proparallel"; + } + + return "SELECT " + column_list + " FROM pg_proc"; +} + +PgProc PgProcContainer::loadElem(const Pgsql::Row &row) +{ + Pgsql::Col col(row); + PgProc v; + col >> v.oid >> v.proname >> v.pronamespace >> v.proowner >> v.prolang >> v.procost >> v.prorows + >> v.provariadic >> v.protransform >> v.proisagg >> v.proiswindow >> v.prosecdef >> v.proleakproof + >> v.proisstrict >> v.proretset >> v.provolatile >> v.pronargs >> v.pronargdefaults + >> v.prorettype; + col.getAsVector(std::back_inserter(v.proargtypes)); + col >> v.proallargtypes >> v.proargmodes >> v.proargnames + >> v.proargdefaults; + col >> v.prosrc; + col >> v.probin >> v.proconfig >> v.proacl; + + auto cat = m_catalogue.lock(); + int ver = cat->serverVersion(); + if (ver >= 90500) { + col >> v.protrftypes; + } + else if (cat->serverVersion() >= 90600) { + col >> v.proparallel; + } + + return v; +} diff --git a/pglablib/PgProcContainer.h b/pglablib/PgProcContainer.h new file mode 100644 index 0000000..ec459c2 --- /dev/null +++ b/pglablib/PgProcContainer.h @@ -0,0 +1,26 @@ +#ifndef PGPROCCONTAINER_H +#define PGPROCCONTAINER_H + +#include "PgContainer.h" +#include "PgProc.h" +#include + +namespace Pgsql { + + class Result; + +} + +class PgProcContainer: public PgContainer { +public: + using PgContainer::PgContainer; + + virtual std::string getLoadQuery() const override; + + //std::vector getTriggersForRelation(Oid cls) const; +protected: + PgProc loadElem(const Pgsql::Row &row) override; +private: +}; + +#endif // PGPROCCONTAINER_H diff --git a/pglablib/PgTablespaceContainer.cpp b/pglablib/PgTablespaceContainer.cpp index 092056e..b0b3556 100644 --- a/pglablib/PgTablespaceContainer.cpp +++ b/pglablib/PgTablespaceContainer.cpp @@ -18,8 +18,6 @@ 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); + col >> v.oid >> v.name >> v.owner >> v.acl >> v.options; return v; } diff --git a/pglablib/pglablib.pro b/pglablib/pglablib.pro index 34c3dba..9108e6e 100644 --- a/pglablib/pglablib.pro +++ b/pglablib/pglablib.pro @@ -65,7 +65,9 @@ codebuilder/StructureTemplate.cpp \ codebuilder/StringLiteralRules.cpp \ codebuilder/StringEscapeRule.cpp \ PgTrigger.cpp \ - PgTriggerContainer.cpp + PgTriggerContainer.cpp \ + PgProc.cpp \ + PgProcContainer.cpp HEADERS += \ Pglablib.h \ @@ -113,7 +115,9 @@ codebuilder/StructureTemplate.h \ codebuilder/StringEscapeRule.h \ codebuilder/StringLiteralRules.h \ PgTrigger.h \ - PgTriggerContainer.h + PgTriggerContainer.h \ + PgProc.h \ + PgProcContainer.h unix { target.path = /usr/lib