Fix: replaced keys become stale

This commit is contained in:
2026-05-14 11:25:13 +02:00
parent e616ea5043
commit 8fcf0863cc
3 changed files with 92 additions and 11 deletions
+40 -10
View File
@@ -43,6 +43,7 @@ type nativeCollectedDataset struct {
Columns []string
Rows []map[string]any
LockData map[string]int
RetiredKeys map[string]struct{}
TableKey string
LockAdded int
LockPruned int
@@ -714,6 +715,7 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
lockModified := false
lockAdded := 0
lockPruned := 0
retiredKeys := map[string]struct{}{}
for key, rowID := range lockData {
if rowID <= baseBoundaryID {
@@ -871,13 +873,16 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
if err != nil {
return err
}
keyChanged, err := updateOverrideRowKey(dataset.Name, existing, expanded, rowByKey, lockData)
keyChanged, retiredKey, err := updateOverrideRowKey(dataset.Name, existing, expanded, rowByKey, lockData)
if err != nil {
return err
}
if keyChanged {
lockModified = true
}
if retiredKey != "" {
retiredKeys[retiredKey] = struct{}{}
}
for field, value := range expanded {
if field == "id" || field == "_tlk" {
continue
@@ -1010,13 +1015,16 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
if err != nil {
return err
}
keyChanged, err := updateOverrideRowKey(dataset.Name, row, expanded, rowByKey, lockData)
keyChanged, retiredKey, err := updateOverrideRowKey(dataset.Name, row, expanded, rowByKey, lockData)
if err != nil {
return err
}
if keyChanged {
lockModified = true
}
if retiredKey != "" {
retiredKeys[retiredKey] = struct{}{}
}
for field, value := range expanded {
if field == "id" || field == "_tlk" {
continue
@@ -1068,7 +1076,7 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
if err != nil {
return nativeCollectedDataset{}, fmt.Errorf("dataset %s: collect referenced keys: %w", dataset.Name, err)
}
if pruned, updated := pruneLockDataToActiveRows(lockData, rows, referencedKeys); pruned > 0 || updated > 0 {
if pruned, updated := pruneLockDataToActiveRows(lockData, rows, referencedKeys, retiredKeys); pruned > 0 || updated > 0 {
lockModified = true
lockPruned += pruned
}
@@ -1082,13 +1090,14 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
Columns: columns,
Rows: rows,
LockData: lockData,
RetiredKeys: retiredKeys,
LockAdded: lockAdded,
LockPruned: lockPruned,
LockModified: lockModified,
}, nil
}
func pruneLockDataToActiveRows(lockData map[string]int, rows []map[string]any, referencedKeys map[string]struct{}) (int, int) {
func pruneLockDataToActiveRows(lockData map[string]int, rows []map[string]any, referencedKeys map[string]struct{}, retiredKeys map[string]struct{}) (int, int) {
if len(lockData) == 0 {
return 0, 0
}
@@ -1108,6 +1117,11 @@ func pruneLockDataToActiveRows(lockData map[string]int, rows []map[string]any, r
}
pruned := 0
for key := range lockData {
if _, retired := retiredKeys[key]; retired {
delete(lockData, key)
pruned++
continue
}
if _, ok := activeKeys[key]; ok {
continue
}
@@ -4123,14 +4137,15 @@ func nullifyOverrideRow(row map[string]any, columns []string, rowByKey map[strin
}
}
func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[string]any, rowByKey map[string]map[string]any, lockData map[string]int) (bool, error) {
func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[string]any, rowByKey map[string]map[string]any, lockData map[string]int) (bool, string, error) {
oldKey, _ := row["key"].(string)
newKeyValue, hasKey := expanded["key"]
if !hasKey {
return false, nil
return false, "", nil
}
rowID, _ := row["id"].(int)
changed := false
retiredKey := ""
if oldKey != "" {
if mapped, ok := rowByKey[oldKey]; ok {
mappedID, mappedHasID := mapped["id"].(int)
@@ -4142,12 +4157,22 @@ func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[s
}
if newKeyValue == nil {
delete(row, "key")
return changed, nil
if oldKey != "" {
retiredKey = oldKey
delete(lockData, oldKey)
changed = true
}
return changed, retiredKey, nil
}
newKey, ok := newKeyValue.(string)
if !ok || newKey == "" || strings.TrimSpace(newKey) == nullValue {
delete(row, "key")
return changed, nil
if oldKey != "" {
retiredKey = oldKey
delete(lockData, oldKey)
changed = true
}
return changed, retiredKey, nil
}
conflictingID := -1
if conflicting, ok := rowByKey[newKey]; ok && conflicting != nil {
@@ -4161,20 +4186,25 @@ func updateOverrideRowKey(datasetName string, row map[string]any, expanded map[s
}
row["key"] = newKey
rowByKey[newKey] = row
if oldKey != "" && oldKey != newKey {
retiredKey = oldKey
delete(lockData, oldKey)
changed = true
}
if existingID, ok := lockData[newKey]; ok {
if existingID != rowID {
if conflictingID >= 0 && existingID == conflictingID {
lockData[newKey] = rowID
changed = true
} else {
return false, fmt.Errorf("dataset %s: key %q is locked to id %d and cannot be rewritten to id %d", datasetName, newKey, existingID, rowID)
return false, "", fmt.Errorf("dataset %s: key %q is locked to id %d and cannot be rewritten to id %d", datasetName, newKey, existingID, rowID)
}
}
} else {
lockData[newKey] = rowID
changed = true
}
return changed, nil
return changed, retiredKey, nil
}
func normalizeCollectedSpellImpactScripts(rows []map[string]any, baseRowKeys map[string]struct{}) {