Introduce a commercial license option alongside AGPL-3.0-only, require a CLA for contributors, and document the terms in COMMERCIAL.md and NOTICE. Add a script to stamp SPDX headers on Go files and apply it across the tree.
120 lines
3.2 KiB
Go
120 lines
3.2 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
|
|
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/db"
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/logging"
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/migrate"
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
var migrateCmd = &cobra.Command{
|
|
Use: "migrate",
|
|
Short: "Database migration commands",
|
|
Long: "Run database migrations up, down, or check status",
|
|
}
|
|
|
|
var migrateUpCmd = &cobra.Command{
|
|
Use: "up",
|
|
Short: "Run all pending migrations",
|
|
Long: "Apply all pending database migrations",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
logger := slog.Default()
|
|
if logging.AppLogger != nil {
|
|
logger = logging.AppLogger
|
|
}
|
|
|
|
dbDSN := viper.GetString("db-dsn")
|
|
config := db.DefaultDBConfig(dbDSN)
|
|
database, err := db.ConnectPlain(context.Background(), logger, config)
|
|
if err != nil {
|
|
logger.Error("failed to connect to database", slog.Any("error", err))
|
|
return err
|
|
}
|
|
defer database.Close()
|
|
|
|
if err := db.RunMigrations(database, migrationSources()); err != nil {
|
|
logger.Error("failed to run migrations", slog.Any("error", err))
|
|
return err
|
|
}
|
|
|
|
logger.Info("migrations completed successfully")
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var migrateDownCmd = &cobra.Command{
|
|
Use: "down",
|
|
Short: "Rollback the last migration",
|
|
Long: "Rollback the most recently applied migration",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
logger := slog.Default()
|
|
if logging.AppLogger != nil {
|
|
logger = logging.AppLogger
|
|
}
|
|
|
|
dbDSN := viper.GetString("db-dsn")
|
|
config := db.DefaultDBConfig(dbDSN)
|
|
database, err := db.ConnectPlain(context.Background(), logger, config)
|
|
if err != nil {
|
|
logger.Error("failed to connect to database", slog.Any("error", err))
|
|
return err
|
|
}
|
|
defer database.Close()
|
|
|
|
if err := db.RollbackMigration(database, migrationSources()); err != nil {
|
|
logger.Error("failed to rollback migration", slog.Any("error", err))
|
|
return err
|
|
}
|
|
|
|
logger.Info("migration rollback completed successfully")
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var migrateStatusCmd = &cobra.Command{
|
|
Use: "status",
|
|
Short: "Show migration status",
|
|
Long: "Display the status of all migrations",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
logger := slog.Default()
|
|
if logging.AppLogger != nil {
|
|
logger = logging.AppLogger
|
|
}
|
|
|
|
dbDSN := viper.GetString("db-dsn")
|
|
config := db.DefaultDBConfig(dbDSN)
|
|
database, err := db.ConnectPlain(context.Background(), logger, config)
|
|
if err != nil {
|
|
logger.Error("failed to connect to database", slog.Any("error", err))
|
|
return err
|
|
}
|
|
defer database.Close()
|
|
|
|
if err := db.MigrationStatus(database, migrationSources()); err != nil {
|
|
logger.Error("failed to get migration status", slog.Any("error", err))
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
// migrationSources returns the ordered migration sources for all modules.
|
|
func migrationSources() []db.MigrationSource {
|
|
return migrate.Sources()
|
|
}
|
|
|
|
func init() {
|
|
migrateCmd.AddCommand(migrateUpCmd)
|
|
migrateCmd.AddCommand(migrateDownCmd)
|
|
migrateCmd.AddCommand(migrateStatusCmd)
|
|
rootCmd.AddCommand(migrateCmd)
|
|
}
|