#include "PgClass.h" #include "PgAttributeContainer.h" #include "PgClassContainer.h" #include "PgDatabaseCatalog.h" #include "PgConstraintContainer.h" #include "PgInheritsContainer.h" #include #include "SqlFormattingUtils.h" void operator<<(RelPersistence &s, const Pgsql::Value &v) { //s = static_cast(v); const char *c = v.c_str(); switch (*c) { case 'p': s = RelPersistence::Permanent; break; case 'u': s = RelPersistence::Unlogged; break; case 't': s = RelPersistence::Temporary; break; } } void operator<<(RelKind &s, const Pgsql::Value &v) { //s = static_cast(v); const char *c = v.c_str(); switch (*c) { case 'r': s = RelKind::Table; break; case 'i': s = RelKind::Index; break; case 'S': s = RelKind::Sequence; break; case 'v': s = RelKind::View; break; case 'm': s = RelKind::MaterializedView; break; case 'c': s = RelKind::Composite; break; case 't': s = RelKind::Toast; break; case 'f': s = RelKind::ForeignTable; break; } } //QString PgClass::objectName() const //{ // return name; //} QString PgClass::createSql() const { if (createSqlCache.isEmpty()) { if (kind == RelKind::Table) createSqlCache = createTableSql(); else if (kind == RelKind::View) createSqlCache = createViewSql(); } return createSqlCache; } QString PgClass::typeName() const { switch (kind) { case RelKind::Table: return "TABLE"; case RelKind::Index: return "INDEX"; case RelKind::Sequence: return "SEQUENCE"; case RelKind::View: return "VIEW"; case RelKind::MaterializedView: return "MATERIALIZED VIEW"; case RelKind::Composite: return "COMPOSITE"; case RelKind::Toast: return "TOAST"; case RelKind::ForeignTable: return "FOREIGN TABLE"; } throw std::runtime_error("Unexpected value in PgClass::typeName()"); } QString PgClass::aclAllPattern() const { switch (kind) { case RelKind::Table: return "arwdDxt"; default: break; } return {}; } QString PgClass::createTableSql() const { QString sql; // CREATE [ TEMP | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [ sql += "CREATE "; if (persistence == RelPersistence::Unlogged) sql += "UNLOGGED "; else if (persistence == RelPersistence::Temporary) sql += "TEMP "; sql += "TABLE "; sql += fullyQualifiedQuotedObjectName(); sql += " (\n "; auto && cols = catalog().attributes()->getColumnsForRelation(oid()); bool first = true; for (auto && col : cols) { if (col.num > 0 && !col.isdropped) { if (first) { sql += "\n "; first = false; } else sql += ",\n "; if (!col.islocal) sql += "-- "; sql += col.columnDefinition(catalog()); } // { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ] // | table_constraint // ] ) } auto && constraints = catalog().constraints()->getConstraintsForRelation(oid()); for (auto && constraint: constraints) { if (first) { sql += "\n "; first = false; } else sql += ",\n "; sql += getConstraintDefinition(catalog(), constraint); } sql += ")"; { // [ 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 } ] // [ TABLESPACE tablespace_name ] sql += ";\n"; return sql; } QString PgClass::createViewSql() const { QString sql; sql += "CREATE OR REPLACE VIEW " + fullyQualifiedQuotedObjectName(); // todo security_barrier // todo check_option sql += " AS \n"; sql += viewdef; // todo owner return sql; }