From 6c76c70a972d5bfd73e5fb20fbda35d2a40ce609 Mon Sep 17 00:00:00 2001 From: eelke Date: Mon, 3 Dec 2018 21:03:49 +0100 Subject: [PATCH] The create table statement now lists the inherited tables and inherited columns are commented out. --- pglablib/PgAttribute.h | 1 + pglablib/PgAttributeContainer.cpp | 4 ++-- pglablib/PgClass.cpp | 18 +++++++++++++++++- pglablib/PgDatabaseCatalog.cpp | 9 +++++++++ pglablib/PgDatabaseCatalog.h | 3 +++ pglablib/PgInherits.cpp | 3 +++ pglablib/PgInherits.h | 25 +++++++++++++++++++++++++ pglablib/PgInheritsContainer.cpp | 29 +++++++++++++++++++++++++++++ pglablib/PgInheritsContainer.h | 22 ++++++++++++++++++++++ pglablib/SqlFormattingUtils.cpp | 2 +- pglablib/pglablib.pro | 8 ++++++-- 11 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 pglablib/PgInherits.cpp create mode 100644 pglablib/PgInherits.h create mode 100644 pglablib/PgInheritsContainer.cpp create mode 100644 pglablib/PgInheritsContainer.h diff --git a/pglablib/PgAttribute.h b/pglablib/PgAttribute.h index 2707bdc..1e0cd8a 100644 --- a/pglablib/PgAttribute.h +++ b/pglablib/PgAttribute.h @@ -24,6 +24,7 @@ public: bool hasdef = false; char identity = ' '; bool isdropped = false; + bool islocal = true; Oid collation = InvalidOid; QString acl; QString options; diff --git a/pglablib/PgAttributeContainer.cpp b/pglablib/PgAttributeContainer.cpp index ef7bca3..9806836 100644 --- a/pglablib/PgAttributeContainer.cpp +++ b/pglablib/PgAttributeContainer.cpp @@ -12,7 +12,7 @@ std::string PgAttributeContainer::getLoadQuery() const std::string q = R"__( SELECT attrelid, attname, atttypid, attstattarget, attnum, attndims, atttypmod, attnotnull, atthasdef, attisdropped, - attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value)__"; + attislocal, attcollation, attacl, attoptions, pg_get_expr(adbin, adrelid) AS def_value)__"; if (m_catalog.serverVersion() >= 100000) q += ", attidentity"; q += @@ -27,7 +27,7 @@ PgAttribute PgAttributeContainer::loadElem(const Pgsql::Row &row) PgAttribute v; col >> v.relid >> v.name >> v.typid >> v.stattarget >> v.num >> v.ndims >> v.typmod >> v.notnull >> v.hasdef >> v.isdropped - >> v.collation >> v.acl >> v.options >> v.defaultValue; + >> v.islocal >> v.collation >> v.acl >> v.options >> v.defaultValue; if (m_catalog.serverVersion() >= 100000) col >> v.identity; diff --git a/pglablib/PgClass.cpp b/pglablib/PgClass.cpp index c83bc43..e1339f9 100644 --- a/pglablib/PgClass.cpp +++ b/pglablib/PgClass.cpp @@ -1,7 +1,9 @@ #include "PgClass.h" #include "PgAttributeContainer.h" +#include "PgClassContainer.h" #include "PgDatabaseCatalog.h" #include "PgConstraintContainer.h" +#include "PgInheritsContainer.h" #include #include "SqlFormattingUtils.h" @@ -93,6 +95,7 @@ QString PgClass::createTableSql() const first = false; } else sql += ",\n "; + if (!col.islocal) sql += "-- "; sql += col.columnDefinition(catalog()); } // { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] @@ -110,7 +113,20 @@ QString PgClass::createTableSql() const } sql += ")"; -// [ INHERITS ( parent_table [, ... ] ) ] + { + // [ INHERITS ( parent_table [, ... ] ) ] + auto parents = catalog().inherits()->getParentsOf(oid()); + if (!parents.empty()) { + sql += "\nINHERITS ("; + bool first = true; + for (auto parent_oid : parents) { + if (first) first = false; + else sql += ", "; + sql += catalog().classes()->getByKey(parent_oid)->fullyQualifiedQuotedObjectName(); + } + sql += ")"; + } + } // [ PARTITION BY { RANGE | LIST } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] // [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] // [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] diff --git a/pglablib/PgDatabaseCatalog.cpp b/pglablib/PgDatabaseCatalog.cpp index eccf681..f5343a0 100644 --- a/pglablib/PgDatabaseCatalog.cpp +++ b/pglablib/PgDatabaseCatalog.cpp @@ -14,6 +14,7 @@ #include "PgTypeContainer.h" #include "PgProcContainer.h" #include "PgCollationContainer.h" +#include "PgInheritsContainer.h" #include "Pgsql_Connection.h" #include "Pgsql_oids.h" @@ -178,6 +179,9 @@ void PgDatabaseCatalog::loadAll(Pgsql::Connection &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); @@ -293,3 +297,8 @@ std::shared_ptr PgDatabaseCatalog::collations() cons { return m_collations; } + +std::shared_ptr PgDatabaseCatalog::inherits() const +{ + return m_inherits; +} diff --git a/pglablib/PgDatabaseCatalog.h b/pglablib/PgDatabaseCatalog.h index f892b2c..02b23e6 100644 --- a/pglablib/PgDatabaseCatalog.h +++ b/pglablib/PgDatabaseCatalog.h @@ -28,6 +28,7 @@ class PgTriggerContainer; class PgTypeContainer; class PgProcContainer; class PgCollationContainer; +class PgInheritsContainer; class PgDatabaseCatalog: public QObject, public std::enable_shared_from_this { @@ -60,6 +61,7 @@ public: std::shared_ptr types() const; std::shared_ptr procs() const; std::shared_ptr collations() const; + std::shared_ptr inherits() const; enum RefreshFlag { Attributes = 1, @@ -98,6 +100,7 @@ private: std::shared_ptr m_types; std::shared_ptr m_procs; std::shared_ptr m_collations; + std::shared_ptr m_inherits; template void load2(std::shared_ptr &ptr, Pgsql::Connection &conn) diff --git a/pglablib/PgInherits.cpp b/pglablib/PgInherits.cpp new file mode 100644 index 0000000..d1be22b --- /dev/null +++ b/pglablib/PgInherits.cpp @@ -0,0 +1,3 @@ +#include "PgInherits.h" + +PgInherits::PgInherits() = default; diff --git a/pglablib/PgInherits.h b/pglablib/PgInherits.h new file mode 100644 index 0000000..8afe92a --- /dev/null +++ b/pglablib/PgInherits.h @@ -0,0 +1,25 @@ +#ifndef PGINHERITS_H +#define PGINHERITS_H + +#include "Pgsql_declare.h" +#include +#include +#include + +class PgInherits { +public: + using Key = std::tuple; + + + Oid relid = InvalidOid; // oid + Oid parent = InvalidOid; // oid + int32_t seqno = 0; // integer + + PgInherits(); + + bool operator==(Key _k) const { return relid == std::get<0>(_k) && seqno == std::get<1>(_k); } + bool operator<(Key _k) const { return relid < std::get<0>(_k) || (relid == std::get<0>(_k) && seqno < std::get<1>(_k)); } + bool operator<(const PgInherits &rhs) const { return relid < rhs.relid || (relid == rhs.relid && seqno < rhs.seqno); } +}; + +#endif // PGINHERITS_H diff --git a/pglablib/PgInheritsContainer.cpp b/pglablib/PgInheritsContainer.cpp new file mode 100644 index 0000000..7c9c9ae --- /dev/null +++ b/pglablib/PgInheritsContainer.cpp @@ -0,0 +1,29 @@ +#include "PgInheritsContainer.h" +#include "Pgsql_Col.h" +#include "PgDatabaseCatalog.h" +#include + +std::vector PgInheritsContainer::getParentsOf(Oid oid) const +{ + std::vector result; + auto&& iter = std::lower_bound(m_container.begin(), m_container.end(), PgInherits::Key{ oid, 1 }); + for (;iter != m_container.end() && iter->relid == oid; ++iter) + result.push_back(iter->parent); + return result; +} + +std::string PgInheritsContainer::getLoadQuery() const +{ + return + "SELECT inhrelid, inhparent, inhseqno \n" + " FROM pg_inherits"; +} + + +PgInherits PgInheritsContainer::loadElem(const Pgsql::Row &row) +{ + Pgsql::Col col(row); + PgInherits v; + col >> v.relid >> v.parent >> v.seqno; + return v; +} diff --git a/pglablib/PgInheritsContainer.h b/pglablib/PgInheritsContainer.h new file mode 100644 index 0000000..3d95377 --- /dev/null +++ b/pglablib/PgInheritsContainer.h @@ -0,0 +1,22 @@ +#ifndef PGINHERITSCONTAINER_H +#define PGINHERITSCONTAINER_H + + +#include "PgContainer.h" +#include "PgInherits.h" +#include "Pgsql_declare.h" + + +class PgInheritsContainer : public PgContainer { +public: + using PgContainer::PgContainer; + + virtual std::string getLoadQuery() const override; + + /// Returns the parents in the correct order + std::vector getParentsOf(Oid oid) const; +protected: + PgInherits loadElem(const Pgsql::Row &row) override; +}; + +#endif // PGINHERITSCONTAINER_H diff --git a/pglablib/SqlFormattingUtils.cpp b/pglablib/SqlFormattingUtils.cpp index 4375441..73633db 100644 --- a/pglablib/SqlFormattingUtils.cpp +++ b/pglablib/SqlFormattingUtils.cpp @@ -317,7 +317,7 @@ QString getForeignKeyConstraintDefinition(const PgDatabaseCatalog &catalog, cons % ForeignKeyMatchToString(constraint.fmatchtype) % " ON UPDATE " % ForeignKeyActionToString(constraint.fupdtype) % " ON DELETE " % ForeignKeyActionToString(constraint.fdeltype) - % deferrable % validated % ";"; + % deferrable % validated; } QString getForeignKeyConstraintReferences(const PgDatabaseCatalog &catalog, const PgConstraint &constraint) diff --git a/pglablib/pglablib.pro b/pglablib/pglablib.pro index da41771..d2c76b9 100644 --- a/pglablib/pglablib.pro +++ b/pglablib/pglablib.pro @@ -73,7 +73,9 @@ codebuilder/StructureTemplate.cpp \ PgOwnedObject.cpp \ PgNamespaceObject.cpp \ PgCollation.cpp \ - PgCollationContainer.cpp + PgCollationContainer.cpp \ + PgInherits.cpp \ + PgInheritsContainer.cpp HEADERS += \ Pglablib.h \ @@ -129,7 +131,9 @@ codebuilder/StructureTemplate.h \ PgOwnedObject.h \ PgNamespaceObject.h \ PgCollation.h \ - PgCollationContainer.h + PgCollationContainer.h \ + PgInherits.h \ + PgInheritsContainer.h unix { target.path = /usr/lib