2017-08-23 13:27:23 +02:00
|
|
|
|
#include "PgClass.h"
|
2018-11-30 18:41:38 +01:00
|
|
|
|
#include "PgAttributeContainer.h"
|
2018-12-03 21:03:49 +01:00
|
|
|
|
#include "PgClassContainer.h"
|
2018-11-30 18:41:38 +01:00
|
|
|
|
#include "PgDatabaseCatalog.h"
|
|
|
|
|
|
#include "PgConstraintContainer.h"
|
2018-12-03 21:03:49 +01:00
|
|
|
|
#include "PgInheritsContainer.h"
|
2018-11-30 18:41:38 +01:00
|
|
|
|
#include <QStringBuilder>
|
|
|
|
|
|
#include "SqlFormattingUtils.h"
|
|
|
|
|
|
|
2017-02-01 18:01:02 +01:00
|
|
|
|
|
2018-11-25 19:45:06 +01:00
|
|
|
|
|
2017-12-10 10:35:46 +01:00
|
|
|
|
void operator<<(RelPersistence &s, const Pgsql::Value &v)
|
|
|
|
|
|
{
|
|
|
|
|
|
//s = static_cast<T>(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<T>(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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-11-25 19:45:06 +01:00
|
|
|
|
|
|
|
|
|
|
//QString PgClass::objectName() const
|
|
|
|
|
|
//{
|
|
|
|
|
|
// return name;
|
|
|
|
|
|
//}
|
2018-11-30 18:41:38 +01:00
|
|
|
|
|
|
|
|
|
|
QString PgClass::createSql() const
|
|
|
|
|
|
{
|
|
|
|
|
|
if (createSqlCache.isEmpty()) {
|
|
|
|
|
|
if (kind == RelKind::Table)
|
|
|
|
|
|
createSqlCache = createTableSql();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
return createSqlCache;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-24 11:31:56 +01:00
|
|
|
|
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()");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-27 12:07:19 +01:00
|
|
|
|
QString PgClass::aclAllPattern() const
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (kind) {
|
|
|
|
|
|
case RelKind::Table: return "arwdDxt";
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-30 18:41:38 +01:00
|
|
|
|
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 ";
|
2018-12-03 21:03:49 +01:00
|
|
|
|
if (!col.islocal) sql += "-- ";
|
2018-11-30 18:41:38 +01:00
|
|
|
|
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 += ")";
|
2018-12-03 21:03:49 +01:00
|
|
|
|
{
|
|
|
|
|
|
// [ 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 += ")";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-11-30 18:41:38 +01:00
|
|
|
|
// [ 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;
|
|
|
|
|
|
}
|