🎨 Supports cleaning up unreferenced databases https://github.com/siyuan-note/siyuan/issues/11569

Signed-off-by: Daniel <845765@qq.com>
This commit is contained in:
Daniel 2026-01-27 22:58:56 +08:00
parent a77e0820ad
commit 1fa674e430
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
6 changed files with 319 additions and 90 deletions

View file

@ -38,12 +38,108 @@ import (
"github.com/siyuan-note/siyuan/kernel/av"
"github.com/siyuan-note/siyuan/kernel/cache"
"github.com/siyuan-note/siyuan/kernel/filesys"
"github.com/siyuan-note/siyuan/kernel/search"
"github.com/siyuan-note/siyuan/kernel/sql"
"github.com/siyuan-note/siyuan/kernel/treenode"
"github.com/siyuan-note/siyuan/kernel/util"
"github.com/xrash/smetrics"
)
func UnusedAttributeViews() (ret []string) {
defer logging.Recover()
ret = []string{}
allAvIDs, err := getAllAvIDs()
if err != nil {
return
}
referencedAvIDs := map[string]bool{}
luteEngine := util.NewLute()
boxes := Conf.GetBoxes()
for _, box := range boxes {
pages := pagedPaths(filepath.Join(util.DataDir, box.ID), 32)
for _, paths := range pages {
var trees []*parse.Tree
for _, localPath := range paths {
tree, loadTreeErr := loadTree(localPath, luteEngine)
if nil != loadTreeErr {
continue
}
trees = append(trees, tree)
}
for _, tree := range trees {
for _, id := range getAvIDs(tree, allAvIDs) {
referencedAvIDs[id] = true
}
}
}
}
templateAvIDs := search.FindAllMatchedTargets(filepath.Join(util.DataDir, "templates"), allAvIDs)
for _, id := range templateAvIDs {
referencedAvIDs[id] = true
}
for _, id := range allAvIDs {
if !referencedAvIDs[id] {
ret = append(ret, id)
}
}
ret = gulu.Str.RemoveDuplicatedElem(ret)
return
}
func getAvIDs(tree *parse.Tree, allAvIDs []string) (ret []string) {
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
}
if ast.NodeAttributeView == n.Type {
ret = append(ret, n.AttributeViewID)
}
for _, kv := range n.KramdownIAL {
ids := util.GetContainsSubStrs(kv[1], allAvIDs)
if 0 < len(ids) {
ret = append(ret, ids...)
}
}
return ast.WalkContinue
})
ret = gulu.Str.RemoveDuplicatedElem(ret)
return
}
func getAllAvIDs() (ret []string, err error) {
ret = []string{}
entries, err := os.ReadDir(filepath.Join(util.DataDir, "storage", "av"))
if nil != err {
return
}
for _, entry := range entries {
name := entry.Name()
if !strings.HasSuffix(name, ".json") {
continue
}
id := strings.TrimSuffix(name, ".json")
if !ast.IsNodeIDPattern(id) {
continue
}
ret = append(ret, id)
}
ret = gulu.Str.RemoveDuplicatedElem(ret)
return
}
func GetAttributeViewItemIDs(avID string, blockIDs []string) (ret map[string]string) {
ret = map[string]string{}
for _, blockID := range blockIDs {