This commit is contained in:
tobi 2025-02-14 15:09:44 +01:00
commit c168c8cc70
2 changed files with 65 additions and 16 deletions

View file

@ -59,6 +59,7 @@ func init() {
Column string Column string
Default *new_gtsmodel.Visibility Default *new_gtsmodel.Visibility
IndexCleanupCallback func(ctx context.Context, tx bun.Tx) error IndexCleanupCallback func(ctx context.Context, tx bun.Tx) error
BatchByColumn string
}{ }{
{ {
Table: "statuses", Table: "statuses",
@ -76,19 +77,26 @@ func init() {
} }
return nil return nil
}, },
BatchByColumn: "id",
}, },
{ {
Table: "sin_bin_statuses", Table: "sin_bin_statuses",
Column: "visibility", Column: "visibility",
BatchByColumn: "id",
}, },
{ {
Table: "account_settings", Table: "account_settings",
Column: "privacy", Column: "privacy",
Default: util.Ptr(new_gtsmodel.VisibilityDefault)}, Default: util.Ptr(new_gtsmodel.VisibilityDefault),
BatchByColumn: "account_id",
},
{ {
Table: "account_settings", Table: "account_settings",
Column: "web_visibility", Column: "web_visibility",
Default: util.Ptr(new_gtsmodel.VisibilityDefault)}, Default: util.Ptr(new_gtsmodel.VisibilityDefault),
BatchByColumn: "account_id",
},
} }
// Get the mapping of old enum string values to new integer values. // Get the mapping of old enum string values to new integer values.
@ -100,7 +108,7 @@ func init() {
// Perform each enum table conversion within its own transaction. // Perform each enum table conversion within its own transaction.
if err := db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { if err := db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
return convertEnums(ctx, tx, table.Table, table.Column, return convertEnums(ctx, tx, table.Table, table.Column,
visibilityMapping, table.Default, table.IndexCleanupCallback) visibilityMapping, table.Default, table.IndexCleanupCallback, table.BatchByColumn)
}); err != nil { }); err != nil {
return err return err
} }
@ -128,7 +136,7 @@ func init() {
// Migrate over old notifications table column to new type in tx. // Migrate over old notifications table column to new type in tx.
if err := db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { if err := db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
return convertEnums(ctx, tx, "notifications", "notification_type", //nolint:revive return convertEnums(ctx, tx, "notifications", "notification_type", //nolint:revive
notificationMapping, nil, nil) notificationMapping, nil, nil, "id")
}); err != nil { }); err != nil {
return err return err
} }

View file

@ -27,6 +27,7 @@ import (
"codeberg.org/gruf/go-byteutil" "codeberg.org/gruf/go-byteutil"
"github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/log"
"github.com/uptrace/bun" "github.com/uptrace/bun"
"github.com/uptrace/bun/dialect" "github.com/uptrace/bun/dialect"
@ -46,6 +47,7 @@ func convertEnums[OldType ~string, NewType ~int16](
mapping map[OldType]NewType, mapping map[OldType]NewType,
defaultValue *NewType, defaultValue *NewType,
indexCleanupCallback func(context.Context, bun.Tx) error, indexCleanupCallback func(context.Context, bun.Tx) error,
batchByColumn string,
) error { ) error {
if len(mapping) == 0 { if len(mapping) == 0 {
return errors.New("empty mapping") return errors.New("empty mapping")
@ -98,15 +100,54 @@ func convertEnums[OldType ~string, NewType ~int16](
} }
qbuf.B = append(qbuf.B, "ELSE ? END)"...) qbuf.B = append(qbuf.B, "ELSE ? END)"...)
args = append(args, *defaultValue) args = append(args, *defaultValue)
qbuf.B = append(qbuf.B, " WHERE ? IN (?)"...)
args = append(args, bun.Ident(batchByColumn))
baseQ := qbuf.String()
// Execute the prepared raw query with arguments. var (
res, err := tx.NewRaw(qbuf.String(), args...).Exec(ctx) nextHighest = id.Highest
if err != nil { updated int64
return gtserror.Newf("error updating old column values: %w", err) )
for {
batchQ := tx.NewRaw(
"SELECT ? FROM ? WHERE ? < ? ORDER BY ? DESC LIMIT ?",
bun.Ident(batchByColumn),
bun.Ident(table),
bun.Ident(batchByColumn),
nextHighest,
bun.Ident(batchByColumn),
5000,
)
q := baseQ + " RETURNING ?"
qArgs := append(args, batchQ) // nolint:gocritic
qArgs = append(qArgs, bun.Ident(batchByColumn))
// Execute the prepared raw query with arguments.
var ids []string
res, err := tx.NewRaw(q, qArgs...).Exec(ctx, &ids)
if err != nil {
return gtserror.Newf("error updating old column values: %w", err)
}
// Count number items updated.
thisUpdated, _ := res.RowsAffected()
if thisUpdated == 0 {
break
}
updated += thisUpdated
highestID := ids[0]
lowestID := ids[len(ids)-1]
log.Infof(ctx,
"updated %d of %d %s (just done from %s to %s)",
updated, total, table, highestID, lowestID,
)
nextHighest = lowestID
} }
// Count number items updated.
updated, _ := res.RowsAffected()
if total != int(updated) { if total != int(updated) {
log.Warnf(ctx, "total=%d does not match updated=%d", total, updated) log.Warnf(ctx, "total=%d does not match updated=%d", total, updated)
} }