package main import ( "flag" "fmt" "log" "os" "strings" "gitlab.com/mbugroup/lti-api.git/internal/config" "gitlab.com/mbugroup/lti-api.git/internal/database" "gorm.io/gorm" ) type options struct { FilePath string Apply bool } func main() { var opts options flag.StringVar(&opts.FilePath, "file", "", "Path to .sql file (required)") flag.BoolVar(&opts.Apply, "apply", false, "Apply SQL to database. If false, run as dry-run") flag.Parse() opts.FilePath = strings.TrimSpace(opts.FilePath) if opts.FilePath == "" { log.Fatal("--file is required") } sqlContent, err := readSQLFile(opts.FilePath) if err != nil { log.Fatalf("failed reading sql file: %v", err) } mode := "dry-run" if opts.Apply { mode = "apply" } fmt.Printf("Mode: %s\n", mode) fmt.Printf("File: %s\n", opts.FilePath) fmt.Printf("SQL bytes: %d\n", len(sqlContent)) if !opts.Apply { fmt.Println("Dry-run only. Add --apply to execute the SQL file.") return } db := database.Connect(config.DBHost, config.DBName) if err := executeSQL(db, sqlContent); err != nil { log.Fatalf("failed executing sql file: %v", err) } fmt.Println("DONE: SQL executed successfully") } func readSQLFile(path string) (string, error) { raw, err := os.ReadFile(path) if err != nil { return "", err } sql := strings.TrimSpace(strings.TrimPrefix(string(raw), "\ufeff")) if sql == "" { return "", fmt.Errorf("sql file is empty") } return sql, nil } func executeSQL(db *gorm.DB, sql string) error { return db.Transaction(func(tx *gorm.DB) error { return tx.Exec(sql).Error }) }