177 lines
4.9 KiB
Go
177 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"git.mchus.pro/mchus/priceforge/internal/appstate"
|
|
"git.mchus.pro/mchus/priceforge/internal/config"
|
|
"git.mchus.pro/mchus/priceforge/internal/localdb"
|
|
"git.mchus.pro/mchus/priceforge/internal/models"
|
|
"gorm.io/driver/mysql"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
func main() {
|
|
configPath := flag.String("config", "config.yaml", "path to config file")
|
|
defaultLocalDBPath, err := appstate.ResolveDBPath("")
|
|
if err != nil {
|
|
log.Fatalf("Failed to resolve default local SQLite path: %v", err)
|
|
}
|
|
localDBPath := flag.String("localdb", defaultLocalDBPath, "path to local SQLite database (default: user state dir or QFS_DB_PATH)")
|
|
dryRun := flag.Bool("dry-run", false, "show what would be migrated without actually doing it")
|
|
flag.Parse()
|
|
|
|
log.Println("PriceForge Configuration Migration Tool")
|
|
log.Println("========================================")
|
|
|
|
// Load config for MariaDB connection
|
|
cfg, err := config.Load(*configPath)
|
|
if err != nil {
|
|
log.Fatalf("Failed to load config: %v", err)
|
|
}
|
|
|
|
// Connect to MariaDB
|
|
log.Printf("Connecting to MariaDB at %s:%d...", cfg.Database.Host, cfg.Database.Port)
|
|
mariaDB, err := gorm.Open(mysql.Open(cfg.Database.DSN()), &gorm.Config{
|
|
Logger: logger.Default.LogMode(logger.Silent),
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("Failed to connect to MariaDB: %v", err)
|
|
}
|
|
log.Println("Connected to MariaDB")
|
|
|
|
// Initialize local SQLite
|
|
log.Printf("Opening local SQLite at %s...", *localDBPath)
|
|
local, err := localdb.New(*localDBPath)
|
|
if err != nil {
|
|
log.Fatalf("Failed to initialize local database: %v", err)
|
|
}
|
|
log.Println("Local SQLite initialized")
|
|
|
|
// Count configurations in MariaDB
|
|
var serverCount int64
|
|
if err := mariaDB.Model(&models.Configuration{}).Count(&serverCount).Error; err != nil {
|
|
log.Fatalf("Failed to count configurations: %v", err)
|
|
}
|
|
log.Printf("Found %d configurations in MariaDB", serverCount)
|
|
|
|
if serverCount == 0 {
|
|
log.Println("No configurations to migrate")
|
|
return
|
|
}
|
|
|
|
// Get all configurations from MariaDB
|
|
var configs []models.Configuration
|
|
if err := mariaDB.Find(&configs).Error; err != nil {
|
|
log.Fatalf("Failed to fetch configurations: %v", err)
|
|
}
|
|
|
|
// Check existing local configurations
|
|
localCount := local.CountConfigurations()
|
|
log.Printf("Found %d configurations in local SQLite", localCount)
|
|
|
|
if *dryRun {
|
|
log.Println("\n[DRY RUN] Would migrate the following configurations:")
|
|
for _, c := range configs {
|
|
userName := c.OwnerUsername
|
|
if userName == "" {
|
|
userName = "unknown"
|
|
}
|
|
log.Printf(" - %s (UUID: %s, User: %s, Items: %d)", c.Name, c.UUID, userName, len(c.Items))
|
|
}
|
|
log.Printf("\nTotal: %d configurations", len(configs))
|
|
return
|
|
}
|
|
|
|
// Migrate configurations
|
|
log.Println("\nMigrating configurations...")
|
|
migrated := 0
|
|
skipped := 0
|
|
errors := 0
|
|
|
|
for _, c := range configs {
|
|
// Check if already exists
|
|
existing, err := local.GetConfigurationByUUID(c.UUID)
|
|
if err == nil && existing.ID > 0 {
|
|
log.Printf(" SKIP: %s (already exists)", c.Name)
|
|
skipped++
|
|
continue
|
|
}
|
|
|
|
// Convert items
|
|
localItems := make(localdb.LocalConfigItems, len(c.Items))
|
|
for i, item := range c.Items {
|
|
localItems[i] = localdb.LocalConfigItem{
|
|
LotName: item.LotName,
|
|
Quantity: item.Quantity,
|
|
UnitPrice: item.UnitPrice,
|
|
}
|
|
}
|
|
|
|
// Create local configuration
|
|
now := time.Now()
|
|
localConfig := &localdb.LocalConfiguration{
|
|
UUID: c.UUID,
|
|
ServerID: &c.ID,
|
|
ProjectUUID: c.ProjectUUID,
|
|
Name: c.Name,
|
|
Items: localItems,
|
|
TotalPrice: c.TotalPrice,
|
|
CustomPrice: c.CustomPrice,
|
|
Notes: c.Notes,
|
|
IsTemplate: c.IsTemplate,
|
|
ServerCount: c.ServerCount,
|
|
CreatedAt: c.CreatedAt,
|
|
UpdatedAt: now,
|
|
SyncedAt: &now,
|
|
SyncStatus: "synced",
|
|
OriginalUserID: derefUint(c.UserID),
|
|
OriginalUsername: c.OwnerUsername,
|
|
}
|
|
|
|
if err := local.SaveConfiguration(localConfig); err != nil {
|
|
log.Printf(" ERROR: %s - %v", c.Name, err)
|
|
errors++
|
|
continue
|
|
}
|
|
|
|
log.Printf(" OK: %s (%d items)", c.Name, len(c.Items))
|
|
migrated++
|
|
}
|
|
|
|
log.Println("\n========================================")
|
|
log.Printf("Migration complete!")
|
|
log.Printf(" Migrated: %d", migrated)
|
|
log.Printf(" Skipped: %d", skipped)
|
|
log.Printf(" Errors: %d", errors)
|
|
|
|
// Save connection settings to local SQLite if not exists
|
|
if !local.HasSettings() {
|
|
log.Println("\nSaving connection settings to local SQLite...")
|
|
if err := local.SaveSettings(
|
|
cfg.Database.Host,
|
|
cfg.Database.Port,
|
|
cfg.Database.Name,
|
|
cfg.Database.User,
|
|
cfg.Database.Password,
|
|
); err != nil {
|
|
log.Printf("Warning: Failed to save settings: %v", err)
|
|
} else {
|
|
log.Println("Connection settings saved")
|
|
}
|
|
}
|
|
|
|
fmt.Println("\nDone! You can now run the server with: go run ./cmd/server")
|
|
}
|
|
|
|
func derefUint(v *uint) uint {
|
|
if v == nil {
|
|
return 0
|
|
}
|
|
return *v
|
|
}
|