Skip to content

Commit

Permalink
Fix store migration on empty string (#2149)
Browse files Browse the repository at this point in the history
* Fix store migration on empty string

when fetching empty values from the database to check for migration our parser failed to handle null strings preventing the service from start

this uses sql.NullString to handle that and check for empty string resulted from null data

---------

Co-authored-by: Viktor Liu <[email protected]>
  • Loading branch information
mlsmaycon and lixmal authored Jun 18, 2024
1 parent 919c1cb commit 381447b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
10 changes: 6 additions & 4 deletions management/server/migration/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,22 @@ func MigrateFieldFromGobToJSON[T any, S any](db *gorm.DB, fieldName string) erro
}
tableName := stmt.Schema.Table

var item string
if err := db.Model(model).Select(oldColumnName).First(&item).Error; err != nil {
var sqliteItem sql.NullString
if err := db.Model(model).Select(oldColumnName).First(&sqliteItem).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Debugf("No records in table %s, no migration needed", tableName)
return nil
}
return fmt.Errorf("fetch first record: %w", err)
}

item := sqliteItem.String

var js json.RawMessage
var syntaxError *json.SyntaxError
err = json.Unmarshal([]byte(item), &js)
if err == nil || !errors.As(err, &syntaxError) {
// if the item is JSON parsable or an empty string it can not be gob encoded
if err == nil || !errors.As(err, &syntaxError) || item == "" {
log.Debugf("No migration needed for %s, %s", tableName, fieldName)
return nil
}
Expand All @@ -74,7 +77,6 @@ func MigrateFieldFromGobToJSON[T any, S any](db *gorm.DB, fieldName string) erro
if err := gob.NewDecoder(reader).Decode(&field); err != nil {
return fmt.Errorf("gob decode error: %w", err)
}

jsonValue, err := json.Marshal(field)
if err != nil {
return fmt.Errorf("re-encode to JSON: %w", err)
Expand Down
21 changes: 21 additions & 0 deletions management/server/sql_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ func TestMigrate(t *testing.T) {
rt := &route{
Network: prefix,
PeerGroups: []string{"group1", "group2"},
Route: route2.Route{ID: "route1"},
}

err = store.db.Save(rt).Error
Expand All @@ -569,6 +570,26 @@ func TestMigrate(t *testing.T) {

err = migrate(store.db)
require.NoError(t, err, "Migration should not fail on migrated db")

err = store.db.Delete(rt).Where("id = ?", "route1").Error
require.NoError(t, err, "Failed to delete Gob data")

prefix = netip.MustParsePrefix("12.0.0.0/24")
nRT := &route2.Route{
Network: prefix,
ID: "route2",
Peer: "peer-id",
}

err = store.db.Save(nRT).Error
require.NoError(t, err, "Failed to insert json nil slice data")

err = migrate(store.db)
require.NoError(t, err, "Migration should not fail on json nil slice populated db")

err = migrate(store.db)
require.NoError(t, err, "Migration should not fail on migrated db")

}

func newSqliteStore(t *testing.T) *SqlStore {
Expand Down

0 comments on commit 381447b

Please sign in to comment.