From 368091bd533a304656fead391ed71cd690a9d6fb Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Fri, 10 Nov 2023 11:01:06 +0800 Subject: [PATCH] :art: Automatically check and eliminate duplicate reference relationships Fix https://github.com/siyuan-note/siyuan/issues/9618 --- kernel/model/backlink.go | 25 +++++++++++++++---------- kernel/model/index_fix.go | 20 ++++++++++++++++++++ kernel/sql/block_ref_query.go | 15 +++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/kernel/model/backlink.go b/kernel/model/backlink.go index 1e0743e89..faaef6b98 100644 --- a/kernel/model/backlink.go +++ b/kernel/model/backlink.go @@ -39,21 +39,26 @@ import ( func RefreshBacklink(id string) { WaitForWritingFiles() + refreshRefsByDefID(id) +} - refs := sql.QueryRefsByDefID(id, false) +func refreshRefsByDefID(defID string) { + refs := sql.QueryRefsByDefID(defID, false) trees := map[string]*parse.Tree{} for _, ref := range refs { tree := trees[ref.RootID] - if nil == tree { - var loadErr error - tree, loadErr = loadTreeByBlockID(ref.RootID) - if nil != loadErr { - logging.LogErrorf("refresh tree refs failed: %s", loadErr) - continue - } - trees[ref.RootID] = tree - sql.UpdateRefsTreeQueue(tree) + if nil != tree { + continue } + + var loadErr error + tree, loadErr = loadTreeByBlockID(ref.RootID) + if nil != loadErr { + logging.LogErrorf("refresh tree refs failed: %s", loadErr) + continue + } + trees[ref.RootID] = tree + sql.UpdateRefsTreeQueue(tree) } } diff --git a/kernel/model/index_fix.go b/kernel/model/index_fix.go index 0365a0b6c..f6c51eeea 100644 --- a/kernel/model/index_fix.go +++ b/kernel/model/index_fix.go @@ -52,12 +52,32 @@ func FixIndexJob() { task.AppendTask(task.DatabaseIndexFix, fixDatabaseIndexByBlockTree) sql.WaitForWritingDatabase() + task.AppendTask(task.DatabaseIndexFix, removeDuplicateDatabaseRefs) + util.PushStatusBar(Conf.Language(185)) debug.FreeOSMemory() } var autoFixLock = sync.Mutex{} +// removeDuplicateDatabaseRefs 删除重复的数据库引用关系。 +func removeDuplicateDatabaseRefs() { + defer logging.Recover() + + autoFixLock.Lock() + defer autoFixLock.Unlock() + + util.PushStatusBar(Conf.Language(58)) + duplicatedRootIDs := sql.GetRefDuplicatedDefRootIDs() + for _, rootID := range duplicatedRootIDs { + refreshRefsByDefID(rootID) + } + + if 0 < len(duplicatedRootIDs) { + logging.LogWarnf("exist more than one ref duplicated [%d], reindex it", duplicatedRootIDs) + } +} + // removeDuplicateDatabaseIndex 删除重复的数据库索引。 func removeDuplicateDatabaseIndex() { defer logging.Recover() diff --git a/kernel/sql/block_ref_query.go b/kernel/sql/block_ref_query.go index eb9fece8d..e631ff20f 100644 --- a/kernel/sql/block_ref_query.go +++ b/kernel/sql/block_ref_query.go @@ -28,6 +28,21 @@ import ( "github.com/siyuan-note/siyuan/kernel/search" ) +func GetRefDuplicatedDefRootIDs() (ret []string) { + rows, err := query("SELECT DISTINCT def_block_root_id FROM `refs` GROUP BY def_block_id, def_block_root_id HAVING COUNT(*) > 1 LIMIT 1") + if nil != err { + logging.LogErrorf("sql query failed: %s", err) + return + } + defer rows.Close() + for rows.Next() { + var id string + rows.Scan(&id) + ret = append(ret, id) + } + return +} + func QueryVirtualRefKeywords(name, alias, anchor, doc bool) (ret []string) { if name { ret = append(ret, queryNames()...)