alter primary keys to uuids and adjust the membership system
This commit is contained in:
134
local/migrations/002_migrate_to_uuid.go
Normal file
134
local/migrations/002_migrate_to_uuid.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"acc-server-manager/local/utl/logging"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Migration002MigrateToUUID migrates tables from integer IDs to UUIDs
|
||||
type Migration002MigrateToUUID struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
// NewMigration002MigrateToUUID creates a new UUID migration
|
||||
func NewMigration002MigrateToUUID(db *gorm.DB) *Migration002MigrateToUUID {
|
||||
return &Migration002MigrateToUUID{DB: db}
|
||||
}
|
||||
|
||||
// Up executes the migration
|
||||
func (m *Migration002MigrateToUUID) Up() error {
|
||||
logging.Info("Checking UUID migration...")
|
||||
|
||||
// Check if migration is needed by looking at the servers table structure
|
||||
if !m.needsMigration() {
|
||||
logging.Info("UUID migration not needed - tables already use UUID primary keys")
|
||||
return nil
|
||||
}
|
||||
|
||||
logging.Info("Starting UUID migration...")
|
||||
|
||||
// Check if migration has already been applied
|
||||
var migrationRecord MigrationRecord
|
||||
err := m.DB.Where("migration_name = ?", "002_migrate_to_uuid").First(&migrationRecord).Error
|
||||
if err == nil {
|
||||
logging.Info("UUID migration already applied, skipping")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create migration tracking table if it doesn't exist
|
||||
if err := m.DB.AutoMigrate(&MigrationRecord{}); err != nil {
|
||||
return fmt.Errorf("failed to create migration tracking table: %v", err)
|
||||
}
|
||||
|
||||
// Execute the UUID migration using the existing migration function
|
||||
logging.Info("Executing UUID migration...")
|
||||
if err := runUUIDMigrationSQL(m.DB); err != nil {
|
||||
return fmt.Errorf("failed to execute UUID migration: %v", err)
|
||||
}
|
||||
|
||||
logging.Info("UUID migration completed successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
// needsMigration checks if the UUID migration is needed by examining table structure
|
||||
func (m *Migration002MigrateToUUID) needsMigration() bool {
|
||||
// Check if servers table exists and has integer primary key
|
||||
var result struct {
|
||||
Type string `gorm:"column:type"`
|
||||
}
|
||||
|
||||
err := m.DB.Raw(`
|
||||
SELECT type FROM pragma_table_info('servers')
|
||||
WHERE name = 'id' AND pk = 1
|
||||
`).Scan(&result).Error
|
||||
|
||||
if err != nil || result.Type == "" {
|
||||
// Table doesn't exist or no primary key found - assume no migration needed
|
||||
return false
|
||||
}
|
||||
|
||||
// If the primary key is INTEGER, we need migration
|
||||
// If it's TEXT (UUID), migration already done
|
||||
return result.Type == "INTEGER" || result.Type == "integer"
|
||||
}
|
||||
|
||||
// Down reverses the migration (not implemented for safety)
|
||||
func (m *Migration002MigrateToUUID) Down() error {
|
||||
logging.Error("UUID migration rollback is not supported for data safety reasons")
|
||||
return fmt.Errorf("UUID migration rollback is not supported")
|
||||
}
|
||||
|
||||
// runUUIDMigrationSQL executes the UUID migration using the SQL file
|
||||
func runUUIDMigrationSQL(db *gorm.DB) error {
|
||||
// Disable foreign key constraints during migration
|
||||
if err := db.Exec("PRAGMA foreign_keys=OFF").Error; err != nil {
|
||||
return fmt.Errorf("failed to disable foreign keys: %v", err)
|
||||
}
|
||||
|
||||
// Start transaction
|
||||
tx := db.Begin()
|
||||
if tx.Error != nil {
|
||||
return fmt.Errorf("failed to start transaction: %v", tx.Error)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
// Read the migration SQL from file
|
||||
sqlPath := filepath.Join("scripts", "migrations", "002_migrate_servers_to_uuid.sql")
|
||||
migrationSQL, err := ioutil.ReadFile(sqlPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read migration SQL file: %v", err)
|
||||
}
|
||||
|
||||
// Execute the migration
|
||||
if err := tx.Exec(string(migrationSQL)).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("failed to execute migration: %v", err)
|
||||
}
|
||||
|
||||
// Commit transaction
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
return fmt.Errorf("failed to commit migration: %v", err)
|
||||
}
|
||||
|
||||
// Re-enable foreign key constraints
|
||||
if err := db.Exec("PRAGMA foreign_keys=ON").Error; err != nil {
|
||||
return fmt.Errorf("failed to re-enable foreign keys: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunUUIDMigration is a convenience function to run the migration
|
||||
func RunUUIDMigration(db *gorm.DB) error {
|
||||
migration := NewMigration002MigrateToUUID(db)
|
||||
return migration.Up()
|
||||
}
|
||||
Reference in New Issue
Block a user