package main import ( "flag" "fmt" "git.wntrmute.dev/kyle/mcias/internal/db" ) func (t *tool) runSchema(args []string) { if len(args) == 0 { fatalf("schema requires a subcommand: verify, migrate, force") } switch args[0] { case "verify": t.schemaVerify() case "migrate": t.schemaMigrate() case "force": t.schemaForce(args[1:]) default: fatalf("unknown schema subcommand %q", args[0]) } } // schemaVerify reports the current schema version and exits 1 if migrations // are pending, 0 if the database is up-to-date. func (t *tool) schemaVerify() { version, err := db.SchemaVersion(t.db) if err != nil { fatalf("get schema version: %v", err) } latest := db.LatestSchemaVersion fmt.Printf("schema version: %d (latest: %d)\n", version, latest) if version < latest { fmt.Printf("%d migration(s) pending\n", latest-version) // Exit 1 to signal that migrations are needed (useful in scripts). // We call os.Exit directly rather than fatalf to avoid printing "mciasdb: ". fmt.Println("run 'mciasdb schema migrate' to apply pending migrations") exitCode1() } fmt.Println("schema is up-to-date") } // schemaForce marks the database as being at a specific migration version // without running any SQL. Use this to clear a dirty migration state after // you have verified that the schema already reflects the target version. // // Example: mciasdb schema force --version 6 func (t *tool) schemaForce(args []string) { fs := flag.NewFlagSet("schema force", flag.ExitOnError) version := fs.Int("version", 0, "schema version to force (required)") _ = fs.Parse(args) if *version <= 0 { fatalf("--version must be a positive integer") } if err := db.ForceSchemaVersion(t.db, *version); err != nil { fatalf("force schema version: %v", err) } fmt.Printf("schema version forced to %d; run 'schema migrate' to apply any remaining migrations\n", *version) } // schemaMigrate applies any pending migrations and reports each one. func (t *tool) schemaMigrate() { before, err := db.SchemaVersion(t.db) if err != nil { fatalf("get schema version: %v", err) } if err := db.Migrate(t.db); err != nil { fatalf("migrate: %v", err) } after, err := db.SchemaVersion(t.db) if err != nil { fatalf("get schema version after migrate: %v", err) } if before == after { fmt.Println("no migrations needed; schema is already up-to-date") return } fmt.Printf("migrated schema from version %d to %d\n", before, after) }