diff --git a/store/adapters/rdbms/ddl/commands.go b/store/adapters/rdbms/ddl/commands.go index f55230cec..ce9ebfc2e 100644 --- a/store/adapters/rdbms/ddl/commands.go +++ b/store/adapters/rdbms/ddl/commands.go @@ -29,27 +29,27 @@ type ( DropIndex struct { Dialect dialect - Ident exp.IdentifierExpression - TableIdent exp.IdentifierExpression + Ident string + TableIdent string } AddColumn struct { Dialect dialect - Table exp.IdentifierExpression + Table string Column *Column } DropColumn struct { Dialect dialect - Table exp.IdentifierExpression - Column exp.IdentifierExpression + Table string + Column string } RenameColumn struct { Dialect dialect - Table exp.IdentifierExpression - Old exp.IdentifierExpression - New exp.IdentifierExpression + Table string + Old string + New string } ) @@ -238,30 +238,30 @@ func (t *CreateIndex) String() string { return sql } -//func (c *AddColumn) String() string { -// sql := "ALTER TABLE" + " " + c.Table + " ADD COLUMN " + c.Column.Name + " " + c.Column.Type -// if !c.Column.IsNull { -// sql += " NOT NULL" -// } -// -// if len(c.Column.DefaultValue) > 0 { -// sql += " DEFAULT " + c.Column.DefaultValue -// } -// -// return sql -//} +func (c *AddColumn) String() string { + sql := "ALTER TABLE" + " " + c.Table + " ADD COLUMN " + c.Column.Ident + " " + c.Column.Type.Name + if !c.Column.Type.Null { + sql += " NOT NULL" + } -//func (c *DropColumn) String() string { -// return "ALTER TABLE" + " " + c.Table.Name + " DROP COLUMN " + c.Column -//} + if len(c.Column.Default) > 0 { + sql += " DEFAULT " + c.Column.Default + } + + return sql +} + +func (c *DropColumn) String() string { + return "ALTER TABLE" + " " + c.Table + " DROP COLUMN " + c.Column +} func (c *DropIndex) Express() exp.SQLExpression { return SQLExpression(exp.NewLiteralExpression("DROP INDEX ? ON ?", c.Ident, c.TableIdent)) } -//func (c *RenameColumn) String() string { -// return "ALTER TABLE" + " " + c.Table.Name + " RENAME COLUMN " + c.Old + " TO " + c.New -//} +func (c *RenameColumn) String() string { + return "ALTER TABLE" + " " + c.Table + " RENAME COLUMN " + c.Old + " TO " + c.New +} // GetBool is a utility function to simplify getting a boolean value from a query result. func GetBool(ctx context.Context, db sqlx.QueryerContext, query exp.SQLExpression) (bool, error) { diff --git a/store/adapters/rdbms/ddl/data_definer.go b/store/adapters/rdbms/ddl/data_definer.go index cc54e4e2c..05575a811 100644 --- a/store/adapters/rdbms/ddl/data_definer.go +++ b/store/adapters/rdbms/ddl/data_definer.go @@ -19,6 +19,7 @@ type ( // DataDefiner describes an interface for all DDL commands DataDefiner interface { ConvertModel(*dal.Model) (*Table, error) + ConvertAttribute(attr *dal.Attribute) (*Column, error) // Tables(ctx context.Context) ([]*Table, error) TableLookup(context.Context, string) (*Table, error) @@ -158,9 +159,8 @@ func ConvertModel(m *dal.Model, d driverDialect) (t *Table, err error) { } } - col, err = d.AttributeToColumn(a) - if err != nil { - return nil, fmt.Errorf("could not convert attribute %q to column: %w", a.Ident, err) + if col, err = ConvertAttribute(a, d); err != nil { + return } t.Columns = append(t.Columns, col) @@ -177,6 +177,15 @@ func ConvertModel(m *dal.Model, d driverDialect) (t *Table, err error) { return } +func ConvertAttribute(attr *dal.Attribute, d driverDialect) (col *Column, err error) { + col, err = d.AttributeToColumn(attr) + if err != nil { + return nil, fmt.Errorf("could not convert attribute %q to column: %w", attr.Ident, err) + } + + return +} + // ConvertIndex converts dal.Index to ddl.Index func ConvertIndex(i *dal.Index, aa dal.AttributeSet, table string, d driverDialect) (idx *Index, err error) { var ( diff --git a/store/adapters/rdbms/drivers/mysql/data_definer.go b/store/adapters/rdbms/drivers/mysql/data_definer.go index d7924bb54..94a1eb6a4 100644 --- a/store/adapters/rdbms/drivers/mysql/data_definer.go +++ b/store/adapters/rdbms/drivers/mysql/data_definer.go @@ -3,8 +3,6 @@ package mysql import ( "context" "github.com/cortezaproject/corteza-server/pkg/dal" - "github.com/doug-martin/goqu/v9/exp" - "github.com/cortezaproject/corteza-server/store/adapters/rdbms/ddl" "github.com/jmoiron/sqlx" ) @@ -54,6 +52,10 @@ func (dd *dataDefiner) ConvertModel(m *dal.Model) (tbl *ddl.Table, err error) { return } +func (dd *dataDefiner) ConvertAttribute(attr *dal.Attribute) (*ddl.Column, error) { + return ddl.ConvertAttribute(attr, dd.d) +} + func (dd *dataDefiner) TableCreate(ctx context.Context, t *ddl.Table) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateTable{ Table: t, @@ -68,23 +70,23 @@ 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: exp.NewIdentifierExpression("", t, ""), + Table: dd.d.QuoteIdent(t), Column: c, }) } func (dd *dataDefiner) ColumnDrop(ctx context.Context, t, col string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropColumn{ - Table: exp.NewIdentifierExpression("", t, ""), - Column: exp.NewIdentifierExpression("", "", col), + Table: dd.d.QuoteIdent(t), + Column: dd.d.QuoteIdent(col), }) } func (dd *dataDefiner) ColumnRename(ctx context.Context, t string, o string, n string) error { return ddl.Exec(ctx, dd.conn, &ddl.RenameColumn{ - Table: exp.NewIdentifierExpression("", t, ""), - Old: exp.NewIdentifierExpression("", "", o), - New: exp.NewIdentifierExpression("", "", n), + Table: dd.d.QuoteIdent(t), + Old: dd.d.QuoteIdent(o), + New: dd.d.QuoteIdent(n), }) } @@ -106,7 +108,7 @@ func (dd *dataDefiner) IndexCreate(ctx context.Context, t string, i *ddl.Index) func (dd *dataDefiner) IndexDrop(ctx context.Context, t, i string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropIndex{ - Ident: exp.NewIdentifierExpression("", t, i), + Ident: dd.d.QuoteIdent(i), Dialect: dd.d, }) } diff --git a/store/adapters/rdbms/drivers/postgres/data_definer.go b/store/adapters/rdbms/drivers/postgres/data_definer.go index ead381f14..93f6e53ce 100644 --- a/store/adapters/rdbms/drivers/postgres/data_definer.go +++ b/store/adapters/rdbms/drivers/postgres/data_definer.go @@ -4,7 +4,6 @@ import ( "context" "github.com/cortezaproject/corteza-server/pkg/dal" "github.com/cortezaproject/corteza-server/store/adapters/rdbms/ddl" - "github.com/doug-martin/goqu/v9/exp" "github.com/jmoiron/sqlx" ) @@ -35,6 +34,10 @@ func (dd *dataDefiner) ConvertModel(m *dal.Model) (*ddl.Table, error) { return ddl.ConvertModel(m, dd.d) } +func (dd *dataDefiner) ConvertAttribute(attr *dal.Attribute) (*ddl.Column, error) { + return ddl.ConvertAttribute(attr, dd.d) +} + func (dd *dataDefiner) TableCreate(ctx context.Context, t *ddl.Table) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateTable{Table: t, Dialect: dd.d}) } @@ -45,25 +48,23 @@ 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: exp.NewIdentifierExpression("", t, ""), + Table: dd.d.QuoteIdent(t), Column: c, }) } func (dd *dataDefiner) ColumnDrop(ctx context.Context, t, col string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropColumn{ - Dialect: dd.d, - Table: exp.NewIdentifierExpression("", t, ""), - Column: exp.NewIdentifierExpression("", "", col), + Table: dd.d.QuoteIdent(t), + Column: dd.d.QuoteIdent(col), }) } func (dd *dataDefiner) ColumnRename(ctx context.Context, t string, o string, n string) error { return ddl.Exec(ctx, dd.conn, &ddl.RenameColumn{ - Dialect: dd.d, - Table: exp.NewIdentifierExpression("", t, ""), - Old: exp.NewIdentifierExpression("", "", o), - New: exp.NewIdentifierExpression("", "", n), + Table: dd.d.QuoteIdent(t), + Old: dd.d.QuoteIdent(o), + New: dd.d.QuoteIdent(n), }) } @@ -84,7 +85,7 @@ func (dd *dataDefiner) IndexCreate(ctx context.Context, t string, i *ddl.Index) func (dd *dataDefiner) IndexDrop(ctx context.Context, t, i string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropIndex{ - Ident: exp.NewIdentifierExpression("", t, i), + Ident: dd.d.QuoteIdent(i), Dialect: dd.d, }) } diff --git a/store/adapters/rdbms/drivers/sqlite/data_definer.go b/store/adapters/rdbms/drivers/sqlite/data_definer.go index 7053d9939..9a15b5c15 100644 --- a/store/adapters/rdbms/drivers/sqlite/data_definer.go +++ b/store/adapters/rdbms/drivers/sqlite/data_definer.go @@ -5,7 +5,6 @@ import ( "github.com/cortezaproject/corteza-server/pkg/dal" "github.com/cortezaproject/corteza-server/pkg/errors" "github.com/cortezaproject/corteza-server/store/adapters/rdbms/ddl" - "github.com/doug-martin/goqu/v9/exp" "github.com/jmoiron/sqlx" ) @@ -36,6 +35,10 @@ func (dd *dataDefiner) ConvertModel(m *dal.Model) (*ddl.Table, error) { return ddl.ConvertModel(m, dd.d) } +func (dd *dataDefiner) ConvertAttribute(attr *dal.Attribute) (*ddl.Column, error) { + return ddl.ConvertAttribute(attr, dd.d) +} + func (dd *dataDefiner) TableCreate(ctx context.Context, t *ddl.Table) error { return ddl.Exec(ctx, dd.conn, &ddl.CreateTable{ Table: t, @@ -50,23 +53,23 @@ 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: exp.NewIdentifierExpression("", t, ""), + Table: dd.d.QuoteIdent(t), Column: c, }) } func (dd *dataDefiner) ColumnDrop(ctx context.Context, t, col string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropColumn{ - Table: exp.NewIdentifierExpression("", t, ""), - Column: exp.NewIdentifierExpression("", "", col), + Table: dd.d.QuoteIdent(t), + Column: dd.d.QuoteIdent(col), }) } func (dd *dataDefiner) ColumnRename(ctx context.Context, t string, o string, n string) error { return ddl.Exec(ctx, dd.conn, &ddl.RenameColumn{ - Table: exp.NewIdentifierExpression("", t, ""), - Old: exp.NewIdentifierExpression("", "", o), - New: exp.NewIdentifierExpression("", "", n), + Table: dd.d.QuoteIdent(t), + Old: dd.d.QuoteIdent(o), + New: dd.d.QuoteIdent(n), }) } @@ -87,7 +90,7 @@ func (dd *dataDefiner) IndexCreate(ctx context.Context, t string, i *ddl.Index) func (dd *dataDefiner) IndexDrop(ctx context.Context, t, i string) error { return ddl.Exec(ctx, dd.conn, &ddl.DropIndex{ - Ident: exp.NewIdentifierExpression("", t, i), + Ident: dd.d.QuoteIdent(i), Dialect: dd.d, }) } diff --git a/store/adapters/rdbms/upgrade.go b/store/adapters/rdbms/upgrade.go index d8fb843d1..9c85aadcf 100644 --- a/store/adapters/rdbms/upgrade.go +++ b/store/adapters/rdbms/upgrade.go @@ -29,40 +29,12 @@ func (s *Store) Upgrade(ctx context.Context) (err error) { return err } - //var ( - // tableExists bool - //) - // - //for _, t := range Tables() { - // tableExists, err = s.SchemaAPI.TableExists(ctx, s.DB, t.Name) - // if err != nil { - // return fmt.Errorf("could not check table %q existance: %w", t.Name, err) - // } - // - // if !tableExists { - // s.log(ctx).Debug("creating table", zap.String("table", t.Name)) - // if err = s.SchemaAPI.CreateTable(ctx, s.DB, t); err != nil { - // return fmt.Errorf("could not create table %q: %w", t.Name, err) - // } - // } - //} - // - //fixes := []func(context.Context, *Store) error{ - // fix202209_extendComposeModuleForPrivacyAndDAL, - // fix202209_extendComposeModuleFieldsForPrivacyAndDAL, - // fix202209_dropObsoleteComposeModuleFields, - // fix202209_composeRecordRevisions, - // fix202209_extendDalConnectionsForMeta, - // fix202209_renameModuleColOnComposeRecords, - // fix202209_addMetaOnComposeRecords, - //} - // - //for _, fix := range fixes { - // if err = fix(ctx, s); err != nil { - // return - // } - //} - // + for _, fix := range fixes { + if err = fix(ctx, s); err != nil { + return + } + } + return } @@ -102,3 +74,67 @@ func createTablesFromModels(ctx context.Context, log *zap.Logger, dd ddl.DataDef return nil } + +func addColumn(ctx context.Context, s *Store, table string, attr *dal.Attribute) error { + tbl, err := s.DataDefiner.TableLookup(ctx, table) + if err != nil { + return err + } + + if tbl.ColumnByIdent(attr.StoreIdent()) != nil { + return nil + } + + s.log(ctx).Info(fmt.Sprintf("extending %q table with %q column", table, attr.StoreIdent())) + + col, err := s.DataDefiner.ConvertAttribute(attr) + if err != nil { + return err + } + + return s.DataDefiner.ColumnAdd(ctx, table, col) +} + +func dropColumns(ctx context.Context, s *Store, table string, cc ...string) error { + tbl, err := s.DataDefiner.TableLookup(ctx, table) + if err != nil { + return err + } + + for _, c := range cc { + if tbl.ColumnByIdent(c) == nil { + // column does not exist, nothing to do + continue + } + + s.log(ctx).Info(fmt.Sprintf("dropping %q column from %q", c, table)) + if err := s.DataDefiner.ColumnDrop(ctx, table, c); err != nil { + return err + } + } + return nil +} + +func renameColumn(ctx context.Context, s *Store, table string, from, to string) error { + tbl, err := s.DataDefiner.TableLookup(ctx, table) + if err != nil { + return err + } + + if tbl.ColumnByIdent(from) == nil { + // from column does not exist, nothing to do + return nil + } + + if tbl.ColumnByIdent(to) != nil { + // to column already exists, nothing to do + return nil + } + + s.log(ctx).Info(fmt.Sprintf("renaming %q column on table %q to %q", from, table, to)) + if err := s.DataDefiner.ColumnRename(ctx, table, from, to); err != nil { + return err + } + + return nil +} diff --git a/store/adapters/rdbms/upgrade_fixes.go b/store/adapters/rdbms/upgrade_fixes.go index 31e44e6ba..654443cf2 100644 --- a/store/adapters/rdbms/upgrade_fixes.go +++ b/store/adapters/rdbms/upgrade_fixes.go @@ -1,182 +1,114 @@ package rdbms -//func fix202209_extendComposeModuleForPrivacyAndDAL(ctx context.Context, s *Store) (err error) { -// s.log(ctx).Info("extending compose_module table with config column") -// return s.SchemaAPI.AddColumn( -// ctx, s.DB, -// "compose_module", -// &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "config"}, -// ) -//} -// -//func fix202209_extendComposeModuleFieldsForPrivacyAndDAL(ctx context.Context, s *Store) (err error) { -// s.log(ctx).Info("extending compose_module_field table with config column") -// return s.SchemaAPI.AddColumn( -// ctx, s.DB, -// "compose_module_field", -// &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "config"}, -// ) -//} -// -//func fix202209_dropObsoleteComposeModuleFields(ctx context.Context, s *Store) (err error) { -// s.log(ctx).Info("extending compose_module_field table with config column") -// return s.SchemaAPI.DropColumn( -// ctx, s.DB, -// "compose_module_field", -// "is_private", -// "is_visible", -// ) -//} -// -//func fix202209_composeRecordRevisions(ctx context.Context, s *Store) (err error) { -// s.log(ctx).Info("extending compose_record table with revision column") -// return s.SchemaAPI.AddColumn( -// ctx, s.DB, -// "compose_record", -// &Column{Type: ColumnType{Type: ColumnTypeInteger}, DefaultValue: "1", Name: "revision"}, -// ) +import ( + "context" + "encoding/json" + "github.com/cortezaproject/corteza-server/pkg/dal" + labelsType "github.com/cortezaproject/corteza-server/pkg/label/types" + "github.com/cortezaproject/corteza-server/store" + "go.uber.org/zap" +) -//return // will probably not need this... -//var ( -// log = s.log(ctx) -//) +// RDBMS database fixes // -//const ( -// envKeySkip = "UPGRADE_COMPOSE_RECORD_CHANGES_PREFILL_SKIP" +// Schema changes that can not be automatically applied or complex changes +// that require some logic to be applied are handled here. // -// tblChanges = "compose_record_changes" -// tblRecords = "compose_record" -//) -// -//if _, set := os.LookupEnv(envKeySkip); set { -// return -//} -// -//var ( -// tblRecordColumns = []any{ -// // reusing record ID for ID of the (1st record) -// // entry in the changes table -// "id", -// "id", -// "rel_namespace", "module_id", -// "values", -// "owned_by", -// "created_at", "created_by", -// "updated_at", "updated_by", -// "deleted_at", "deleted_by", -// } -// -// tblChangesColumns = []any{ -// "id", -// "rel_record", -// "rel_namespace", "rel_module", -// "values", -// "owned_by", -// "created_at", "created_by", -// "updated_at", "updated_by", -// "deleted_at", "deleted_by", -// } -// -// d = s.Dialect -// check = d.Select(exp.NewLiteralExpression("1")).From(tblChanges).Limit(1) -// count int -// -// copyAll = d. -// Insert(tblChanges). -// Cols(tblChangesColumns...). -// FromQuery(d.From(tblRecords).Select(tblRecordColumns...)) -//) -// -//if err = s.QueryOne(ctx, check, &count); err != nil { -// // exit on error or when changes table is not empty -// if !errors.IsNotFound(err) { -// return fmt.Errorf("could not check if %q is empty: %w", tblChanges, err) -// } -// -//} else if count > 0 { -// return -//} -// -//log.Warn(fmt.Sprintf("Empty %s table detected. "+ -// "Prefilling record changes table with current records, "+ -// "this might take a while, depending amount of records you have and how fast your database is. "+ -// "If you need to disable this, stop the server, set %s=1 "+ -// "and restart the server.", -// tblChanges, -// envKeySkip, -//)) -// -//spew.Dump(copyAll.ToSQL()) -// -//// make a copy of records to changes table -//return s.Exec(ctx, copyAll) -//} -// -//func fix202209_extendDalConnectionsForMeta(ctx context.Context, s *Store) (err error) { -// s.log(ctx).Info("extending dal_connections table with meta column") -// return s.SchemaAPI.AddColumn( -// ctx, s.DB, -// &Table{Name: "dal_connections"}, -// &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "meta"}, -// ) -//} -// -//func fix202209_renameModuleColOnComposeRecords(ctx context.Context, s *Store) (err error) { -// s.log(ctx).Info("rename module_id column on compose_record table") -// return s.SchemaAPI.RenameColumn( -// ctx, s.DB, &Table{Name: "compose_record"}, "module_id", "rel_module", -// ) -//} -// -//func fix202209_addMetaOnComposeRecords(ctx context.Context, s *Store) (err error) { -// var ( -// log = s.log(ctx) -// -// groupedMeta = make(map[uint64]map[string]any) -// packed []byte -// ) -// -// log.Info("add meta column on compose_record table") -// err = s.SchemaAPI.AddColumn( -// ctx, s.DB, -// &Table{Name: "compose_record"}, -// &Column{Type: ColumnType{Type: ColumnTypeJson}, DefaultValue: "'{}'", Name: "meta"}, -// ) -// -// if err != nil { -// return -// } -// -// return s.Tx(ctx, func(ctx context.Context, s store.Storer) (err error) { -// log.Info("collecting record labels") -// ll, _, err := store.SearchLabels(ctx, s, labelsType.LabelFilter{Kind: "compose:record"}) -// if err != nil { -// return -// } -// -// log.Info("grouping labels", zap.Int("count", len(ll))) -// for _, l := range ll { -// if _, has := groupedMeta[l.ResourceID]; !has { -// groupedMeta[l.ResourceID] = make(map[string]any) -// } -// -// groupedMeta[l.ResourceID][l.Name] = l.Value -// if err = store.DeleteLabel(ctx, s, l); err != nil { -// return -// } -// } -// -// log.Info("updating records with meta", zap.Int("count", len(ll))) -// for recordID, labels := range groupedMeta { -// packed, err = json.Marshal(labels) -// _, err = s.(*Store).DB.ExecContext(ctx, "UPDATE compose_record SET meta = $1 WHERE id = $2", packed, recordID) -// if err != nil { -// return -// } -// } -// -// return -// -// }) -// -//} +// Function names should start with "fix" and version. +// This does not have any effect on how fixes are executed, only for organisation purposes. + +var ( + // all enabled fix function need to be listed here + fixes = []func(context.Context, *Store) error{ + fix_2022_09_00_extendComposeModuleForPrivacyAndDAL, + fix_2022_09_00_extendComposeModuleFieldsForPrivacyAndDAL, + fix_2022_09_00_dropObsoleteComposeModuleFields, + fix_2022_09_00_extendDalConnectionsForMeta, + fix_2022_09_00_renameModuleColOnComposeRecords, + fix_2022_09_00_addMetaOnComposeRecords, + } +) + +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: "'{}'"}}, + ) +} + +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: "'{}'"}}, + ) +} + +func fix_2022_09_00_dropObsoleteComposeModuleFields(ctx context.Context, s *Store) (err error) { + return dropColumns(ctx, s, + "compose_module_field", + "is_private", + "is_visible", + ) +} + +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: "'{}'"}}, + ) +} + +func fix_2022_09_00_renameModuleColOnComposeRecords(ctx context.Context, s *Store) (err error) { + return renameColumn(ctx, s, "compose_record", "module_id", "rel_module") +} + +func fix_2022_09_00_addMetaOnComposeRecords(ctx context.Context, s *Store) (err error) { + var ( + log = s.log(ctx) + + groupedMeta = make(map[uint64]map[string]any) + packed []byte + ) + + err = addColumn(ctx, s, + "compose_record", + &dal.Attribute{Ident: "meta", Type: &dal.TypeJSON{DefaultValue: "'{}'"}}, + ) + + if err != nil { + return + } + + return s.Tx(ctx, func(ctx context.Context, s store.Storer) (err error) { + log.Info("collecting record labels") + ll, _, err := store.SearchLabels(ctx, s, labelsType.LabelFilter{Kind: "compose:record"}) + if err != nil { + return + } + + log.Info("grouping labels", zap.Int("count", len(ll))) + for _, l := range ll { + if _, has := groupedMeta[l.ResourceID]; !has { + groupedMeta[l.ResourceID] = make(map[string]any) + } + + groupedMeta[l.ResourceID][l.Name] = l.Value + if err = store.DeleteLabel(ctx, s, l); err != nil { + return + } + } + + log.Info("updating records with meta", zap.Int("count", len(ll))) + for recordID, labels := range groupedMeta { + packed, err = json.Marshal(labels) + _, err = s.(*Store).DB.ExecContext(ctx, "UPDATE compose_record SET meta = $1 WHERE id = $2", packed, recordID) + if err != nil { + return + } + } + + return + + }) + +} diff --git a/store/adapters/rdbms/upgrade_tables.go b/store/adapters/rdbms/upgrade_tables.go deleted file mode 100644 index 496aea481..000000000 --- a/store/adapters/rdbms/upgrade_tables.go +++ /dev/null @@ -1,765 +0,0 @@ -package rdbms - -const ( - handleLength = 64 - resourceLength = 512 - - // https://www.rfc-editor.org/errata/eid1690 - emailLength = 254 - - // Enough for IPv6, ports, delimiters, IPv4-mapped IPV6 addresses... - ipAddrLength = 64 - - // IETF language tag doesn't specify a hard limit (there can be a lot of modifiers) - // so I can't put a strict limit. - // Omiting the bits of the specs that don't have a limited length a size of 32 would suffice. - // Going a bit extra for future proofing - languageTagLength = 128 - - // Some keys may introduce generated identifiers which may cause the size - // to inflate. - languageKeyLength = 256 - - urlLength = 2048 - locationLength = 256 -) - -// Tables fn holds a list of all tables that need to be created -//func Tables() []*Table { -// return []*Table{ -// tableUsers(), -// tableDalConnections(), -// tableDalSensitivityLevels(), -// tableCredentials(), -// tableAuthClients(), -// tableAuthConfirmedClients(), -// tableAuthSessions(), -// tableAuthOA2Tokens(), -// tableRoles(), -// tableRoleMembers(), -// tableApplications(), -// tableReminders(), -// tableAttachments(), -// tableActionLog(), -// tableRbacRules(), -// tableSettings(), -// tableLabels(), -// tableFlags(), -// tableTemplates(), -// tableReports(), -// tableResourceTranslations(), -// tableComposeAttachment(), -// tableComposeChart(), -// tableComposeModule(), -// tableComposeModuleField(), -// tableComposeNamespace(), -// tableComposePage(), -// tableComposeRecord(), -// tableComposeRecordRevisions(), -// tableFederationModuleShared(), -// tableFederationModuleExposed(), -// tableFederationModuleMapping(), -// tableFederationNodes(), -// tableFederationNodesSync(), -// tableAutomationWorkflows(), -// tableAutomationTriggers(), -// tableAutomationSessions(), -// //tableAutomationState(), -// tableMessagebusQueue(), -// tableMessagebusQueuemessage(), -// tableApigwRoute(), -// tableApigwFilter(), -// tableResourceActivityLog(), -// tableDataPrivacyRequests(), -// tableDataPrivacyRequestComments(), -// } -//} - -//func tableUsers() *Table { -// return TableDef("users", -// ID, -// ColumnDef("email", ColumnTypeVarchar, ColumnTypeLength(emailLength)), -// ColumnDef("email_confirmed", ColumnTypeBoolean, DefaultValue("false")), -// ColumnDef("username", ColumnTypeText), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(8)), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("suspended_at", ColumnTypeTimestamp, Null), -// CUDTimestamps, -// -// AddIndex("unique_email", IExpr("LOWER(email)"), IWhere("LENGTH(email) > 0 AND deleted_at IS NULL AND suspended_at IS NULL")), -// AddIndex("unique_username", IExpr("LOWER(username)"), IWhere("LENGTH(username) > 0 AND deleted_at IS NULL AND suspended_at IS NULL")), -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL AND suspended_at IS NULL")), -// ) -//} -// -//func tableDalConnections() *Table { -// return TableDef("dal_connections", -// ID, -// -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("type", ColumnTypeText), -// -// ColumnDef("config", ColumnTypeJson), -// ColumnDef("meta", ColumnTypeJson), -// -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableDalSensitivityLevels() *Table { -// return TableDef("dal_sensitivity_levels", -// ID, -// -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("level", ColumnTypeInteger), -// -// ColumnDef("meta", ColumnTypeJson), -// -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableCredentials() *Table { -// return TableDef(`credentials`, -// ID, -// ColumnDef("rel_owner", ColumnTypeIdentifier), -// ColumnDef("label", ColumnTypeText), -// ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(128)), -// ColumnDef("credentials", ColumnTypeText), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("expires_at", ColumnTypeTimestamp, Null), -// ColumnDef("last_used_at", ColumnTypeTimestamp, Null), -// CUDTimestamps, -// -// AddIndex("owner_kind", IColumn("rel_owner", "kind"), IWhere("deleted_at IS NULL")), -// ) -//} -// -//func tableAuthClients() *Table { -// return TableDef(`auth_clients`, -// ID, -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("secret", ColumnTypeVarchar, ColumnTypeLength(64)), -// ColumnDef("scope", ColumnTypeVarchar, ColumnTypeLength(512)), -// ColumnDef("valid_grant", ColumnTypeVarchar, ColumnTypeLength(32)), -// ColumnDef("redirect_uri", ColumnTypeText), -// ColumnDef("enabled", ColumnTypeBoolean), -// ColumnDef("trusted", ColumnTypeBoolean), -// ColumnDef("valid_from", ColumnTypeTimestamp, Null), -// ColumnDef("expires_at", ColumnTypeTimestamp, Null), -// ColumnDef("security", ColumnTypeJson), -// ColumnDef("owned_by", ColumnTypeIdentifier), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableAuthConfirmedClients() *Table { -// return TableDef(`auth_confirmed_clients`, -// ColumnDef("rel_user", ColumnTypeIdentifier), -// ColumnDef("rel_client", ColumnTypeIdentifier), -// ColumnDef("confirmed_at", ColumnTypeTimestamp), -// -// PrimaryKey(IColumn("rel_user", "rel_client")), -// ) -//} -// -//func tableAuthSessions() *Table { -// return TableDef(`auth_sessions`, -// ColumnDef("id", ColumnTypeVarchar, ColumnTypeLength(64)), -// ColumnDef("data", ColumnTypeBinary), -// ColumnDef("rel_user", ColumnTypeIdentifier), -// ColumnDef("created_at", ColumnTypeTimestamp), -// ColumnDef("expires_at", ColumnTypeTimestamp), -// ColumnDef("remote_addr", ColumnTypeVarchar, ColumnTypeLength(ipAddrLength)), -// ColumnDef("user_agent", ColumnTypeText), -// -// AddIndex("expires_at", IColumn("expires_at")), -// AddIndex("user", IColumn("rel_user")), -// PrimaryKey(IColumn("id")), -// ) -//} -// -//func tableAuthOA2Tokens() *Table { -// return TableDef(`auth_oa2tokens`, -// ID, -// -// ColumnDef("code", ColumnTypeVarchar, ColumnTypeLength(48)), -// ColumnDef("access", ColumnTypeVarchar, ColumnTypeLength(2048)), -// ColumnDef("refresh", ColumnTypeVarchar, ColumnTypeLength(48)), -// ColumnDef("data", ColumnTypeJson), -// ColumnDef("remote_addr", ColumnTypeVarchar, ColumnTypeLength(ipAddrLength)), -// ColumnDef("user_agent", ColumnTypeText), -// -// ColumnDef("rel_client", ColumnTypeIdentifier), -// ColumnDef("rel_user", ColumnTypeIdentifier), -// ColumnDef("created_at", ColumnTypeTimestamp), -// ColumnDef("expires_at", ColumnTypeTimestamp), -// -// AddIndex("expires_at", IColumn("expires_at")), -// AddIndex("code", IColumn("code")), -// AddIndex("access", IColumn("access")), -// AddIndex("refresh", IColumn("refresh")), -// AddIndex("client", IColumn("rel_client")), -// AddIndex("user", IColumn("rel_user")), -// ) -//} -// -//func tableRoles() *Table { -// return TableDef(`roles`, -// ID, -// ColumnDef("name", ColumnTypeText), -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("archived_at", ColumnTypeTimestamp, Null), -// CUDTimestamps, -// -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL AND archived_at IS NULL")), -// ) -//} -// -//func tableRoleMembers() *Table { -// return TableDef(`role_members`, -// ColumnDef("rel_role", ColumnTypeIdentifier), -// ColumnDef("rel_user", ColumnTypeIdentifier), -// -// AddIndex("unique_membership", IColumn("rel_role", "rel_user")), -// ) -//} -// -//func tableApplications() *Table { -// return TableDef("applications", -// ID, -// ColumnDef("name", ColumnTypeText), -// ColumnDef("enabled", ColumnTypeBoolean, DefaultValue("true")), -// ColumnDef("weight", ColumnTypeInteger, DefaultValue("0")), -// ColumnDef("unify", ColumnTypeJson), -// ColumnDef("rel_owner", ColumnTypeIdentifier), -// CUDTimestamps, -// ) -//} -// -//func tableReminders() *Table { -// return TableDef("reminders", -// ID, -// ColumnDef("resource", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("payload", ColumnTypeJson), -// ColumnDef("snooze_count", ColumnTypeInteger, DefaultValue("0")), -// ColumnDef("assigned_to", ColumnTypeIdentifier, DefaultValue("0")), -// ColumnDef("assigned_by", ColumnTypeIdentifier, DefaultValue("0")), -// ColumnDef("assigned_at", ColumnTypeTimestamp), -// ColumnDef("remind_at", ColumnTypeTimestamp, Null), -// ColumnDef("dismissed_at", ColumnTypeTimestamp, Null), -// ColumnDef("dismissed_by", ColumnTypeIdentifier, DefaultValue("0")), -// CUDTimestamps, -// -// AddIndex("resource", IColumn("resource")), -// AddIndex("assignee", IColumn("assigned_to")), -// ) -//} -// -//func tableAttachments() *Table { -// return TableDef("attachments", -// ID, -// ColumnDef("rel_owner", ColumnTypeIdentifier), -// ColumnDef("kind", ColumnTypeText), -// ColumnDef("url", ColumnTypeText), -// ColumnDef("preview_url", ColumnTypeText), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("meta", ColumnTypeJson), -// CUDTimestamps, -// ) -//} -// -//func tableActionLog() *Table { -// return TableDef("actionlog", -// ID, -// ColumnDef("ts", ColumnTypeTimestamp), -// ColumnDef("actor_ip_addr", ColumnTypeVarchar, ColumnTypeLength(ipAddrLength)), -// ColumnDef("actor_id", ColumnTypeIdentifier), -// ColumnDef("request_origin", ColumnTypeVarchar, ColumnTypeLength(32)), -// ColumnDef("request_id", ColumnTypeVarchar, ColumnTypeLength(256)), -// ColumnDef("resource", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("action", ColumnTypeVarchar, ColumnTypeLength(64)), -// ColumnDef("error", ColumnTypeText), -// ColumnDef("severity", ColumnTypeInteger), -// ColumnDef("description", ColumnTypeText), -// ColumnDef("meta", ColumnTypeJson), -// -// AddIndex("ts", IColumn("ts")), -// AddIndex("request_origin", IColumn("request_origin")), -// AddIndex("actor_id", IColumn("actor_id")), -// AddIndex("resource", IColumn("resource")), -// AddIndex("action", IColumn("action")), -// ) -//} -// -//func tableRbacRules() *Table { -// return TableDef("rbac_rules", -// ColumnDef("rel_role", ColumnTypeIdentifier), -// ColumnDef("resource", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("operation", ColumnTypeVarchar, ColumnTypeLength(50)), -// ColumnDef("access", ColumnTypeInteger), -// -// PrimaryKey(IColumn("rel_role", "resource", "operation")), -// ) -//} -// -//func tableSettings() *Table { -// return TableDef("settings", -// ColumnDef("rel_owner", ColumnTypeIdentifier), -// ColumnDef("name", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("value", ColumnTypeJson), -// ColumnDef("updated_by", ColumnTypeIdentifier), -// ColumnDef("updated_at", ColumnTypeTimestamp), -// -// AddIndex("unique_name", IExpr("LOWER(name)"), IColumn("rel_owner")), -// ) -//} -// -//func tableLabels() *Table { -// return TableDef("labels", -// ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("rel_resource", ColumnTypeIdentifier), -// ColumnDef("name", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("value", ColumnTypeText), -// -// AddIndex("unique_kind_res_name", IColumn("kind", "rel_resource"), IExpr("LOWER(name)")), -// ) -//} -// -//func tableFlags() *Table { -// return TableDef("flags", -// ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("rel_resource", ColumnTypeIdentifier), -// ColumnDef("owned_by", ColumnTypeIdentifier), -// ColumnDef("name", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("active", ColumnTypeBoolean), -// -// AddIndex("unique_kind_res_owner_name", IColumn("kind", "rel_resource", "owned_by"), IExpr("LOWER(name)")), -// ) -//} -// -//func tableTemplates() *Table { -// return TableDef("templates", -// ID, -// ColumnDef("rel_owner", ColumnTypeIdentifier), -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("language", ColumnTypeText), -// ColumnDef("type", ColumnTypeText), -// ColumnDef("partial", ColumnTypeBoolean), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("template", ColumnTypeText), -// CUDTimestamps, -// ColumnDef("last_used_at", ColumnTypeTimestamp, Null), -// -// AddIndex("unique_language_handle", IColumn("language"), IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableReports() *Table { -// return TableDef("reports", -// ID, -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("scenarios", ColumnTypeJson), -// ColumnDef("sources", ColumnTypeJson), -// ColumnDef("blocks", ColumnTypeJson), -// -// ColumnDef("owned_by", ColumnTypeIdentifier), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableResourceTranslations() *Table { -// return TableDef("resource_translations", -// ID, -// -// ColumnDef("lang", ColumnTypeVarchar, ColumnTypeLength(languageTagLength)), -// ColumnDef("resource", ColumnTypeVarchar, ColumnTypeLength(resourceLength)), -// ColumnDef("k", ColumnTypeVarchar, ColumnTypeLength(languageKeyLength)), -// ColumnDef("message", ColumnTypeText), -// -// CUDTimestamps, -// ColumnDef("owned_by", ColumnTypeIdentifier), -// CUDUsers, -// -// AddIndex("unique_translation", IExpr("LOWER(lang)"), IExpr("LOWER(resource)"), IExpr("LOWER(k)")), -// ) -//} -// -//func tableComposeAttachment() *Table { -// // @todo merge with general attachment table -// -// return TableDef("compose_attachment", -// ID, -// ColumnDef("rel_namespace", ColumnTypeIdentifier), -// ColumnDef("rel_owner", ColumnTypeIdentifier), -// ColumnDef("kind", ColumnTypeText), -// ColumnDef("url", ColumnTypeText), -// ColumnDef("preview_url", ColumnTypeText), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("meta", ColumnTypeJson), -// CUDTimestamps, -// -// AddIndex("namespace", IColumn("rel_namespace")), -// ) -//} -// -//func tableComposeChart() *Table { -// return TableDef("compose_chart", -// ID, -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("rel_namespace", ColumnTypeIdentifier), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("config", ColumnTypeJson), -// CUDTimestamps, -// -// AddIndex("namespace", IColumn("rel_namespace")), -// AddIndex("unique_handle", IColumn("rel_namespace"), IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableComposeModule() *Table { -// return TableDef("compose_module", -// ID, -// ColumnDef("rel_namespace", ColumnTypeIdentifier), -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("config", ColumnTypeJson), -// CUDTimestamps, -// -// AddIndex("namespace", IColumn("rel_namespace")), -// AddIndex("unique_handle", IColumn("rel_namespace"), IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableComposeModuleField() *Table { -// return TableDef("compose_module_field", -// ID, -// -// ColumnDef("rel_module", ColumnTypeIdentifier), -// ColumnDef("place", ColumnTypeInteger), -// ColumnDef("kind", ColumnTypeText), -// ColumnDef("options", ColumnTypeJson), -// ColumnDef("config", ColumnTypeJson), -// ColumnDef("default_value", ColumnTypeJson), -// ColumnDef("expressions", ColumnTypeJson), -// ColumnDef("name", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("label", ColumnTypeText), -// ColumnDef("is_required", ColumnTypeBoolean), -// ColumnDef("is_multi", ColumnTypeBoolean), -// -// CUDTimestamps, -// -// AddIndex("unique_name", IColumn("rel_module"), IExpr("LOWER(name)"), IWhere("LENGTH(name) > 0 AND deleted_at IS NULL")), -// AddIndex("module", IColumn("rel_module")), -// ) -//} -// -//func tableComposeNamespace() *Table { -// return TableDef("compose_namespace", -// ID, -// ColumnDef("name", ColumnTypeText), -// ColumnDef("slug", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("enabled", ColumnTypeBoolean), -// ColumnDef("meta", ColumnTypeJson), -// CUDTimestamps, -// -// AddIndex("unique_slug", IExpr("LOWER(slug)"), IWhere("LENGTH(slug) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableComposePage() *Table { -// return TableDef("compose_page", -// ID, -// ColumnDef("title", ColumnTypeText), -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("description", ColumnTypeText), -// ColumnDef("rel_namespace", ColumnTypeIdentifier), -// ColumnDef("rel_module", ColumnTypeIdentifier), -// ColumnDef("self_id", ColumnTypeIdentifier), -// ColumnDef("config", ColumnTypeJson), -// ColumnDef("blocks", ColumnTypeJson), -// ColumnDef("visible", ColumnTypeBoolean), -// ColumnDef("weight", ColumnTypeInteger), -// CUDTimestamps, -// -// AddIndex("self", IColumn("self_id")), -// AddIndex("namespace", IColumn("rel_namespace")), -// AddIndex("module", IColumn("rel_module")), -// AddIndex("unique_handle", IColumn("rel_namespace"), IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableComposeRecord() *Table { -// return TableDef("compose_record", -// ID, -// ColumnDef("rel_namespace", ColumnTypeIdentifier), -// ColumnDef("rel_module", ColumnTypeIdentifier), -// ColumnDef("revision", ColumnTypeInteger), -// ColumnDef("values", ColumnTypeJson), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("owned_by", ColumnTypeIdentifier), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("namespace", IColumn("rel_namespace")), -// AddIndex("module", IColumn("rel_module")), -// AddIndex("owner", IColumn("owned_by")), -// ) -//} -// -//func tableComposeRecordRevisions() *Table { -// return TableDef("compose_record_revisions", -// ID, -// ColumnDef("ts", ColumnTypeTimestamp), -// ColumnDef("rel_resource", ColumnTypeIdentifier), -// ColumnDef("revision", ColumnTypeInteger), -// ColumnDef("operation", ColumnTypeText), -// ColumnDef("rel_user", ColumnTypeIdentifier), -// ColumnDef("delta", ColumnTypeJson), -// ColumnDef("comment", ColumnTypeText), -// -// AddIndex("record", IColumn("rel_resource")), -// ) -//} -// -//func tableFederationModuleShared() *Table { -// return TableDef("federation_module_shared", -// ID, -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("rel_node", ColumnTypeIdentifier), -// ColumnDef("xref_module", ColumnTypeIdentifier), -// ColumnDef("fields", ColumnTypeJson), -// CUDTimestamps, -// CUDUsers, -// ) -//} -// -//func tableFederationModuleExposed() *Table { -// return TableDef("federation_module_exposed", -// ID, -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("rel_node", ColumnTypeIdentifier), -// ColumnDef("rel_compose_module", ColumnTypeIdentifier), -// ColumnDef("rel_compose_namespace", ColumnTypeIdentifier), -// ColumnDef("fields", ColumnTypeJson), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("unique_node_compose_module", IColumn("rel_node", "rel_compose_module", "rel_compose_namespace")), -// ) -//} -// -//func tableFederationModuleMapping() *Table { -// return TableDef("federation_module_mapping", -// ColumnDef("rel_federation_module", ColumnTypeIdentifier), -// ColumnDef("rel_compose_module", ColumnTypeIdentifier), -// ColumnDef("rel_compose_namespace", ColumnTypeIdentifier), -// ColumnDef("field_mapping", ColumnTypeJson), -// -// AddIndex("unique_module_compose_module", IColumn("rel_federation_module", "rel_compose_module", "rel_compose_namespace")), -// ) -//} -// -//func tableFederationNodes() *Table { -// return TableDef("federation_nodes", -// ID, -// ColumnDef("shared_node_id", ColumnTypeIdentifier), -// ColumnDef("name", ColumnTypeText), -// ColumnDef("base_url", ColumnTypeText), -// ColumnDef("status", ColumnTypeText), -// ColumnDef("contact", ColumnTypeVarchar, ColumnTypeLength(emailLength)), -// ColumnDef("pair_token", ColumnTypeText), -// ColumnDef("auth_token", ColumnTypeText), -// -// CUDTimestamps, -// CUDUsers, -// ) -//} -// -//func tableFederationNodesSync() *Table { -// return TableDef("federation_nodes_sync", -// ColumnDef("rel_node", ColumnTypeIdentifier), -// ColumnDef("rel_module", ColumnTypeIdentifier), -// ColumnDef("sync_type", ColumnTypeText), -// ColumnDef("sync_status", ColumnTypeText), -// ColumnDef("time_action", ColumnTypeTimestamp), -// ) -//} -// -//func tableAutomationWorkflows() *Table { -// return TableDef("automation_workflows", -// ID, -// ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("enabled", ColumnTypeBoolean), -// ColumnDef("trace", ColumnTypeBoolean), -// ColumnDef("keep_sessions", ColumnTypeInteger), -// ColumnDef("scope", ColumnTypeJson), -// ColumnDef("steps", ColumnTypeJson), -// ColumnDef("paths", ColumnTypeJson), -// ColumnDef("issues", ColumnTypeJson), -// ColumnDef("run_as", ColumnTypeIdentifier), -// ColumnDef("owned_by", ColumnTypeIdentifier), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("unique_handle", IExpr("LOWER(handle)"), IWhere("LENGTH(handle) > 0 AND deleted_at IS NULL")), -// ) -//} -// -//func tableAutomationSessions() *Table { -// return TableDef("automation_sessions", -// ID, -// ColumnDef("rel_workflow", ColumnTypeIdentifier), -// ColumnDef("status", ColumnTypeInteger), -// ColumnDef("event_type", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("resource_type", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("input", ColumnTypeJson), -// ColumnDef("output", ColumnTypeJson), -// ColumnDef("stacktrace", ColumnTypeJson), -// ColumnDef("created_by", ColumnTypeIdentifier), -// ColumnDef("created_at", ColumnTypeTimestamp), -// ColumnDef("purge_at", ColumnTypeTimestamp, Null), -// ColumnDef("suspended_at", ColumnTypeTimestamp, Null), -// ColumnDef("completed_at", ColumnTypeTimestamp, Null), -// ColumnDef("error", ColumnTypeText), -// -// AddIndex("workflow", IColumn("rel_workflow")), -// AddIndex("event_type", IFieldFull(&IField{Field: "event_type", Length: handleLength})), -// AddIndex("resource_type", IFieldFull(&IField{Field: "resource_type", Length: handleLength})), -// AddIndex("status", IColumn("status")), -// AddIndex("created_at", IColumn("created_at")), -// AddIndex("completed_at", IColumn("completed_at")), -// AddIndex("suspended_at", IColumn("suspended_at")), -// ) -//} -// -//func tableAutomationTriggers() *Table { -// return TableDef("automation_triggers", -// ID, -// ColumnDef("rel_workflow", ColumnTypeIdentifier), -// ColumnDef("rel_step", ColumnTypeIdentifier), -// ColumnDef("enabled", ColumnTypeBoolean), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("resource_type", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("event_type", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("constraints", ColumnTypeJson), -// ColumnDef("input", ColumnTypeJson), -// ColumnDef("owned_by", ColumnTypeIdentifier), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("workflow", IColumn("rel_workflow")), -// ) -//} -// -//func tableMessagebusQueuemessage() *Table { -// return TableDef("queue_messages", -// ID, -// ColumnDef("queue", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("payload", ColumnTypeBinary), -// ColumnDef("created", ColumnTypeTimestamp), -// ColumnDef("processed", ColumnTypeTimestamp, Null), -// -// // AddIndex("processed", IColumn("processed")), -// ) -//} -// -//func tableMessagebusQueue() *Table { -// return TableDef("queue_settings", -// ID, -// ColumnDef("consumer", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("queue", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("meta", ColumnTypeJson), -// CUDTimestamps, -// CUDUsers, -// ) -//} -// -//func tableApigwRoute() *Table { -// return TableDef("apigw_routes", -// ID, -// ColumnDef("endpoint", ColumnTypeText, ColumnTypeLength(resourceLength)), -// ColumnDef("method", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("enabled", ColumnTypeBoolean), -// ColumnDef("meta", ColumnTypeJson), -// ColumnDef("rel_group", ColumnTypeIdentifier), -// CUDTimestamps, -// CUDUsers, -// ) -//} -// -//func tableApigwFilter() *Table { -// return TableDef("apigw_filters", -// ID, -// ColumnDef("rel_route", ColumnTypeIdentifier), -// ColumnDef("weight", ColumnTypeInteger), -// ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("ref", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("enabled", ColumnTypeBoolean), -// ColumnDef("params", ColumnTypeJson), -// CUDTimestamps, -// CUDUsers, -// ) -//} -// -//func tableResourceActivityLog() *Table { -// return TableDef("resource_activity_log", -// ID, -// ColumnDef("rel_resource", ColumnTypeIdentifier), -// ColumnDef("resource_type", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("resource_action", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("ts", ColumnTypeTimestamp), -// ColumnDef("meta", ColumnTypeJson), -// -// AddIndex("rel_resource", IColumn("rel_resource")), -// AddIndex("ts", IColumn("ts")), -// ) -//} -// -//func tableDataPrivacyRequests() *Table { -// return TableDef("data_privacy_requests", -// ID, -// ColumnDef("kind", ColumnTypeText, ColumnTypeLength(handleLength)), -// ColumnDef("status", ColumnTypeVarchar, ColumnTypeLength(handleLength)), -// ColumnDef("payload", ColumnTypeJson), -// ColumnDef("requested_at", ColumnTypeTimestamp), -// ColumnDef("requested_by", ColumnTypeIdentifier), -// ColumnDef("completed_at", ColumnTypeTimestamp, Null), -// ColumnDef("completed_by", ColumnTypeIdentifier, DefaultValue("0")), -// CUDTimestamps, -// CUDUsers, -// -// AddIndex("status", IColumn("status")), -// ) -//} -// -//func tableDataPrivacyRequestComments() *Table { -// return TableDef("data_privacy_request_comments", -// ID, -// ColumnDef("rel_request", ColumnTypeIdentifier), -// ColumnDef("comment", ColumnTypeText), -// CUDTimestamps, -// CUDUsers, -// ) -//}