diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index c0446d980..9a438d618 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1343,6 +1343,8 @@ func unbindAttributeViewBlock(operation *Operation, tx *Transaction) (err error) if nil != value.Block { value.Block.ID = operation.NextID } + + replaceRelationAvValues(operation.AvID, operation.ID, operation.NextID) } } @@ -3022,6 +3024,8 @@ func replaceAttributeViewBlock(operation *Operation, tx *Transaction) (err error if av.KeyTypeBlock == value.Type && !operation.IsDetached { bindBlockAv(tx, operation.AvID, operation.NextID) + + replaceRelationAvValues(operation.AvID, operation.PreviousID, operation.NextID) } } } @@ -3537,3 +3541,43 @@ func getAttrViewName(attrView *av.AttributeView) string { } return ret } + +func replaceRelationAvValues(avID, previousID, nextID string) { + // The database relation fields follow the change after the primary key field is changed https://github.com/siyuan-note/siyuan/issues/11117 + + srcAvIDs := av.GetSrcAvIDs(avID) + for _, srcAvID := range srcAvIDs { + srcAv, parseErr := av.ParseAttributeView(srcAvID) + changed := false + if nil != parseErr { + continue + } + + for _, srcKeyValues := range srcAv.KeyValues { + if av.KeyTypeRelation != srcKeyValues.Key.Type { + continue + } + + if avID != srcKeyValues.Key.Relation.AvID { + continue + } + + for _, srcValue := range srcKeyValues.Values { + if nil == srcValue.Relation { + continue + } + + srcAvChanged := false + srcValue.Relation.BlockIDs, srcAvChanged = util.ReplaceStr(srcValue.Relation.BlockIDs, previousID, nextID) + if srcAvChanged { + changed = true + } + } + } + + if changed { + av.SaveAttributeView(srcAv) + util.PushReloadAttrView(srcAvID) + } + } +} diff --git a/kernel/util/misc.go b/kernel/util/misc.go index 3a55688c5..84295a52f 100644 --- a/kernel/util/misc.go +++ b/kernel/util/misc.go @@ -135,3 +135,18 @@ func ContainsSubStr(s string, subStrs []string) bool { } return false } + +func ReplaceStr(strs []string, old, new string) (ret []string, changed bool) { + if old == new { + return strs, false + } + + for i, v := range strs { + if v == old { + strs[i] = new + changed = true + } + } + ret = strs + return +}