diff --git a/kernel/conf/search.go b/kernel/conf/search.go index 80275d1b7..eace0a039 100644 --- a/kernel/conf/search.go +++ b/kernel/conf/search.go @@ -36,6 +36,7 @@ type Search struct { SuperBlock bool `json:"superBlock"` Paragraph bool `json:"paragraph"` HTMLBlock bool `json:"htmlBlock"` + EmbedBlock bool `json:"embedBlock"` Limit int `json:"limit"` CaseSensitive bool `json:"caseSensitive"` @@ -71,6 +72,7 @@ func NewSearch() *Search { SuperBlock: true, Paragraph: true, HTMLBlock: true, + EmbedBlock: false, Limit: 64, CaseSensitive: true, @@ -180,6 +182,12 @@ func (s *Search) TypeFilter() string { buf.WriteByte('\'') buf.WriteString(",") } + if s.EmbedBlock { + buf.WriteByte('\'') + buf.WriteString(treenode.TypeAbbr(ast.NodeBlockQueryEmbed.String())) + buf.WriteByte('\'') + buf.WriteString(",") + } // 无法搜索到 iframe 块、视频块和音频块 https://github.com/siyuan-note/siyuan/issues/3604 buf.WriteString("'iframe','query_embed','video','audio',") // 挂件块支持内置属性搜索 https://github.com/siyuan-note/siyuan/issues/4497 diff --git a/kernel/main.go b/kernel/main.go index caf2dd1c7..d0f6dcc12 100644 --- a/kernel/main.go +++ b/kernel/main.go @@ -56,6 +56,7 @@ func main() { go treenode.AutoFlushBlockTree() go cache.LoadAssets() go model.AutoFixIndex() + go model.AutoIndexEmbedBlock() go model.AutoOCRAssets() go model.AutoFlushAssetsTexts() go model.HookDesktopUIProc() diff --git a/kernel/mobile/kernel.go b/kernel/mobile/kernel.go index c043809dc..58c3d9019 100644 --- a/kernel/mobile/kernel.go +++ b/kernel/mobile/kernel.go @@ -70,6 +70,7 @@ func StartKernel(container, appDir, workspaceBaseDir, timezoneID, localIPs, lang go treenode.AutoFlushBlockTree() go cache.LoadAssets() go model.AutoFixIndex() + go model.AutoIndexEmbedBlock() go model.AutoOCRAssets() go model.AutoFlushAssetsTexts() }() diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index cda7666c9..e68675d59 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -1216,6 +1216,27 @@ func updateRefText(refNode *ast.Node, changedDefNodes map[string]*ast.Node) (cha return } +// AutoIndexEmbedBlock 嵌入块支持搜索 https://github.com/siyuan-note/siyuan/issues/7112 +func AutoIndexEmbedBlock() { + for { + task.AppendTask(task.DatabaseIndexEmbedBlock, autoIndexEmbedBlock) + time.Sleep(30 * time.Second) + } +} + +func autoIndexEmbedBlock() { + embedBlocks := sql.QueryEmbedBlocks() + for _, embedBlock := range embedBlocks { + stmt := strings.TrimPrefix(embedBlock.Markdown, "{{") + stmt = strings.TrimSuffix(stmt, "}}") + blocks := sql.SelectBlocksRawStmtNoParse(stmt, 102400) + for _, block := range blocks { + embedBlock.Content = block.Content + sql.UpdateBlockContent(embedBlock) + } + } +} + // AutoFixIndex 自动校验数据库索引 https://github.com/siyuan-note/siyuan/issues/7016 func AutoFixIndex() { for { @@ -1229,13 +1250,6 @@ var autoFixLock = sync.Mutex{} func autoFixIndex() { defer logging.Recover() - if util.IsMutexLocked(&autoFixLock) { - return - } - - autoFixLock.Lock() - defer autoFixLock.Unlock() - // 根据文件系统补全块树 boxes := Conf.GetOpenedBoxes() for _, box := range boxes { diff --git a/kernel/sql/block.go b/kernel/sql/block.go index 6a39bd264..d88b888e2 100644 --- a/kernel/sql/block.go +++ b/kernel/sql/block.go @@ -55,9 +55,11 @@ func updateRootContent(tx *sql.Tx, content, updated, id string) { if err := execStmtTx(tx, stmt, content, content, updated, id); nil != err { return } - stmt = "UPDATE blocks_fts_case_insensitive SET content = ?, fcontent = ?, updated = ? WHERE id = ?" - if err := execStmtTx(tx, stmt, content, content, updated, id); nil != err { - return + if !caseSensitive { + stmt = "UPDATE blocks_fts_case_insensitive SET content = ?, fcontent = ?, updated = ? WHERE id = ?" + if err := execStmtTx(tx, stmt, content, content, updated, id); nil != err { + return + } } removeBlockCache(id) cache.RemoveBlockIAL(id) @@ -66,3 +68,30 @@ func updateRootContent(tx *sql.Tx, content, updated, id string) { func InsertBlock(tx *sql.Tx, block *Block, context map[string]interface{}) (err error) { return insertBlocks(tx, []*Block{block}, context) } + +func UpdateBlockContent(block *Block) { + tx, err := BeginTx() + if nil != err { + return + } + + stmt := "UPDATE blocks SET content = ? WHERE id = ?" + if err = execStmtTx(tx, stmt, block.Content, block.ID); nil != err { + tx.Rollback() + return + } + stmt = "UPDATE blocks_fts SET content = ? WHERE id = ?" + if err = execStmtTx(tx, stmt, block.Content, block.ID); nil != err { + tx.Rollback() + return + } + if !caseSensitive { + stmt = "UPDATE blocks_fts_case_insensitive SET content = ? WHERE id = ?" + if err = execStmtTx(tx, stmt, block.Content, block.ID); nil != err { + tx.Rollback() + return + } + } + tx.Commit() + putBlockCache(block) +} diff --git a/kernel/sql/block_query.go b/kernel/sql/block_query.go index 71b5bd8ac..32e35c108 100644 --- a/kernel/sql/block_query.go +++ b/kernel/sql/block_query.go @@ -31,6 +31,22 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func QueryEmbedBlocks() (ret []*Block) { + stmt := "SELECT * FROM blocks WHERE type = 'query_embed' AND content = ''" + rows, err := query(stmt) + if nil != err { + logging.LogErrorf("sql query [%s] failed: %s", stmt, err) + return + } + defer rows.Close() + for rows.Next() { + if block := scanBlockRows(rows); nil != block { + ret = append(ret, block) + } + } + return +} + func queryBlockHashes(rootID string) (ret map[string]string) { stmt := "SELECT id, hash FROM blocks WHERE root_id = ?" rows, err := query(stmt, rootID)