Implement local DB migrations and archived configuration lifecycle
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
uuidpkg "github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
@@ -52,6 +53,7 @@ func New(dbPath string) (*LocalDB, error) {
|
||||
if err := db.AutoMigrate(
|
||||
&ConnectionSettings{},
|
||||
&LocalConfiguration{},
|
||||
&LocalConfigurationVersion{},
|
||||
&LocalPricelist{},
|
||||
&LocalPricelistItem{},
|
||||
&LocalComponent{},
|
||||
@@ -60,6 +62,9 @@ func New(dbPath string) (*LocalDB, error) {
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("migrating sqlite database: %w", err)
|
||||
}
|
||||
if err := runLocalMigrations(db); err != nil {
|
||||
return nil, fmt.Errorf("running local sqlite migrations: %w", err)
|
||||
}
|
||||
|
||||
slog.Info("local SQLite database initialized", "path", dbPath)
|
||||
|
||||
@@ -193,7 +198,59 @@ func (l *LocalDB) GetConfigurationByUUID(uuid string) (*LocalConfiguration, erro
|
||||
|
||||
// DeleteConfiguration deletes a configuration by UUID
|
||||
func (l *LocalDB) DeleteConfiguration(uuid string) error {
|
||||
return l.db.Where("uuid = ?", uuid).Delete(&LocalConfiguration{}).Error
|
||||
return l.DeactivateConfiguration(uuid)
|
||||
}
|
||||
|
||||
// DeactivateConfiguration marks configuration as inactive and appends one snapshot version.
|
||||
func (l *LocalDB) DeactivateConfiguration(uuid string) error {
|
||||
return l.db.Transaction(func(tx *gorm.DB) error {
|
||||
var cfg LocalConfiguration
|
||||
if err := tx.Where("uuid = ?", uuid).First(&cfg).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if !cfg.IsActive {
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg.IsActive = false
|
||||
cfg.UpdatedAt = time.Now()
|
||||
cfg.SyncStatus = "pending"
|
||||
if err := tx.Save(&cfg).Error; err != nil {
|
||||
return fmt.Errorf("save inactive configuration: %w", err)
|
||||
}
|
||||
|
||||
var maxVersion int
|
||||
if err := tx.Model(&LocalConfigurationVersion{}).
|
||||
Where("configuration_uuid = ?", cfg.UUID).
|
||||
Select("COALESCE(MAX(version_no), 0)").
|
||||
Scan(&maxVersion).Error; err != nil {
|
||||
return fmt.Errorf("read max version for deactivate: %w", err)
|
||||
}
|
||||
|
||||
snapshot, err := BuildConfigurationSnapshot(&cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("build deactivate snapshot: %w", err)
|
||||
}
|
||||
note := "deactivate via local delete"
|
||||
version := &LocalConfigurationVersion{
|
||||
ID: uuidpkg.NewString(),
|
||||
ConfigurationUUID: cfg.UUID,
|
||||
VersionNo: maxVersion + 1,
|
||||
Data: snapshot,
|
||||
ChangeNote: ¬e,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
if err := tx.Create(version).Error; err != nil {
|
||||
return fmt.Errorf("insert deactivate version: %w", err)
|
||||
}
|
||||
if err := tx.Model(&LocalConfiguration{}).
|
||||
Where("uuid = ?", cfg.UUID).
|
||||
Update("current_version_id", version.ID).Error; err != nil {
|
||||
return fmt.Errorf("set current version after deactivate: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// CountConfigurations returns the number of local configurations
|
||||
|
||||
Reference in New Issue
Block a user