diff --git a/pglab/PgConstraint.cpp b/pglab/PgConstraint.cpp new file mode 100644 index 0000000..af88095 --- /dev/null +++ b/pglab/PgConstraint.cpp @@ -0,0 +1,70 @@ +#include "PgConstraint.h" + +void operator<<(ConstraintType &s, const Pgsql::Value &v) +{ + const char *c = v.c_str(); + switch (*c) { + case 'c': + s = ConstraintType::Check; + break; + case 'f': + s = ConstraintType::ForeignKey; + break; + case 'p': + s = ConstraintType::PrimaryKey; + break; + case 'u': + s = ConstraintType::Unique; + break; + case 't': + s = ConstraintType::ConstraintTrigger; + break; + case 'x': + s = ConstraintType::ExclusionConstraint; + break; + } +} + +void operator<<(ForeignKeyAction &s, const Pgsql::Value &v) +{ + const char *c = v.c_str(); + switch (*c) { + case 'a': + s = ForeignKeyAction::NoAction; + break; + case 'r': + s = ForeignKeyAction::Restrict; + break; + case 'c': + s = ForeignKeyAction::Cascade; + break; + case 'n': + s = ForeignKeyAction::SetNull; + break; + case 'd': + s = ForeignKeyAction::SetDefault; + break; + } +} + +void operator<<(ForeignKeyMatch &s, const Pgsql::Value &v) +{ + const char *c = v.c_str(); + switch (*c) { + case 'f': + s = ForeignKeyMatch::Full; + break; + case 'p': + s = ForeignKeyMatch::Partial; + break; + case 's': + s = ForeignKeyMatch::Simple; + break; + } +} + + +PgConstraint::PgConstraint() +{ + +} diff --git a/pglab/PgConstraint.h b/pglab/PgConstraint.h new file mode 100644 index 0000000..cd2c5f7 --- /dev/null +++ b/pglab/PgConstraint.h @@ -0,0 +1,78 @@ +#ifndef PGCONSTRAINT_H +#define PGCONSTRAINT_H + +#include "Pgsql_Value.h" +#include +#include + +#include +#include + +enum class ConstraintType { + Check, // c + ForeignKey, // f + PrimaryKey, // p + Unique, // u + ConstraintTrigger, // t + ExclusionConstraint, // x +}; + +void operator<<(ConstraintType &s, const Pgsql::Value &v); + + +enum class ForeignKeyAction { + NoAction, // a + Restrict, // r + Cascade, // c + SetNull, // n + SetDefault // d +}; + +void operator<<(ForeignKeyAction &s, const Pgsql::Value &v); + +enum class ForeignKeyMatch { + Full, // f + Partial, // p + Simple // s +}; + +void operator<<(ForeignKeyMatch &s, const Pgsql::Value &v); + +class PgConstraint { +public: + Oid oid = InvalidOid; + QString name; + Oid connamespace = InvalidOid; + ConstraintType type; + bool deferrable; + bool deferred; + bool validated; + Oid relid = InvalidOid; ///< the table this constraint is on + Oid typid = InvalidOid; + Oid indid = InvalidOid; ///< index supporting the constraint + Oid frelid = InvalidOid; ///< only for FK, referenced table pg_class + ForeignKeyAction fupdtype; // on update + ForeignKeyAction fdeltype; // on delete + ForeignKeyMatch fmatchtype; // match type + bool islocal; + int32_t inhcount; + bool noinherit; + std::vector key; // list of constraint columns attnum + std::vector fkey; // fkey list of referenced columns + std::vector pfeqop; + std::vector ppeqop; + std::vector ffeqop; + std::vector exclop; + QString bin; + QString src; + + QString definition; + + PgConstraint(); + 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 PgConstraint &rhs) const { return oid < rhs.oid; } +}; + +#endif // PGCONSTRAINT_H diff --git a/pglab/PgConstraintContainer.cpp b/pglab/PgConstraintContainer.cpp new file mode 100644 index 0000000..275a93c --- /dev/null +++ b/pglab/PgConstraintContainer.cpp @@ -0,0 +1,49 @@ +#include "PgConstraintContainer.h" +#include "Pgsql_Col.h" + +std::string PgConstraintContainer::getLoadQuery() const +{ + std::string q = R"__( +SELECT oid, conname, connamespace, contype, condeferrable, + condeferred, convalidated, conrelid, contypid, conindid, + confrelid, confupdtype, confdeltype, confmatchtype, + conislocal, coninhcount, connoinherit, conkey, confkey, + conpfeqop, conppeqop, conffeqop, conexclop, conbin, consrc, + pg_get_constraintdef(oid) +FROM pg_constraint)__"; + +// auto cat = m_catalogue.lock(); +// if (cat && cat->serverVersion() >= 90400) +// q += ", indisreplident "; +// q += "\nFROM pg_index"; + return q; +} + +//void operator<<(std::vector &s, const Pgsql::Value &v) +//{ + +//} + +//void operator<<(std::vector &s, const Pgsql::Value &v) +//{ + +//} + + +PgConstraint PgConstraintContainer::loadElem(const Pgsql::Row &row) +{ + Pgsql::Col col(row); + PgConstraint v; + 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)); + col.getAsArray(std::back_inserter(v.fkey)); + col.getAsArray(std::back_inserter(v.pfeqop)); + col.getAsArray(std::back_inserter(v.ppeqop)); + col.getAsArray(std::back_inserter(v.ffeqop)); + col.getAsArray(std::back_inserter(v.exclop)); + col >> v.bin >> v.src >> v.definition; + return v; +} diff --git a/pglab/PgConstraintContainer.h b/pglab/PgConstraintContainer.h new file mode 100644 index 0000000..6dc8a00 --- /dev/null +++ b/pglab/PgConstraintContainer.h @@ -0,0 +1,20 @@ +#ifndef PGCONSTRAINTCONTAINER_H +#define PGCONSTRAINTCONTAINER_H + +#include "PgContainer.h" +#include "PgConstraint.h" +#include "Pgsql_declare.h" +#include + +class PgConstraintContainer : public PgContainer { +public: + using PgContainer::PgContainer; + + virtual std::string getLoadQuery() const override; + //std::vector getIndexesForTable(Oid table_oid) const; +protected: + virtual PgConstraint loadElem(const Pgsql::Row &row) override; +}; + + +#endif // PGCONSTRAINTCONTAINER_H diff --git a/pglab/pglab.pro b/pglab/pglab.pro index 9bfd6d5..11e507e 100644 --- a/pglab/pglab.pro +++ b/pglab/pglab.pro @@ -80,7 +80,9 @@ SOURCES += main.cpp\ PgContainer.cpp \ PgAttributeContainer.cpp \ PgIndex.cpp \ - PgIndexContainer.cpp + PgIndexContainer.cpp \ + PgConstraint.cpp \ + PgConstraintContainer.cpp HEADERS += \ QueryResultModel.h \ @@ -132,7 +134,9 @@ HEADERS += \ PgAttribute.h \ PgAttributeContainer.h \ PgIndex.h \ - PgIndexContainer.h + PgIndexContainer.h \ + PgConstraint.h \ + PgConstraintContainer.h FORMS += mainwindow.ui \ DatabaseWindow.ui \