修改包依赖名称
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -371,3 +372,219 @@ func LoadMigrationsFromFiles(dir string, pattern string) ([]Migration, error) {
|
||||
func GenerateVersion() string {
|
||||
return strconv.FormatInt(time.Now().Unix(), 10)
|
||||
}
|
||||
|
||||
// Reset 重置所有迁移(清空迁移记录表)
|
||||
// confirm: 确认标志,必须为true才能执行重置
|
||||
// 注意:此操作会清空所有迁移记录,但不会回滚已执行的迁移操作
|
||||
// 如果需要回滚迁移,请先使用Down方法逐个回滚
|
||||
func (m *Migrator) Reset(confirm bool) error {
|
||||
if !confirm {
|
||||
return fmt.Errorf("reset operation requires explicit confirmation (confirm must be true)")
|
||||
}
|
||||
|
||||
if err := m.initTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取已应用的迁移数量
|
||||
applied, err := m.getAppliedMigrations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := len(applied)
|
||||
if count == 0 {
|
||||
fmt.Println("No migrations to reset")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 清空迁移记录表
|
||||
err = m.db.Exec(fmt.Sprintf("DELETE FROM %s", m.tableName)).Error
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reset migrations: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Reset completed: %d migration record(s) cleared\n", count)
|
||||
fmt.Println("WARNING: This only clears migration records, not the actual database changes.")
|
||||
fmt.Println("If you need to rollback database changes, use Down() method before reset.")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetWithConfirm 交互式重置所有迁移(带确认提示)
|
||||
// 会提示用户数据会被清空,需要输入确认才能执行
|
||||
func (m *Migrator) ResetWithConfirm() error {
|
||||
if err := m.initTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取已应用的迁移数量
|
||||
applied, err := m.getAppliedMigrations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := len(applied)
|
||||
if count == 0 {
|
||||
fmt.Println("No migrations to reset")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 显示警告信息
|
||||
fmt.Println("=" + strings.Repeat("=", 60) + "=")
|
||||
fmt.Println("WARNING: This operation will clear all migration records!")
|
||||
fmt.Println("=" + strings.Repeat("=", 60) + "=")
|
||||
fmt.Printf("This will clear %d migration record(s) from the database.\n", count)
|
||||
fmt.Println()
|
||||
fmt.Println("IMPORTANT NOTES:")
|
||||
fmt.Println(" 1. This operation only clears migration records, NOT the actual database changes.")
|
||||
fmt.Println(" 2. If you need to rollback database changes, use Down() method before reset.")
|
||||
fmt.Println(" 3. After reset, you may need to re-run migrations if the database structure changed.")
|
||||
fmt.Println()
|
||||
fmt.Print("Type 'RESET' (all caps) to confirm, or anything else to cancel: ")
|
||||
|
||||
// 读取用户输入
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read confirmation: %w", err)
|
||||
}
|
||||
|
||||
// 去除换行符和空格
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
// 检查确认
|
||||
if input != "RESET" {
|
||||
fmt.Println("Reset operation cancelled.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 执行重置
|
||||
return m.Reset(true)
|
||||
}
|
||||
|
||||
// ResetAll 重置所有迁移并回滚所有已应用的迁移
|
||||
// confirm: 确认标志,必须为true才能执行
|
||||
// 注意:此操作会回滚所有已应用的迁移,然后清空迁移记录
|
||||
func (m *Migrator) ResetAll(confirm bool) error {
|
||||
if !confirm {
|
||||
return fmt.Errorf("reset all operation requires explicit confirmation (confirm must be true)")
|
||||
}
|
||||
|
||||
if err := m.initTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取已应用的迁移
|
||||
applied, err := m.getAppliedMigrations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := len(applied)
|
||||
if count == 0 {
|
||||
fmt.Println("No migrations to reset")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 回滚所有已应用的迁移
|
||||
fmt.Printf("Rolling back %d migration(s)...\n", count)
|
||||
|
||||
// 排序迁移(倒序)
|
||||
sort.Slice(m.migrations, func(i, j int) bool {
|
||||
return m.migrations[i].Version > m.migrations[j].Version
|
||||
})
|
||||
|
||||
// 回滚所有已应用的迁移
|
||||
for _, migration := range m.migrations {
|
||||
if !applied[migration.Version] {
|
||||
continue
|
||||
}
|
||||
|
||||
if migration.Down == nil {
|
||||
fmt.Printf("Warning: Migration %s has no Down function, skipping rollback\n", migration.Version)
|
||||
continue
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
tx := m.db.Begin()
|
||||
if tx.Error != nil {
|
||||
return fmt.Errorf("failed to begin transaction: %w", tx.Error)
|
||||
}
|
||||
|
||||
// 执行回滚
|
||||
if err := migration.Down(tx); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("failed to rollback migration %s: %w", migration.Version, err)
|
||||
}
|
||||
|
||||
// 删除迁移记录
|
||||
if err := m.recordMigrationWithDB(tx, migration.Version, migration.Description, false); err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return fmt.Errorf("failed to commit rollback %s: %w", migration.Version, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Rolled back migration: %s - %s\n", migration.Version, migration.Description)
|
||||
}
|
||||
|
||||
fmt.Printf("Reset all completed: %d migration(s) rolled back and records cleared\n", count)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetAllWithConfirm 交互式重置所有迁移并回滚(带确认提示)
|
||||
// 会提示用户数据会被清空,需要输入确认才能执行
|
||||
func (m *Migrator) ResetAllWithConfirm() error {
|
||||
if err := m.initTable(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取已应用的迁移数量
|
||||
applied, err := m.getAppliedMigrations()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := len(applied)
|
||||
if count == 0 {
|
||||
fmt.Println("No migrations to reset")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 显示警告信息
|
||||
fmt.Println("=" + strings.Repeat("=", 60) + "=")
|
||||
fmt.Println("WARNING: This operation will rollback ALL migrations and clear records!")
|
||||
fmt.Println("=" + strings.Repeat("=", 60) + "=")
|
||||
fmt.Printf("This will rollback %d migration(s) and clear all migration records.\n", count)
|
||||
fmt.Println()
|
||||
fmt.Println("IMPORTANT NOTES:")
|
||||
fmt.Println(" 1. This operation will EXECUTE Down() functions for all applied migrations.")
|
||||
fmt.Println(" 2. All database changes made by migrations will be REVERTED.")
|
||||
fmt.Println(" 3. This operation CANNOT be undone!")
|
||||
fmt.Println(" 4. Make sure you have a database backup before proceeding.")
|
||||
fmt.Println()
|
||||
fmt.Print("Type 'RESET ALL' (all caps) to confirm, or anything else to cancel: ")
|
||||
|
||||
// 读取用户输入
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read confirmation: %w", err)
|
||||
}
|
||||
|
||||
// 去除换行符和空格
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
// 检查确认
|
||||
if input != "RESET ALL" {
|
||||
fmt.Println("Reset all operation cancelled.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 执行重置
|
||||
return m.ResetAll(true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user