From 323a6bb34b6573efe2082edd091148637eaacf92 Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Thu, 29 Sep 2022 14:32:42 +0200 Subject: [PATCH] Refactor RDBMS DDL --- store/adapters/rdbms/ddl/commands.go | 65 ++++++++++--------- .../rdbms/drivers/mysql/data_definer.go | 23 ++++--- .../rdbms/drivers/postgres/data_definer.go | 21 +++--- .../rdbms/drivers/sqlite/data_definer.go | 23 ++++--- store/adapters/rdbms/upgrade.go | 11 ++-- store/adapters/rdbms/upgrade_fixes.go | 8 +-- 6 files changed, 82 insertions(+), 69 deletions(-) diff --git a/store/adapters/rdbms/ddl/commands.go b/store/adapters/rdbms/ddl/commands.go index ce9ebfc2e..8250792df 100644 --- a/store/adapters/rdbms/ddl/commands.go +++ b/store/adapters/rdbms/ddl/commands.go @@ -53,22 +53,6 @@ type ( } ) -func CreateIndexTemplates(base *CreateIndex, ii ...*Index) []any { - var ( - tt = make([]any, len(ii)) - ) - - for i := range ii { - tt[i] = &CreateIndex{ - Index: ii[i], - OmitIfNotExistsClause: base.OmitIfNotExistsClause, - OmitFieldLength: base.OmitFieldLength, - } - } - - return tt -} - // Exec is a utility for executing series of commands // // Parameters can be string, Stringer interface or goqu's exp.SQLExpression @@ -82,15 +66,15 @@ func Exec(ctx context.Context, db sqlx.ExtContext, ss ...any) (err error) { ) switch c := s.(type) { - case string: - sql = c - case fmt.Stringer: - sql = c.String() - case exp.SQLExpression: + case interface{ ToSQL() (string, []any, error) }: sql, args, err = c.ToSQL() if err != nil { return } + case fmt.Stringer: + sql = c.String() + case string: + sql = c default: panic(fmt.Sprintf("unexecutable input (%T)", s)) } @@ -238,29 +222,50 @@ func (t *CreateIndex) String() string { return sql } -func (c *AddColumn) String() string { - sql := "ALTER TABLE" + " " + c.Table + " ADD COLUMN " + c.Column.Ident + " " + c.Column.Type.Name +func (c *AddColumn) ToSQL() (sql string, aa []interface{}, err error) { + sql = fmt.Sprintf( + `ALTER TABLE %s ADD COLUMN %s %s`, + c.Dialect.QuoteIdent(c.Table), + c.Dialect.QuoteIdent(c.Column.Ident), + c.Column.Type.Name, + ) + if !c.Column.Type.Null { sql += " NOT NULL" } if len(c.Column.Default) > 0 { + // @todo right now we can (and need to) trust that default + // values are unharmful! sql += " DEFAULT " + c.Column.Default } - return sql + return } -func (c *DropColumn) String() string { - return "ALTER TABLE" + " " + c.Table + " DROP COLUMN " + c.Column +func (c *DropColumn) ToSQL() (sql string, aa []interface{}, err error) { + return fmt.Sprintf( + `ALTER TABLE %s DROP COLUMN %s`, + c.Dialect.QuoteIdent(c.Table), + c.Dialect.QuoteIdent(c.Column), + ), nil, nil } -func (c *DropIndex) Express() exp.SQLExpression { - return SQLExpression(exp.NewLiteralExpression("DROP INDEX ? ON ?", c.Ident, c.TableIdent)) +func (c *DropIndex) ToSQL() (sql string, aa []interface{}, err error) { + return fmt.Sprintf( + `DROP INDEX %s ON %s`, + c.Dialect.QuoteIdent(c.Ident), + c.Dialect.QuoteIdent(c.TableIdent), + ), nil, nil } -func (c *RenameColumn) String() string { - return "ALTER TABLE" + " " + c.Table + " RENAME COLUMN " + c.Old + " TO " + c.New +func (c *RenameColumn) ToSQL() (sql string, aa []interface{}, err error) { + return fmt.Sprintf( + `ALTER TABLE %s RENAME %s TO %s`, + c.Dialect.QuoteIdent(c.Table), + c.Dialect.QuoteIdent(c.Old), + c.Dialect.QuoteIdent(c.New), + ), nil, nil } // GetBool is a utility function to simplify getting a boolean value from a query result. diff --git a/store/adapters/rdbms/drivers/mysql/data_definer.go b/store/adapters/rdbms/drivers/mysql/data_definer.go index 94a1eb6a4..98eb7b2c6 100644 --- a/store/adapters/rdbms/drivers/mysql/data_definer.go +++ b/store/adapters/rdbms/drivers/mysql/data_definer.go @@ -58,8 +58,8 @@ func (dd *dataDefiner) ConvertAttribute(attr *dal.Attribute) (*ddl.Column, error func (dd *dataDefiner) TableCreate(ctx context.Context, t *ddl.Table) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateTable{ - Table: t, Dialect: dd.d, + Table: t, OmitIfNotExistsClause: true, }) } @@ -70,23 +70,26 @@ func (dd *dataDefiner) TableLookup(ctx context.Context, t string) (*ddl.Table, e func (dd *dataDefiner) ColumnAdd(ctx context.Context, t string, c *ddl.Column) error { return ddl.Exec(ctx, dd.conn, &ddl.AddColumn{ - Table: dd.d.QuoteIdent(t), - Column: c, + Dialect: dd.d, + Table: t, + Column: c, }) } func (dd *dataDefiner) ColumnDrop(ctx context.Context, t, col string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropColumn{ - Table: dd.d.QuoteIdent(t), - Column: dd.d.QuoteIdent(col), + Dialect: dd.d, + Table: t, + Column: col, }) } func (dd *dataDefiner) ColumnRename(ctx context.Context, t string, o string, n string) error { return ddl.Exec(ctx, dd.conn, &ddl.RenameColumn{ - Table: dd.d.QuoteIdent(t), - Old: dd.d.QuoteIdent(o), - New: dd.d.QuoteIdent(n), + Dialect: dd.d, + Table: t, + Old: o, + New: n, }) } @@ -100,16 +103,16 @@ func (dd *dataDefiner) IndexLookup(ctx context.Context, i, t string) (*ddl.Index func (dd *dataDefiner) IndexCreate(ctx context.Context, t string, i *ddl.Index) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateIndex{ - Index: i, Dialect: dd.d, + Index: i, OmitIfNotExistsClause: true, }) } func (dd *dataDefiner) IndexDrop(ctx context.Context, t, i string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropIndex{ - Ident: dd.d.QuoteIdent(i), Dialect: dd.d, + Ident: i, }) } diff --git a/store/adapters/rdbms/drivers/postgres/data_definer.go b/store/adapters/rdbms/drivers/postgres/data_definer.go index 93f6e53ce..b5d25f3fd 100644 --- a/store/adapters/rdbms/drivers/postgres/data_definer.go +++ b/store/adapters/rdbms/drivers/postgres/data_definer.go @@ -48,23 +48,26 @@ func (dd *dataDefiner) TableLookup(ctx context.Context, t string) (*ddl.Table, e func (dd *dataDefiner) ColumnAdd(ctx context.Context, t string, c *ddl.Column) error { return ddl.Exec(ctx, dd.conn, &ddl.AddColumn{ - Table: dd.d.QuoteIdent(t), - Column: c, + Dialect: dd.d, + Table: t, + Column: c, }) } func (dd *dataDefiner) ColumnDrop(ctx context.Context, t, col string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropColumn{ - Table: dd.d.QuoteIdent(t), - Column: dd.d.QuoteIdent(col), + Dialect: dd.d, + Table: t, + Column: col, }) } func (dd *dataDefiner) ColumnRename(ctx context.Context, t string, o string, n string) error { return ddl.Exec(ctx, dd.conn, &ddl.RenameColumn{ - Table: dd.d.QuoteIdent(t), - Old: dd.d.QuoteIdent(o), - New: dd.d.QuoteIdent(n), + Dialect: dd.d, + Table: t, + Old: o, + New: n, }) } @@ -78,14 +81,14 @@ func (dd *dataDefiner) IndexLookup(ctx context.Context, i, t string) (*ddl.Index func (dd *dataDefiner) IndexCreate(ctx context.Context, t string, i *ddl.Index) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateIndex{ - Index: i, Dialect: dd.d, + Index: i, }) } func (dd *dataDefiner) IndexDrop(ctx context.Context, t, i string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropIndex{ - Ident: dd.d.QuoteIdent(i), Dialect: dd.d, + Ident: i, }) } diff --git a/store/adapters/rdbms/drivers/sqlite/data_definer.go b/store/adapters/rdbms/drivers/sqlite/data_definer.go index 69258a748..c37179f19 100644 --- a/store/adapters/rdbms/drivers/sqlite/data_definer.go +++ b/store/adapters/rdbms/drivers/sqlite/data_definer.go @@ -40,8 +40,8 @@ func (dd *dataDefiner) ConvertAttribute(attr *dal.Attribute) (*ddl.Column, error func (dd *dataDefiner) TableCreate(ctx context.Context, t *ddl.Table) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateTable{ - Table: t, Dialect: dd.d, + Table: t, }) } @@ -51,23 +51,26 @@ func (dd *dataDefiner) TableLookup(ctx context.Context, t string) (*ddl.Table, e func (dd *dataDefiner) ColumnAdd(ctx context.Context, t string, c *ddl.Column) error { return ddl.Exec(ctx, dd.conn, &ddl.AddColumn{ - Table: dd.d.QuoteIdent(t), - Column: c, + Dialect: dd.d, + Table: t, + Column: c, }) } func (dd *dataDefiner) ColumnDrop(ctx context.Context, t, col string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropColumn{ - Table: dd.d.QuoteIdent(t), - Column: dd.d.QuoteIdent(col), + Dialect: dd.d, + Table: t, + Column: col, }) } func (dd *dataDefiner) ColumnRename(ctx context.Context, t string, o string, n string) error { return ddl.Exec(ctx, dd.conn, &ddl.RenameColumn{ - Table: dd.d.QuoteIdent(t), - Old: dd.d.QuoteIdent(o), - New: dd.d.QuoteIdent(n), + Dialect: dd.d, + Table: t, + Old: o, + New: n, }) } @@ -81,14 +84,14 @@ func (dd *dataDefiner) IndexLookup(ctx context.Context, i, t string) (*ddl.Index func (dd *dataDefiner) IndexCreate(ctx context.Context, t string, i *ddl.Index) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateIndex{ - Index: i, Dialect: dd.d, + Index: i, }) } func (dd *dataDefiner) IndexDrop(ctx context.Context, t, i string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropIndex{ - Ident: dd.d.QuoteIdent(i), Dialect: dd.d, + Ident: i, }) } diff --git a/store/adapters/rdbms/upgrade.go b/store/adapters/rdbms/upgrade.go index b774b927f..c6c1ac424 100644 --- a/store/adapters/rdbms/upgrade.go +++ b/store/adapters/rdbms/upgrade.go @@ -14,6 +14,11 @@ import ( ) func (s *Store) Upgrade(ctx context.Context) (err error) { + for _, fix := range fixes { + if err = fix(ctx, s); err != nil { + return + } + } err = createTablesFromModels( ctx, @@ -29,12 +34,6 @@ func (s *Store) Upgrade(ctx context.Context) (err error) { return err } - for _, fix := range fixes { - if err = fix(ctx, s); err != nil { - return - } - } - return } diff --git a/store/adapters/rdbms/upgrade_fixes.go b/store/adapters/rdbms/upgrade_fixes.go index 654443cf2..e55880a51 100644 --- a/store/adapters/rdbms/upgrade_fixes.go +++ b/store/adapters/rdbms/upgrade_fixes.go @@ -32,14 +32,14 @@ var ( func fix_2022_09_00_extendComposeModuleForPrivacyAndDAL(ctx context.Context, s *Store) (err error) { return addColumn(ctx, s, "compose_module", - &dal.Attribute{Ident: "config", Type: &dal.TypeJSON{DefaultValue: "'{}'"}}, + &dal.Attribute{Ident: "config", Type: &dal.TypeJSON{DefaultValue: "{}"}}, ) } func fix_2022_09_00_extendComposeModuleFieldsForPrivacyAndDAL(ctx context.Context, s *Store) (err error) { return addColumn(ctx, s, "compose_module", - &dal.Attribute{Ident: "config", Type: &dal.TypeJSON{DefaultValue: "'{}'"}}, + &dal.Attribute{Ident: "config", Type: &dal.TypeJSON{DefaultValue: "{}"}}, ) } @@ -54,7 +54,7 @@ func fix_2022_09_00_dropObsoleteComposeModuleFields(ctx context.Context, s *Stor func fix_2022_09_00_extendDalConnectionsForMeta(ctx context.Context, s *Store) (err error) { return addColumn(ctx, s, "dal_connections", - &dal.Attribute{Ident: "meta", Type: &dal.TypeJSON{DefaultValue: "'{}'"}}, + &dal.Attribute{Ident: "meta", Type: &dal.TypeJSON{DefaultValue: "{}"}}, ) } @@ -72,7 +72,7 @@ func fix_2022_09_00_addMetaOnComposeRecords(ctx context.Context, s *Store) (err err = addColumn(ctx, s, "compose_record", - &dal.Attribute{Ident: "meta", Type: &dal.TypeJSON{DefaultValue: "'{}'"}}, + &dal.Attribute{Ident: "meta", Type: &dal.TypeJSON{DefaultValue: "{}"}}, ) if err != nil {