Merge branch 'refs/heads/migrate-with-json-serializer' into deploy/peer-performance

This commit is contained in:
bcmmbaga
2024-05-03 14:11:23 +03:00
3 changed files with 27 additions and 13 deletions
+24 -11
View File
@@ -1,6 +1,7 @@
package migration package migration
import ( import (
"database/sql"
"encoding/gob" "encoding/gob"
"encoding/json" "encoding/json"
"errors" "errors"
@@ -121,7 +122,7 @@ func MigrateNetIPFieldFromBlobToJSON[T any](db *gorm.DB, fieldName string, index
} }
tableName := stmt.Schema.Table tableName := stmt.Schema.Table
var item string var item sql.NullString
if err := db.Model(&model).Select(oldColumnName).First(&item).Error; err != nil { if err := db.Model(&model).Select(oldColumnName).First(&item).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
log.Printf("No records in table %s, no migration needed", tableName) log.Printf("No records in table %s, no migration needed", tableName)
@@ -130,12 +131,14 @@ func MigrateNetIPFieldFromBlobToJSON[T any](db *gorm.DB, fieldName string, index
return fmt.Errorf("fetch first record: %w", err) return fmt.Errorf("fetch first record: %w", err)
} }
var js json.RawMessage if item.Valid {
var syntaxError *json.SyntaxError var js json.RawMessage
err = json.Unmarshal([]byte(item), &js) var syntaxError *json.SyntaxError
if err == nil || !errors.As(err, &syntaxError) { err = json.Unmarshal([]byte(item.String), &js)
log.Debugf("No migration needed for %s, %s", tableName, fieldName) if err == nil || !errors.As(err, &syntaxError) {
return nil log.Debugf("No migration needed for %s, %s", tableName, fieldName)
return nil
}
} }
if err := db.Transaction(func(tx *gorm.DB) error { if err := db.Transaction(func(tx *gorm.DB) error {
@@ -153,12 +156,22 @@ func MigrateNetIPFieldFromBlobToJSON[T any](db *gorm.DB, fieldName string, index
} }
for _, row := range rows { for _, row := range rows {
blob, ok := row[oldColumnName].(string) var blobValue string
if !ok { if columnValue := row[oldColumnName]; columnValue != nil {
return fmt.Errorf("type assertion failed") value, ok := columnValue.(string)
if !ok {
return fmt.Errorf("type assertion failed")
}
blobValue = value
} }
jsonValue, err := json.Marshal(net.IP(blob)) columnIpValue := net.IP(blobValue)
if net.ParseIP(columnIpValue.String()) == nil {
log.Debugf("failed to parse %s as ip, fallback to ipv6 loopback", oldColumnName)
columnIpValue = net.IPv6loopback
}
jsonValue, err := json.Marshal(columnIpValue)
if err != nil { if err != nil {
return fmt.Errorf("re-encode to JSON: %w", err) return fmt.Errorf("re-encode to JSON: %w", err)
} }
@@ -145,6 +145,7 @@ func TestMigrateNetIPFieldFromBlobToJSON_WithJSONData(t *testing.T) {
require.NoError(t, err, "Failed to auto-migrate tables") require.NoError(t, err, "Failed to auto-migrate tables")
err = db.Save(&server.Account{ err = db.Save(&server.Account{
Id: "1234",
PeersG: []nbpeer.Peer{ PeersG: []nbpeer.Peer{
{Location: nbpeer.Location{ConnectionIP: net.IP{10, 0, 0, 1}}}, {Location: nbpeer.Location{ConnectionIP: net.IP{10, 0, 0, 1}}},
}}, }},
+2 -2
View File
@@ -622,10 +622,10 @@ func getMigrations() []migrationFunc {
return migration.MigrateFieldFromGobToJSON[route.Route, []string](db, "peer_groups") return migration.MigrateFieldFromGobToJSON[route.Route, []string](db, "peer_groups")
}, },
func(db *gorm.DB) error { func(db *gorm.DB) error {
return migration.MigrateNetIPFieldFromBlobToJSON[nbpeer.Peer](db, "ip", "idx_peers_account_id_ip") return migration.MigrateNetIPFieldFromBlobToJSON[nbpeer.Peer](db, "location_connection_ip", "")
}, },
func(db *gorm.DB) error { func(db *gorm.DB) error {
return migration.MigrateNetIPFieldFromBlobToJSON[nbpeer.Peer](db, "location_connection_ip", "") return migration.MigrateNetIPFieldFromBlobToJSON[nbpeer.Peer](db, "ip", "idx_peers_account_id_ip")
}, },
} }
} }