package migrations import ( "bytes" "errors" "fmt" "strconv" "go.uber.org/zap" "git.sr.ht/~ashkeel/strimertul/database" ) const ( SchemaKey = "strimertul/schema-version" SchemaVersion = 4 ) // GetCurrentSchemaVersion returns the current schema version // from the database, or 0 if it's not set (v3.x.x or earlier) func GetCurrentSchemaVersion(db database.Database) (int, error) { versionStr, err := db.GetKey(SchemaKey) if err != nil { if errors.Is(err, database.ErrEmptyKey) { return 0, nil } } if versionStr == "" { return 0, nil } return strconv.Atoi(versionStr) } func Run(driver database.Driver, db database.Database, logger *zap.Logger) (err error) { // Make a backup of the database var buffer bytes.Buffer if err = driver.Backup(&buffer); err != nil { return fmt.Errorf("failed to backup database: %s", err) } // Restore the backup if an error occurs defer func() { if err != nil { restoreErr := driver.Restore(bytes.NewReader(buffer.Bytes())) if restoreErr != nil { logger.Error("Failed to restore database from backup", zap.Error(restoreErr)) } } }() // Get the current schema version var currentVersion int currentVersion, err = GetCurrentSchemaVersion(db) if err != nil { return } // Migrate from v3.x.x to v4.0.0 if currentVersion < 4 { if err = migrateToV4(db, logger); err != nil { return } } // Set the new schema version if err = db.PutKey(SchemaKey, strconv.Itoa(SchemaVersion)); err != nil { return } return }