WIP: SQL for creating table and related objects
This commit is contained in:
parent
57217974f4
commit
498233d58c
15 changed files with 221 additions and 121 deletions
|
|
@ -1,4 +1,10 @@
|
|||
#include "PgClass.h"
|
||||
#include "PgAttributeContainer.h"
|
||||
#include "PgDatabaseCatalog.h"
|
||||
#include "PgConstraintContainer.h"
|
||||
#include <QStringBuilder>
|
||||
#include "SqlFormattingUtils.h"
|
||||
|
||||
|
||||
|
||||
void operator<<(RelPersistence &s, const Pgsql::Value &v)
|
||||
|
|
@ -54,3 +60,61 @@ void operator<<(RelKind &s, const Pgsql::Value &v)
|
|||
//{
|
||||
// return name;
|
||||
//}
|
||||
|
||||
QString PgClass::createSql() const
|
||||
{
|
||||
if (createSqlCache.isEmpty()) {
|
||||
if (kind == RelKind::Table)
|
||||
createSqlCache = createTableSql();
|
||||
|
||||
}
|
||||
return createSqlCache;
|
||||
}
|
||||
|
||||
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 ";
|
||||
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 [, ... ] ) ]
|
||||
// [ 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,12 @@ public:
|
|||
// bool operator<(Oid _oid) const { return oid < _oid; }
|
||||
// bool operator<(const PgClass &rhs) const { return oid < rhs.oid; }
|
||||
|
||||
QString createSql() const;
|
||||
|
||||
private:
|
||||
mutable QString createSqlCache;
|
||||
|
||||
QString createTableSql() const;
|
||||
};
|
||||
|
||||
#endif // PGCLASS_H
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ QString ForeignKeyMatchToString(ForeignKeyMatch fkm)
|
|||
}
|
||||
|
||||
|
||||
PgConstraint::PgConstraint()
|
||||
{
|
||||
//PgConstraint::PgConstraint()
|
||||
//{
|
||||
|
||||
}
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef PGCONSTRAINT_H
|
||||
#define PGCONSTRAINT_H
|
||||
|
||||
#include "PgNamespaceObject.h"
|
||||
#include "Pgsql_Value.h"
|
||||
#include "PgCatalogTypes.h"
|
||||
#include <QString>
|
||||
|
|
@ -46,11 +47,8 @@ void operator<<(ForeignKeyMatch &s, const Pgsql::Value &v);
|
|||
|
||||
QString ForeignKeyMatchToString(ForeignKeyMatch fkm);
|
||||
|
||||
class PgConstraint {
|
||||
class PgConstraint: public PgNamespaceObject {
|
||||
public:
|
||||
Oid oid = InvalidOid;
|
||||
QString name;
|
||||
Oid connamespace = InvalidOid;
|
||||
ConstraintType type;
|
||||
bool deferrable;
|
||||
bool deferred;
|
||||
|
|
@ -76,11 +74,7 @@ public:
|
|||
|
||||
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; }
|
||||
using PgNamespaceObject::PgNamespaceObject;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,25 +20,17 @@ FROM pg_constraint)__";
|
|||
return q;
|
||||
}
|
||||
|
||||
//void operator<<(std::vector<int16_t> &s, const Pgsql::Value &v)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//void operator<<(std::vector<Oid> &s, const Pgsql::Value &v)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
PgConstraint PgConstraintContainer::loadElem(const Pgsql::Row &row)
|
||||
{
|
||||
using namespace Pgsql;
|
||||
Col col(row);
|
||||
PgConstraint v;
|
||||
col >> v.oid >> v.name >> v.connamespace >> v.type >> v.deferrable
|
||||
Oid oid = col.nextValue();
|
||||
QString name = col.nextValue();
|
||||
Oid ns_oid = col.nextValue();
|
||||
PgConstraint v(m_catalog, oid, name, ns_oid);
|
||||
col >> 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
|
||||
|
|
|
|||
|
|
@ -42,16 +42,6 @@ QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
|||
return name;
|
||||
}
|
||||
|
||||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
{
|
||||
QString result;
|
||||
auto nss = cat.namespaces();
|
||||
auto ns = nss->getByKey(oid);
|
||||
if (ns)
|
||||
result = ns->objectName(); //QString("ns %1").arg(oid);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString getClassDisplayString(const PgDatabaseCatalog &cat, Oid oid)
|
||||
{
|
||||
QString result;
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ private:
|
|||
|
||||
QString getRoleNameFromOid(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getRoleDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getNamespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getTablespaceDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
QString getTypeDisplayString(const PgDatabaseCatalog &cat, Oid oid, int32_t typmod = -1);
|
||||
QString getIndexDisplayString(const PgDatabaseCatalog &cat, Oid oid);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "PgDatabaseCatalog.h"
|
||||
#include "PgClassContainer.h"
|
||||
#include "PgAmContainer.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
QString PgIndex::getAm() const
|
||||
{
|
||||
|
|
@ -15,3 +16,62 @@ QString PgIndex::getAm() const
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString PgIndex::createSql() const
|
||||
{
|
||||
return definition + ";";
|
||||
|
||||
// const PgClass *table_class = catalog.classes()->getByKey(index.relid);
|
||||
// const PgClass *index_class = catalog.classes()->getByKey(index.indexrelid);
|
||||
|
||||
// QString result;
|
||||
// result = "CREATE ";
|
||||
// if (index.isunique)
|
||||
// result += "UNIQUE ";
|
||||
// result += "INDEX "
|
||||
//// % quoteIdent(getIndexDisplayString(catalog, index.indexrelid))
|
||||
// % quoteIdent(index_class.name)
|
||||
// % "\n ON " % genFQTableName(catalog, table_class);
|
||||
//// % "\n USING " % index_class.am lookup in pg_am table
|
||||
// return result;
|
||||
|
||||
#if 0
|
||||
+ wxT("\n USING ") + GetIndexType()
|
||||
+ wxT("\n (");
|
||||
if (GetProcName().IsNull())
|
||||
str += GetQuotedColumns();
|
||||
else
|
||||
{
|
||||
str += GetQuotedSchemaPrefix(GetProcNamespace()) + qtIdent(GetProcName()) + wxT("(") + GetQuotedColumns() + wxT(")");
|
||||
if (!this->GetOperatorClasses().IsNull())
|
||||
str += wxT(" ") + GetOperatorClasses();
|
||||
}
|
||||
|
||||
str += wxT(")");
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0)
|
||||
str += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")");
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace())
|
||||
str += wxT("\nTABLESPACE ") + qtIdent(tablespace);
|
||||
|
||||
AppendIfFilled(str, wxT("\n WHERE "), GetConstraint());
|
||||
|
||||
str += wxT(";\n");
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(7, 5))
|
||||
if (GetIsClustered())
|
||||
str += wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable())
|
||||
+ wxT(" CLUSTER ON ") + qtIdent(GetName())
|
||||
+ wxT(";\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
QString PgIndex::dropSql() const
|
||||
{
|
||||
QString result;
|
||||
result = "DROP INDEX "
|
||||
% fullyQualifiedQuotedObjectName()
|
||||
% ";";
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ public:
|
|||
// //bool operator==(const QString &n) const { return name == n; }
|
||||
// bool operator<(Oid _oid) const { return indexrelid < _oid; }
|
||||
// bool operator<(const PgIndex &rhs) const { return indexrelid < rhs.indexrelid; }
|
||||
|
||||
QString createSql() const;
|
||||
QString dropSql() const;
|
||||
};
|
||||
|
||||
#endif // PGINDEX_H
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ QString dollarQuoteString(const QString &value)
|
|||
// return ns->quotedObjectName() % "." % cls.quotedObjectName();
|
||||
//}
|
||||
|
||||
QString genAlterTable(const PgDatabaseCatalog &catalog, const PgClass &cls)
|
||||
QString genAlterTable(const PgDatabaseCatalog &, const PgClass &cls)
|
||||
{
|
||||
return "ALTER TABLE " % cls.fullyQualifiedQuotedObjectName(); // genFQTableName(catalog, cls);
|
||||
}
|
||||
|
|
@ -269,7 +269,7 @@ QString genAlterTable(const PgDatabaseCatalog &catalog, const PgClass &cls)
|
|||
QString getDropConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint)
|
||||
{
|
||||
const PgClass *cls = catalog.classes()->getByKey(constraint.relid);
|
||||
return genAlterTable(catalog, *cls) % " DROP CONSTRAINT " % quoteIdent(constraint.name) % ";";
|
||||
return genAlterTable(catalog, *cls) % " DROP CONSTRAINT " % quoteIdent(constraint.objectName()) % ";";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -368,7 +368,7 @@ QString getForeignKeyConstraintReferencesShort(const PgDatabaseCatalog &catalog,
|
|||
QString getPrimaryKeyConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint)
|
||||
{
|
||||
QString ddl = " PRIMARY KEY ("
|
||||
% getColumnNameList(catalog, constraint.relid, constraint.key) % ");";
|
||||
% getColumnNameList(catalog, constraint.relid, constraint.key) % ")";
|
||||
|
||||
return ddl;
|
||||
}
|
||||
|
|
@ -376,18 +376,22 @@ QString getPrimaryKeyConstraintDefinition(const PgDatabaseCatalog &catalog, cons
|
|||
QString getUniqueConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint)
|
||||
{
|
||||
QString ddl = " UNIQUE ("
|
||||
% getColumnNameList(catalog, constraint.relid, constraint.key) % ");";
|
||||
% getColumnNameList(catalog, constraint.relid, constraint.key) % ")";
|
||||
|
||||
return ddl;
|
||||
}
|
||||
|
||||
QString getConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint)
|
||||
QString getAlterTableConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint)
|
||||
{
|
||||
const PgClass *cls = catalog.classes()->getByKey(constraint.relid);
|
||||
// return genAlterTable(catalog, cls) % " ADD CONSTRAINT "
|
||||
// % quoteIdent(constraint.name) % " " % constraint.definition % ";";
|
||||
QString result = genAlterTable(catalog, *cls) % "\n ADD CONSTRAINT "
|
||||
% quoteIdent(constraint.name);
|
||||
QString result = genAlterTable(catalog, *cls) % "\n ADD ";
|
||||
result += getConstraintDefinition(catalog, constraint) % ";";
|
||||
return result;
|
||||
}
|
||||
|
||||
QString getConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint)
|
||||
{
|
||||
QString result = "CONSTRAINT " % quoteIdent(constraint.objectName());
|
||||
switch (constraint.type) {
|
||||
case ConstraintType::ForeignKey:
|
||||
result += getForeignKeyConstraintDefinition(catalog, constraint);
|
||||
|
|
@ -406,66 +410,4 @@ QString getConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstr
|
|||
return result;
|
||||
}
|
||||
|
||||
QString getIndexDefinition(const PgDatabaseCatalog &, const PgIndex &index)
|
||||
{
|
||||
// const PgClass *table_class = catalog.classes()->getByKey(index.relid);
|
||||
// const PgClass *index_class = catalog.classes()->getByKey(index.indexrelid);
|
||||
|
||||
|
||||
return index.definition + ";";
|
||||
|
||||
// QString result;
|
||||
// result = "CREATE ";
|
||||
// if (index.isunique)
|
||||
// result += "UNIQUE ";
|
||||
// result += "INDEX "
|
||||
//// % quoteIdent(getIndexDisplayString(catalog, index.indexrelid))
|
||||
// % quoteIdent(index_class.name)
|
||||
// % "\n ON " % genFQTableName(catalog, table_class);
|
||||
//// % "\n USING " % index_class.am lookup in pg_am table
|
||||
// return result;
|
||||
|
||||
#if 0
|
||||
+ wxT("\n USING ") + GetIndexType()
|
||||
+ wxT("\n (");
|
||||
if (GetProcName().IsNull())
|
||||
str += GetQuotedColumns();
|
||||
else
|
||||
{
|
||||
str += GetQuotedSchemaPrefix(GetProcNamespace()) + qtIdent(GetProcName()) + wxT("(") + GetQuotedColumns() + wxT(")");
|
||||
if (!this->GetOperatorClasses().IsNull())
|
||||
str += wxT(" ") + GetOperatorClasses();
|
||||
}
|
||||
|
||||
str += wxT(")");
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0)
|
||||
str += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")");
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace())
|
||||
str += wxT("\nTABLESPACE ") + qtIdent(tablespace);
|
||||
|
||||
AppendIfFilled(str, wxT("\n WHERE "), GetConstraint());
|
||||
|
||||
str += wxT(";\n");
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(7, 5))
|
||||
if (GetIsClustered())
|
||||
str += wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable())
|
||||
+ wxT(" CLUSTER ON ") + qtIdent(GetName())
|
||||
+ wxT(";\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
QString getDropIndexDefinition(const PgDatabaseCatalog &catalog, const PgIndex &index)
|
||||
{
|
||||
// const PgClass *table_class = catalog.classes()->getByKey(index.relid);
|
||||
// const PgClass *index_class = catalog.classes()->getByKey(index.indexrelid);
|
||||
|
||||
QString result;
|
||||
result = "DROP INDEX "
|
||||
% index.fullyQualifiedQuotedObjectName() // quoteIdent(getIndexDisplayString(catalog, index.indexrelid))
|
||||
% ";";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,8 @@ QString dollarQuoteString(const QString &value);
|
|||
|
||||
//QString genFQTableName(const PgDatabaseCatalog &catalog, const PgClass &cls);
|
||||
QString getDropConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint);
|
||||
QString getAlterTableConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint);
|
||||
QString getConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint);
|
||||
QString getIndexDefinition(const PgDatabaseCatalog &catalog, const PgIndex &index);
|
||||
QString getDropIndexDefinition(const PgDatabaseCatalog &catalog, const PgIndex &index);
|
||||
/// Returns the foreignKey specific part of the constraint definition
|
||||
QString getForeignKeyConstraintDefinition(const PgDatabaseCatalog &catalog, const PgConstraint &constraint);
|
||||
/// Returns the REFERENCES construct as used directly after a column in the create table statement
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue