backend barebone done, big chunk of work done
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed migrations/*.sql
|
||||
var migrationFiles embed.FS
|
||||
|
||||
// Migrate applies any pending SQL migrations in order within a single transaction.
|
||||
func (s *Store) Migrate(ctx context.Context) error {
|
||||
conn, err := s.pool.Acquire(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Release()
|
||||
|
||||
tx, err := conn.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if tx != nil {
|
||||
tx.Rollback(ctx)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = tx.Exec(ctx, `CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version INT PRIMARY KEY
|
||||
)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entries, err := migrationFiles.ReadDir("migrations")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type mig struct {
|
||||
ver int
|
||||
name string
|
||||
}
|
||||
var migs []mig
|
||||
for _, e := range entries {
|
||||
name := e.Name()
|
||||
if !strings.HasSuffix(name, ".sql") {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(name, "_", 2)
|
||||
v, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
migs = append(migs, mig{ver: v, name: name})
|
||||
}
|
||||
sort.Slice(migs, func(i, j int) bool { return migs[i].ver < migs[j].ver })
|
||||
|
||||
for _, m := range migs {
|
||||
var exists bool
|
||||
err = tx.QueryRow(ctx, "SELECT EXISTS(SELECT 1 FROM schema_migrations WHERE version=$1)", m.ver).Scan(&exists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
continue
|
||||
}
|
||||
data, err := migrationFiles.ReadFile("migrations/" + m.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = tx.Exec(ctx, string(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = tx.Exec(ctx, "INSERT INTO schema_migrations(version) VALUES($1)", m.ver); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = tx.Commit(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
tx = nil
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user