mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-09-22 00:20:47 +02:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
9df352efdb
7 changed files with 60 additions and 172 deletions
|
@ -564,27 +564,29 @@ func (av *AttributeView) GetCurrentView(viewID string) (ret *View, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (av *AttributeView) ExistBlock(blockID string) bool {
|
||||
for _, kv := range av.KeyValues {
|
||||
if KeyTypeBlock != kv.Key.Type {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, v := range kv.Values {
|
||||
if v.BlockID == blockID {
|
||||
func (av *AttributeView) ExistItem(itemID string) bool {
|
||||
for _, blockVal := range av.GetBlockKeyValues().Values {
|
||||
if blockVal.BlockID == itemID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (av *AttributeView) ExistBoundBlock(nodeID string) bool {
|
||||
for _, blockVal := range av.GetBlockKeyValues().Values {
|
||||
if blockVal.Block.ID == nodeID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (av *AttributeView) GetValue(keyID, blockID string) (ret *Value) {
|
||||
func (av *AttributeView) GetValue(keyID, itemID string) (ret *Value) {
|
||||
for _, kv := range av.KeyValues {
|
||||
if kv.Key.ID == keyID {
|
||||
for _, v := range kv.Values {
|
||||
if v.BlockID == blockID {
|
||||
if v.BlockID == itemID {
|
||||
ret = v
|
||||
return
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ func (value *Value) Filter(filter *ViewFilter, attrView *AttributeView, rowID st
|
|||
for _, blockID := range relVal.Relation.BlockIDs {
|
||||
destVal := destAv.GetValue(key.Rollup.KeyID, blockID)
|
||||
if nil == destVal {
|
||||
if destAv.ExistBlock(blockID) { // 数据库中存在行但是列值不存在是数据未初始化,这里补一个默认值
|
||||
if destAv.ExistItem(blockID) { // 数据库中存在项目但是字段值不存在是数据未初始化,这里补一个默认值
|
||||
destVal = GetAttributeViewDefaultValue(ast.NewNodeID(), key.Rollup.KeyID, blockID, destKey.Type)
|
||||
}
|
||||
if nil == destVal {
|
||||
|
|
|
@ -33,9 +33,9 @@ import (
|
|||
|
||||
type Value struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
KeyID string `json:"keyID,omitempty"`
|
||||
BlockID string `json:"blockID,omitempty"`
|
||||
Type KeyType `json:"type,omitempty"`
|
||||
KeyID string `json:"keyID,omitempty"` // 字段 ID
|
||||
BlockID string `json:"blockID,omitempty"` // 项目 ID
|
||||
Type KeyType `json:"type,omitempty"` // 字段类型
|
||||
IsDetached bool `json:"isDetached,omitempty"` // 是否为非绑定块,注意这个字段只能在主键(KeyTypeBlock)上使用,其他类型的值不要使用
|
||||
|
||||
CreatedAt int64 `json:"createdAt,omitempty"`
|
||||
|
|
|
@ -850,7 +850,7 @@ func AppendAttributeViewDetachedBlocksWithValues(avID string, blocksValues [][]*
|
|||
if av.KeyTypeBlock == v.Type {
|
||||
v.Block.Created = now
|
||||
v.Block.Updated = now
|
||||
v.Block.ID = "" // 非绑定块 ID 置空
|
||||
v.Block.ID = ""
|
||||
}
|
||||
v.IsDetached = true
|
||||
v.CreatedAt = now
|
||||
|
@ -1284,18 +1284,12 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
|
|||
if nil == attrView {
|
||||
attrView, _ = av.ParseAttributeView(avID)
|
||||
if nil == attrView {
|
||||
unbindBlockAv(nil, avID, blockID)
|
||||
return
|
||||
}
|
||||
attrViewCache[avID] = attrView
|
||||
}
|
||||
|
||||
if 1 > len(attrView.Views) {
|
||||
unbindBlockAv(nil, avID, blockID)
|
||||
return
|
||||
}
|
||||
|
||||
if !attrView.ExistBlock(blockID) {
|
||||
if !attrView.ExistBoundBlock(blockID) {
|
||||
// 比如剪切后粘贴,块 ID 会变,但是属性还在块上,这里做一次数据订正
|
||||
// Auto verify the database name when clicking the block superscript icon https://github.com/siyuan-note/siyuan/issues/10861
|
||||
unbindBlockAv(nil, avID, blockID)
|
||||
|
@ -1384,7 +1378,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
|
|||
for _, bID := range relVal.Relation.BlockIDs {
|
||||
destVal := destAv.GetValue(kv.Key.Rollup.KeyID, bID)
|
||||
if nil == destVal {
|
||||
if destAv.ExistBlock(bID) { // 数据库中存在行但是字段值不存在是数据未初始化,这里补一个默认值
|
||||
if destAv.ExistItem(bID) { // 数据库中存在项目但是字段值不存在是数据未初始化,这里补一个默认值
|
||||
destVal = av.GetAttributeViewDefaultValue(ast.NewNodeID(), kv.Key.Rollup.KeyID, bID, destKey.Type)
|
||||
}
|
||||
if nil == destVal {
|
||||
|
@ -1787,81 +1781,6 @@ func GetCurrentAttributeViewImages(avID, viewID, query string) (ret []string, er
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doUnbindAttrViewBlock(operation *Operation) (ret *TxErr) {
|
||||
err := unbindAttributeViewBlock(operation, tx)
|
||||
if err != nil {
|
||||
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func unbindAttributeViewBlock(operation *Operation, tx *Transaction) (err error) {
|
||||
attrView, err := av.ParseAttributeView(operation.AvID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
node, _, _ := getNodeByBlockID(tx, operation.ID)
|
||||
if nil == node {
|
||||
return
|
||||
}
|
||||
|
||||
var changedAvIDs []string
|
||||
for _, keyValues := range attrView.KeyValues {
|
||||
for _, value := range keyValues.Values {
|
||||
if av.KeyTypeRelation == value.Type {
|
||||
if nil != value.Relation {
|
||||
for i, relBlockID := range value.Relation.BlockIDs {
|
||||
if relBlockID == operation.ID {
|
||||
value.Relation.BlockIDs[i] = operation.NextID
|
||||
changedAvIDs = append(changedAvIDs, attrView.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if value.BlockID != operation.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
if av.KeyTypeBlock == value.Type {
|
||||
unbindBlockAv(tx, operation.AvID, value.BlockID)
|
||||
}
|
||||
value.BlockID = operation.NextID
|
||||
value.IsDetached = true
|
||||
if nil != value.Block {
|
||||
value.Block.ID = ""
|
||||
}
|
||||
|
||||
avIDs := replaceRelationAvValues(operation.AvID, operation.ID, operation.NextID)
|
||||
changedAvIDs = append(changedAvIDs, avIDs...)
|
||||
}
|
||||
}
|
||||
|
||||
replacedRowID := false
|
||||
for _, v := range attrView.Views {
|
||||
for i, itemID := range v.ItemIDs {
|
||||
if itemID == operation.ID {
|
||||
v.ItemIDs[i] = operation.NextID
|
||||
replacedRowID = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !replacedRowID {
|
||||
v.ItemIDs = append(v.ItemIDs, operation.NextID)
|
||||
}
|
||||
}
|
||||
|
||||
err = av.SaveAttributeView(attrView)
|
||||
|
||||
changedAvIDs = gulu.Str.RemoveDuplicatedElem(changedAvIDs)
|
||||
for _, avID := range changedAvIDs {
|
||||
ReloadAttrView(avID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewColDate(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewColDate(operation)
|
||||
if err != nil {
|
||||
|
@ -2623,20 +2542,20 @@ func (tx *Transaction) getAttrViewBoundNodes(attrView *av.AttributeView) (trees
|
|||
}
|
||||
|
||||
var tree *parse.Tree
|
||||
tree = trees[blockKeyValue.BlockID]
|
||||
tree = trees[blockKeyValue.Block.ID]
|
||||
if nil == tree {
|
||||
if nil == tx {
|
||||
tree, _ = LoadTreeByBlockID(blockKeyValue.BlockID)
|
||||
tree, _ = LoadTreeByBlockID(blockKeyValue.Block.ID)
|
||||
} else {
|
||||
tree, _ = tx.loadTree(blockKeyValue.BlockID)
|
||||
tree, _ = tx.loadTree(blockKeyValue.Block.ID)
|
||||
}
|
||||
}
|
||||
if nil == tree {
|
||||
continue
|
||||
}
|
||||
trees[blockKeyValue.BlockID] = tree
|
||||
trees[blockKeyValue.Block.ID] = tree
|
||||
|
||||
node := treenode.GetNodeInTree(tree, blockKeyValue.BlockID)
|
||||
node := treenode.GetNodeInTree(tree, blockKeyValue.Block.ID)
|
||||
if nil == node {
|
||||
continue
|
||||
}
|
||||
|
@ -4019,31 +3938,26 @@ func replaceAttributeViewBlock(avID, oldBlockID, newBlockID string, isDetached b
|
|||
|
||||
func replaceAttributeViewBlock0(attrView *av.AttributeView, oldBlockID, newBlockID string, isDetached bool, tx *Transaction) (err error) {
|
||||
avID := attrView.ID
|
||||
var node *ast.Node
|
||||
var tree *parse.Tree
|
||||
var node *ast.Node
|
||||
if !isDetached {
|
||||
node, tree, _ = getNodeByBlockID(tx, newBlockID)
|
||||
}
|
||||
|
||||
now := util.CurrentTimeMillis()
|
||||
// 检查是否已经存在绑定块,如果存在的话则重新绑定
|
||||
for _, keyValues := range attrView.KeyValues {
|
||||
for _, value := range keyValues.Values {
|
||||
if av.KeyTypeBlock == value.Type && nil != value.Block && value.BlockID == newBlockID {
|
||||
if !isDetached {
|
||||
for _, blockVal := range attrView.GetBlockKeyValues().Values {
|
||||
if !isDetached && blockVal.Block.ID == newBlockID && nil != node && nil != tree {
|
||||
bindBlockAv0(tx, avID, node, tree)
|
||||
value.IsDetached = false
|
||||
blockVal.IsDetached = false
|
||||
icon, content := getNodeAvBlockText(node)
|
||||
content = util.UnescapeHTML(content)
|
||||
value.Block.Icon, value.Block.Content = icon, content
|
||||
value.UpdatedAt = now
|
||||
blockVal.Block.Icon, blockVal.Block.Content = icon, content
|
||||
blockVal.UpdatedAt = now
|
||||
regenAttrViewGroups(attrView, "force")
|
||||
err = av.SaveAttributeView(attrView)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var changedAvIDs []string
|
||||
for _, keyValues := range attrView.KeyValues {
|
||||
|
@ -4063,45 +3977,25 @@ func replaceAttributeViewBlock0(attrView *av.AttributeView, oldBlockID, newBlock
|
|||
continue
|
||||
}
|
||||
|
||||
if av.KeyTypeBlock == value.Type && value.BlockID != newBlockID {
|
||||
// 换绑
|
||||
unbindBlockAv(tx, avID, value.BlockID)
|
||||
}
|
||||
|
||||
value.BlockID = newBlockID
|
||||
if av.KeyTypeBlock == value.Type && nil != value.Block {
|
||||
if av.KeyTypeBlock == value.Type {
|
||||
value.IsDetached = isDetached
|
||||
if !isDetached {
|
||||
if "" != value.Block.ID && value.Block.ID != newBlockID {
|
||||
unbindBlockAv(tx, avID, value.Block.ID)
|
||||
}
|
||||
bindBlockAv(tx, avID, newBlockID)
|
||||
|
||||
value.Block.ID = newBlockID
|
||||
icon, content := getNodeAvBlockText(node)
|
||||
content = util.UnescapeHTML(content)
|
||||
value.Block.Icon, value.Block.Content = icon, content
|
||||
|
||||
avIDs := replaceRelationAvValues(avID, oldBlockID, newBlockID)
|
||||
changedAvIDs = append(changedAvIDs, avIDs...)
|
||||
} else {
|
||||
value.Block.ID = ""
|
||||
}
|
||||
}
|
||||
|
||||
if av.KeyTypeBlock == value.Type && !isDetached {
|
||||
bindBlockAv(tx, avID, newBlockID)
|
||||
|
||||
avIDs := replaceRelationAvValues(avID, oldBlockID, newBlockID)
|
||||
changedAvIDs = append(changedAvIDs, avIDs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replacedRowID := false
|
||||
for _, v := range attrView.Views {
|
||||
for i, itemID := range v.ItemIDs {
|
||||
if itemID == oldBlockID {
|
||||
v.ItemIDs[i] = newBlockID
|
||||
replacedRowID = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !replacedRowID {
|
||||
v.ItemIDs = append(v.ItemIDs, newBlockID)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4135,18 +4029,13 @@ func BatchReplaceAttributeViewBlocks(avID string, isDetached bool, oldNew []map[
|
|||
}
|
||||
|
||||
func (tx *Transaction) doUpdateAttrViewCell(operation *Operation) (ret *TxErr) {
|
||||
err := updateAttributeViewCell(operation, tx)
|
||||
_, err := UpdateAttributeViewCell(tx, operation.AvID, operation.KeyID, operation.RowID, operation.Data)
|
||||
if err != nil {
|
||||
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func updateAttributeViewCell(operation *Operation, tx *Transaction) (err error) {
|
||||
_, err = UpdateAttributeViewCell(tx, operation.AvID, operation.KeyID, operation.RowID, operation.Data)
|
||||
return
|
||||
}
|
||||
|
||||
func BatchUpdateAttributeViewCells(tx *Transaction, avID string, values []interface{}) (err error) {
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
if err != nil {
|
||||
|
@ -4317,17 +4206,15 @@ func updateAttributeViewValue(tx *Transaction, attrView *av.AttributeView, keyID
|
|||
|
||||
if isUpdatingBlockKey {
|
||||
if oldIsDetached {
|
||||
// 之前是游离行
|
||||
// 之前是非绑定块
|
||||
|
||||
if !val.IsDetached { // 现在绑定了块
|
||||
// 将游离行绑定到新建的块上
|
||||
bindBlockAv(tx, avID, val.Block.ID)
|
||||
}
|
||||
} else {
|
||||
// 之前绑定了块
|
||||
|
||||
if val.IsDetached { // 现在是游离行
|
||||
// 将绑定的块从属性视图中移除
|
||||
if val.IsDetached { // 现在是非绑定块
|
||||
unbindBlockAv(tx, avID, blockID)
|
||||
} else {
|
||||
// 现在也绑定了块
|
||||
|
@ -4343,6 +4230,7 @@ func updateAttributeViewValue(tx *Transaction, attrView *av.AttributeView, keyID
|
|||
updateStaticText := true
|
||||
_, blockText := getNodeAvBlockText(node)
|
||||
if "" == content {
|
||||
// 使用动态锚文本
|
||||
val.Block.Content = util.UnescapeHTML(blockText)
|
||||
} else {
|
||||
if blockText == content {
|
||||
|
@ -4468,8 +4356,8 @@ func regenAttrViewGroups(attrView *av.AttributeView, keyID string) {
|
|||
}
|
||||
}
|
||||
|
||||
func unbindBlockAv(tx *Transaction, avID, blockID string) {
|
||||
node, tree, err := getNodeByBlockID(tx, blockID)
|
||||
func unbindBlockAv(tx *Transaction, avID, nodeID string) {
|
||||
node, tree, err := getNodeByBlockID(tx, nodeID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -4498,7 +4386,7 @@ func unbindBlockAv(tx *Transaction, avID, blockID string) {
|
|||
err = setNodeAttrs(node, tree, attrs)
|
||||
}
|
||||
if err != nil {
|
||||
logging.LogWarnf("set node [%s] attrs failed: %s", blockID, err)
|
||||
logging.LogWarnf("set node [%s] attrs failed: %s", nodeID, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
|
|
|
@ -277,8 +277,6 @@ func performTx(tx *Transaction) (ret *TxErr) {
|
|||
ret = tx.doHideAttrViewName(op)
|
||||
case "setAttrViewColDate":
|
||||
ret = tx.doSetAttrViewColDate(op)
|
||||
case "unbindAttrViewBlock":
|
||||
ret = tx.doUnbindAttrViewBlock(op)
|
||||
case "duplicateAttrViewKey":
|
||||
ret = tx.doDuplicateAttrViewKey(op)
|
||||
case "setAttrViewCoverFrom":
|
||||
|
|
|
@ -284,7 +284,7 @@ func filterNotFoundAttrViewItems(keyValuesMap *map[string][]*av.KeyValues) {
|
|||
continue
|
||||
}
|
||||
|
||||
toCheckBlockIDs = append(toCheckBlockIDs, blockID)
|
||||
toCheckBlockIDs = append(toCheckBlockIDs, blockValue.Block.ID)
|
||||
}
|
||||
checkRet := treenode.ExistBlockTrees(toCheckBlockIDs)
|
||||
for blockID, exist := range checkRet {
|
||||
|
@ -385,7 +385,7 @@ func fillAttributeViewAutoGeneratedValues(attrView *av.AttributeView, collection
|
|||
}
|
||||
|
||||
if nil == destVal {
|
||||
if destAv.ExistBlock(blockID) { // 数据库中存在行但是列值不存在是数据未初始化,这里补一个默认值
|
||||
if destAv.ExistItem(blockID) { // 数据库中存在项目但是字段值不存在是数据未初始化,这里补一个默认值
|
||||
destVal = av.GetAttributeViewDefaultValue(ast.NewNodeID(), rollupKey.Rollup.KeyID, blockID, destKey.Type)
|
||||
}
|
||||
if nil == destVal {
|
||||
|
|
|
@ -136,11 +136,11 @@ func fillAttributeViewGalleryCardCover(attrView *av.AttributeView, view *av.View
|
|||
break
|
||||
}
|
||||
|
||||
tree := trees[blockValue.BlockID]
|
||||
tree := trees[blockValue.Block.ID]
|
||||
if nil == tree {
|
||||
break
|
||||
}
|
||||
node := treenode.GetNodeInTree(tree, blockValue.BlockID)
|
||||
node := treenode.GetNodeInTree(tree, blockValue.Block.ID)
|
||||
if nil == node {
|
||||
break
|
||||
}
|
||||
|
@ -199,11 +199,11 @@ func fillAttributeViewGalleryCardCover(attrView *av.AttributeView, view *av.View
|
|||
break
|
||||
}
|
||||
|
||||
tree := trees[blockValue.BlockID]
|
||||
tree := trees[blockValue.Block.ID]
|
||||
if nil == tree {
|
||||
break
|
||||
}
|
||||
node := treenode.GetNodeInTree(tree, blockValue.BlockID)
|
||||
node := treenode.GetNodeInTree(tree, blockValue.Block.ID)
|
||||
if nil == node {
|
||||
break
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue