updates the enum migration to perform a singular update for all values, using an SQL case statement

This commit is contained in:
kim 2025-02-11 14:30:05 +00:00
commit bb8afd231d

View file

@ -35,6 +35,11 @@ import (
"github.com/uptrace/bun/schema"
)
// formatQuery formats given query + args according to given bun dialect, using for debug logging.
func formatQuery(d schema.Dialect, query string, args ...any) string {
return schema.NewFormatter(d).FormatQuery(query, args...)
}
// convertEnums performs a transaction that converts
// a table's column of our old-style enums (strings) to
// more performant and space-saving integer types.
@ -82,26 +87,31 @@ func convertEnums[OldType ~string, NewType ~int16](
return gtserror.Newf("error selecting total count: %w", err)
}
var updated int
var args []any
var qbuf byteutil.Buffer
// Prepare a singular UPDATE statement using
// SET $newColumn = (CASE $column WHEN $old THEN $new ... END)
qbuf.WriteString("UPDATE ? SET ? = (CASE ? ")
args = append(args, bun.Ident(table))
args = append(args, bun.Ident(newColumn))
args = append(args, bun.Ident(column))
for old, new := range mapping {
qbuf.WriteString("WHEN ? THEN ? ")
args = append(args, old, new)
}
qbuf.WriteString("ELSE ? END)")
args = append(args, *defaultValue)
// Update old to new values.
res, err := tx.NewUpdate().
Table(table).
Where("? = ?", bun.Ident(column), old).
Set("? = ?", bun.Ident(newColumn), new).
Exec(ctx)
if err != nil {
return gtserror.Newf("error updating old column values: %w", err)
}
// Count number items updated.
n, _ := res.RowsAffected()
updated += int(n)
// Execute the prepared raw query with arguments.
res, err := tx.NewRaw(qbuf.String(), args...).Exec(ctx)
if err != nil {
return gtserror.Newf("error updating old column values: %w", err)
}
// Check total updated.
if total != updated {
// Count number items updated.
updated, _ := res.RowsAffected()
if total != int(updated) {
log.Warnf(ctx, "total=%d does not match updated=%d", total, updated)
}