[bugfix] Drop status indices AFTER updating visibility (#3795)

* [bugfix] Drop status indices AFTER updating visibility

* rename to status vis indices just to indicate they're only used in the statuses hook func

---------

Co-authored-by: kim <grufwub@gmail.com>
This commit is contained in:
tobi 2025-02-14 13:52:04 +01:00 committed by GitHub
parent 1ee56d66ce
commit 879ca2d2f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 49 additions and 27 deletions

View File

@ -32,20 +32,8 @@ func init() {
up := func(ctx context.Context, db *bun.DB) error { up := func(ctx context.Context, db *bun.DB) error {
return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
// Tables with visibility types. // Status visibility type indices.
var visTables = []struct { var statusVisIndices = []struct {
Table string
Column string
Default *new_gtsmodel.Visibility
}{
{Table: "statuses", Column: "visibility"},
{Table: "sin_bin_statuses", Column: "visibility"},
{Table: "account_settings", Column: "privacy", Default: util.Ptr(new_gtsmodel.VisibilityDefault)},
{Table: "account_settings", Column: "web_visibility", Default: util.Ptr(new_gtsmodel.VisibilityDefault)},
}
// Visibility type indices.
var visIndices = []struct {
name string name string
cols []string cols []string
order string order string
@ -67,16 +55,42 @@ func init() {
}, },
} }
// Before making changes to the visibility col // Tables with visibility types.
// we must drop all indices that rely on it. var visTables = []struct {
log.Info(ctx, "dropping old visibility indexes...") Table string
for _, index := range visIndices { Column string
log.Infof(ctx, "dropping old index %s...", index.name) Default *new_gtsmodel.Visibility
if _, err := tx.NewDropIndex(). IndexCleanupCallback func(ctx context.Context, tx bun.Tx) error
Index(index.name). }{
Exec(ctx); err != nil { {
return err Table: "statuses",
} Column: "visibility",
IndexCleanupCallback: func(ctx context.Context, tx bun.Tx) error {
// After new column has been created and
// populated, drop indices relying on old column.
for _, index := range statusVisIndices {
log.Infof(ctx, "dropping old index %s...", index.name)
if _, err := tx.NewDropIndex().
Index(index.name).
Exec(ctx); err != nil {
return err
}
}
return nil
},
},
{
Table: "sin_bin_statuses",
Column: "visibility",
},
{
Table: "account_settings",
Column: "privacy",
Default: util.Ptr(new_gtsmodel.VisibilityDefault)},
{
Table: "account_settings",
Column: "web_visibility",
Default: util.Ptr(new_gtsmodel.VisibilityDefault)},
} }
// Get the mapping of old enum string values to new integer values. // Get the mapping of old enum string values to new integer values.
@ -85,14 +99,14 @@ func init() {
// Convert all visibility tables. // Convert all visibility tables.
for _, table := range visTables { for _, table := range visTables {
if err := convertEnums(ctx, tx, table.Table, table.Column, if err := convertEnums(ctx, tx, table.Table, table.Column,
visibilityMapping, table.Default); err != nil { visibilityMapping, table.Default, table.IndexCleanupCallback); err != nil {
return err return err
} }
} }
// Recreate the visibility indices. // Recreate the visibility indices.
log.Info(ctx, "creating new visibility indexes...") log.Info(ctx, "creating new visibility indexes...")
for _, index := range visIndices { for _, index := range statusVisIndices {
log.Infof(ctx, "creating new index %s...", index.name) log.Infof(ctx, "creating new index %s...", index.name)
q := tx.NewCreateIndex(). q := tx.NewCreateIndex().
Table("statuses"). Table("statuses").
@ -111,7 +125,7 @@ func init() {
// Migrate over old notifications table column over to new column type. // Migrate over old notifications table column over to new column type.
if err := convertEnums(ctx, tx, "notifications", "notification_type", //nolint:revive if err := convertEnums(ctx, tx, "notifications", "notification_type", //nolint:revive
notificationMapping, nil); err != nil { notificationMapping, nil, nil); err != nil {
return err return err
} }

View File

@ -45,6 +45,7 @@ func convertEnums[OldType ~string, NewType ~int16](
column string, column string,
mapping map[OldType]NewType, mapping map[OldType]NewType,
defaultValue *NewType, defaultValue *NewType,
indexCleanupCallback func(context.Context, bun.Tx) error,
) error { ) error {
if len(mapping) == 0 { if len(mapping) == 0 {
return errors.New("empty mapping") return errors.New("empty mapping")
@ -110,6 +111,13 @@ func convertEnums[OldType ~string, NewType ~int16](
log.Warnf(ctx, "total=%d does not match updated=%d", total, updated) log.Warnf(ctx, "total=%d does not match updated=%d", total, updated)
} }
// Run index cleanup callback if set.
if indexCleanupCallback != nil {
if err := indexCleanupCallback(ctx, tx); err != nil {
return gtserror.Newf("error running index cleanup callback: %w", err)
}
}
// Drop the old column from table. // Drop the old column from table.
if _, err := tx.NewDropColumn(). if _, err := tx.NewDropColumn().
Table(table). Table(table).