1package sqlite23import (4 "context"5 "database/sql"6 "embed"7 "fmt"8 "io"9)1011var (12 //go:embed *.sql13 SQLFiles embed.FS14 Migrations []func(context.Context, *sql.Tx) error15)1617func init() {18 Migrations = []func(context.Context, *sql.Tx) error{19 fromFile("000_init.sql"),20 fromFile("001_request_table.sql"),21 }22}2324func fromFile(fname string) func(context.Context, *sql.Tx) error {25 sql_file, err := SQLFiles.Open(fname)26 if err != nil {27 panic(err)28 }29 defer sql_file.Close()3031 raw_sql, err := io.ReadAll(sql_file)32 if err != nil {33 panic(err)34 }35 _sql := string(raw_sql)3637 return func(ctx context.Context, tx *sql.Tx) error {38 _, err := tx.ExecContext(ctx, _sql)39 return err40 }41}4243func migrate(ctx context.Context, db *sql.DB) (err error) {44 var (45 version, maxVersion int6446 )4748 db.QueryRowContext(ctx, "pragma user_version").Scan(&version)49 maxVersion = int64(len(Migrations))5051 for v := version; v < maxVersion; v++ {52 tx, err := db.BeginTx(ctx, nil)53 if err != nil {54 return err55 }5657 if err = Migrations[v](ctx, tx); err != nil {58 tx.Rollback()59 return err60 }61 if _, err = tx.ExecContext(ctx, fmt.Sprintf("pragma user_version = %d", v+1)); err != nil {62 tx.Rollback()63 return err64 }65 if err = tx.Commit(); err != nil {66 return err67 }68 }6970 return nil71}