Something went wrong. Try again.
MongoDB migrations made simple for go
mongodb migration db
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125package moose
import ( "errors" "fmt" "html/template" "math" "os" "path/filepath" "time")
const timestampFormat = "20060102150405"
type tmplVars struct { Version string CamelName string Package string}
const jsonVersionTemplate = "%05v"
func CreateWithTemplate(dir string, tmpl *template.Template, name string, migrationType MigrationType, sequential bool) (string, error) { version := time.Now().UTC().Format(timestampFormat)
if _, err := os.Stat(dir); os.IsNotExist(err) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { return "", err } }
if sequential { // always use osFS here because it's modifying operation migrations, err := collect(osFS{}, dir, math.MinInt64, math.MaxInt64, registeredGoMigrations) if err != nil && !errors.Is(err, ErrNoMigrationFiles) { return "", err }
vMigrations, err := Migrations(migrations).versioned(timestampFormat) if err != nil { return "", err }
if last, err := vMigrations.Last(); err == nil { version = fmt.Sprintf(jsonVersionTemplate, last.Version+1) } else { version = fmt.Sprintf(jsonVersionTemplate, int64(1)) } }
filename := fmt.Sprintf("%v_%v.%v", version, snakeCase(name), migrationType)
if tmpl == nil { switch migrationType { case MigrationTypeGo: tmpl = goMigrationTemplate case MigrationTypeJSON: tmpl = jsonMigrationTemplate default: return "", fmt.Errorf("unsupported migration type %q, use go or json", migrationType) } }
path := filepath.Join(dir, filename) if _, err := os.Stat(path); !os.IsNotExist(err) { return "", fmt.Errorf("failed to create migration file: %w", err) }
f, err := os.Create(path) if err != nil { return "", fmt.Errorf("failed to create migration file: %w", err) } defer func() { _ = f.Close() }()
abs, err := filepath.Abs(path) if err != nil { return "", fmt.Errorf("failed to create migration file: %w", err) } vars := tmplVars{ Version: version, CamelName: camelCase(name), Package: filepath.Base(filepath.Dir(abs)), } if err := tmpl.Execute(f, vars); err != nil { return "", fmt.Errorf("failed to execute tmpl: %w", err) }
return f.Name(), nil}
// Create writes a new blank migration file.func Create(dir, name string, migrationType MigrationType, sequential bool) (string, error) { return CreateWithTemplate(dir, nil, name, migrationType, sequential)}
var jsonMigrationTemplate = template.Must(template.New("moose.json-migration").Parse(`{ "up":{ "tx": true, "cmds": [] }, "down": { "tx": true, "cmds": [] }}`))
var goMigrationTemplate = template.Must(template.New("moose.go-migration").Parse(`package {{.Package}}
import ( "context"
"tangled.org/softprops.tngl.sh/moose" "go.mongodb.org/mongo-driver/v2/mongo")
func init() { moose.AddMigration(up{{.CamelName}}, down{{.CamelName}})}
func up{{.CamelName}}(ctx context.Context, client *mongo.Database) error { // This code is executed when the migration is applied. return nil}
func down{{.CamelName}}(ctx context.Context, client *mongo.Database) error { // This code is executed when the migration is rolled back. return nil}`))