Переглянути джерело

:art: Automatically check and eliminate duplicate reference relationships Fix https://github.com/siyuan-note/siyuan/issues/9618

Daniel 1 рік тому
батько
коміт
368091bd53
3 змінених файлів з 50 додано та 10 видалено
  1. 15 10
      kernel/model/backlink.go
  2. 20 0
      kernel/model/index_fix.go
  3. 15 0
      kernel/sql/block_ref_query.go

+ 15 - 10
kernel/model/backlink.go

@@ -39,21 +39,26 @@ import (
 
 
 func RefreshBacklink(id string) {
 func RefreshBacklink(id string) {
 	WaitForWritingFiles()
 	WaitForWritingFiles()
+	refreshRefsByDefID(id)
+}
 
 
-	refs := sql.QueryRefsByDefID(id, false)
+func refreshRefsByDefID(defID string) {
+	refs := sql.QueryRefsByDefID(defID, false)
 	trees := map[string]*parse.Tree{}
 	trees := map[string]*parse.Tree{}
 	for _, ref := range refs {
 	for _, ref := range refs {
 		tree := trees[ref.RootID]
 		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)
 	}
 	}
 }
 }
 
 

+ 20 - 0
kernel/model/index_fix.go

@@ -52,12 +52,32 @@ func FixIndexJob() {
 	task.AppendTask(task.DatabaseIndexFix, fixDatabaseIndexByBlockTree)
 	task.AppendTask(task.DatabaseIndexFix, fixDatabaseIndexByBlockTree)
 	sql.WaitForWritingDatabase()
 	sql.WaitForWritingDatabase()
 
 
+	task.AppendTask(task.DatabaseIndexFix, removeDuplicateDatabaseRefs)
+
 	util.PushStatusBar(Conf.Language(185))
 	util.PushStatusBar(Conf.Language(185))
 	debug.FreeOSMemory()
 	debug.FreeOSMemory()
 }
 }
 
 
 var autoFixLock = sync.Mutex{}
 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 删除重复的数据库索引。
 // removeDuplicateDatabaseIndex 删除重复的数据库索引。
 func removeDuplicateDatabaseIndex() {
 func removeDuplicateDatabaseIndex() {
 	defer logging.Recover()
 	defer logging.Recover()

+ 15 - 0
kernel/sql/block_ref_query.go

@@ -28,6 +28,21 @@ import (
 	"github.com/siyuan-note/siyuan/kernel/search"
 	"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) {
 func QueryVirtualRefKeywords(name, alias, anchor, doc bool) (ret []string) {
 	if name {
 	if name {
 		ret = append(ret, queryNames()...)
 		ret = append(ret, queryNames()...)