Some checks failed
CI / Build & Test (push) Failing after 1m31s
- Add user management endpoints (list/create/get/update/delete) with pagination and search - Add dashboard stats endpoint with tenant/user/online counts and growth metrics - Add tenant resolver middleware for multi-tenant request scoping - Add i18n kernel with zh/en message files and AcceptLanguage middleware - Add WebSocket hub/handler for real-time communication - Add job scheduler kernel with cron support - Add plugin sandbox for isolated execution - Add storage kernel (local filesystem) - Add event bus kernel for pub/sub - Add cache kernel abstraction - Add database migration runner and version upgrade checker - Add rate limiting middleware with Redis backend - Add SQL migrations for rbac, audit_logs, settings, notifications, examples - Extend user repository with list/delete/count operations - Register all module routes with tenant resolver
108 lines
2.6 KiB
Go
108 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
"mengstack/internal/config"
|
|
"mengstack/migrations"
|
|
|
|
"github.com/golang-migrate/migrate/v4"
|
|
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
fmt.Println("Usage: migrate <command> [flags]")
|
|
fmt.Println("Commands: up, down, status")
|
|
fmt.Println(" up [steps] Run pending migrations (optional step count)")
|
|
fmt.Println(" down [steps] Rollback migrations (optional step count, 0=all)")
|
|
fmt.Println(" status Show current migration status")
|
|
os.Exit(1)
|
|
}
|
|
|
|
cfg, err := config.Load()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
dsn := fmt.Sprintf(
|
|
"postgres://%s:%s@%s:%d/%s?sslmode=%s&search_path=public",
|
|
cfg.Database.User, cfg.Database.Password,
|
|
cfg.Database.Host, cfg.Database.Port,
|
|
cfg.Database.DBName, cfg.Database.SSLMode,
|
|
)
|
|
|
|
source, err := iofs.New(migrations.Files, ".")
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error creating migration source: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
m, err := migrate.NewWithSourceInstance("iofs", source, dsn)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error creating migrator: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
cmd := os.Args[1]
|
|
switch cmd {
|
|
case "up":
|
|
steps := 0
|
|
fs := flag.NewFlagSet("up", flag.ExitOnError)
|
|
fs.IntVar(&steps, "steps", 0, "number of migrations to run (0=all)")
|
|
fs.Parse(os.Args[2:])
|
|
|
|
if steps > 0 {
|
|
err = m.Steps(steps)
|
|
} else {
|
|
err = m.Up()
|
|
}
|
|
if err != nil && err != migrate.ErrNoChange {
|
|
fmt.Fprintf(os.Stderr, "Migration error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
if err == migrate.ErrNoChange {
|
|
fmt.Println("No pending migrations")
|
|
} else {
|
|
fmt.Println("Migrations applied successfully")
|
|
}
|
|
|
|
case "down":
|
|
steps := 1
|
|
fs := flag.NewFlagSet("down", flag.ExitOnError)
|
|
fs.IntVar(&steps, "steps", 1, "number of migrations to rollback (0=all)")
|
|
fs.Parse(os.Args[2:])
|
|
|
|
if steps == 0 {
|
|
err = m.Down()
|
|
} else {
|
|
err = m.Steps(-steps)
|
|
}
|
|
if err != nil && err != migrate.ErrNoChange {
|
|
fmt.Fprintf(os.Stderr, "Rollback error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println("Rollback completed")
|
|
|
|
case "status":
|
|
v, dirty, err := m.Version()
|
|
if err != nil && err != migrate.ErrNoChange {
|
|
fmt.Fprintf(os.Stderr, "Status error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
if err == migrate.ErrNoChange {
|
|
fmt.Println("No migrations applied yet")
|
|
} else {
|
|
fmt.Printf("Current version: %d, dirty: %v\n", v, dirty)
|
|
}
|
|
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", cmd)
|
|
os.Exit(1)
|
|
}
|
|
}
|