diff --git a/kernel/model/block.go b/kernel/model/block.go index 8b62d12ff..3978cddda 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -25,31 +25,32 @@ import ( // Block 描述了内容块。 type Block struct { - Box string `json:"box"` - Path string `json:"path"` - HPath string `json:"hPath"` - ID string `json:"id"` - RootID string `json:"rootID"` - ParentID string `json:"parentID"` - Name string `json:"name"` - Alias string `json:"alias"` - Memo string `json:"memo"` - Tag string `json:"tag"` - Content string `json:"content"` - FContent string `json:"fcontent"` - Markdown string `json:"markdown"` - Folded bool `json:"folded"` - Type string `json:"type"` - SubType string `json:"subType"` - RefText string `json:"refText"` - Defs []*Block `json:"-"` // 当前块引用了这些块,避免序列化 JSON 时产生循环引用 - Refs []*Block `json:"refs"` // 当前块被这些块引用 - DefID string `json:"defID"` - DefPath string `json:"defPath"` - IAL map[string]string `json:"ial"` - Children []*Block `json:"children"` - Depth int `json:"depth"` - Count int `json:"count"` + Box string `json:"box"` + Path string `json:"path"` + HPath string `json:"hPath"` + ID string `json:"id"` + RootID string `json:"rootID"` + ParentID string `json:"parentID"` + Name string `json:"name"` + Alias string `json:"alias"` + Memo string `json:"memo"` + Tag string `json:"tag"` + Content string `json:"content"` + FContent string `json:"fcontent"` + Markdown string `json:"markdown"` + FMarkdown string `json:"fmarkdown"` + Folded bool `json:"folded"` + Type string `json:"type"` + SubType string `json:"subType"` + RefText string `json:"refText"` + Defs []*Block `json:"-"` // 当前块引用了这些块,避免序列化 JSON 时产生循环引用 + Refs []*Block `json:"refs"` // 当前块被这些块引用 + DefID string `json:"defID"` + DefPath string `json:"defPath"` + IAL map[string]string `json:"ial"` + Children []*Block `json:"children"` + Depth int `json:"depth"` + Count int `json:"count"` } func (block *Block) IsContainerBlock() bool { diff --git a/kernel/model/search.go b/kernel/model/search.go index 8a919fa2e..879508529 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -486,24 +486,25 @@ func fromSQLBlock(sqlBlock *sql.Block, terms string, beforeLen int) (block *Bloc p := sqlBlock.Path content, _ = markSearch(content, terms, beforeLen) - markdown := maxContent(sqlBlock.Markdown, 5120) content = maxContent(content, 5120) + markdown := maxContent(sqlBlock.Markdown, 5120) block = &Block{ - Box: sqlBlock.Box, - Path: p, - ID: id, - RootID: sqlBlock.RootID, - ParentID: sqlBlock.ParentID, - Alias: sqlBlock.Alias, - Name: sqlBlock.Name, - Memo: sqlBlock.Memo, - Tag: sqlBlock.Tag, - Content: content, - FContent: sqlBlock.FContent, - Markdown: markdown, - Type: treenode.FromAbbrType(sqlBlock.Type), - SubType: sqlBlock.SubType, + Box: sqlBlock.Box, + Path: p, + ID: id, + RootID: sqlBlock.RootID, + ParentID: sqlBlock.ParentID, + Alias: sqlBlock.Alias, + Name: sqlBlock.Name, + Memo: sqlBlock.Memo, + Tag: sqlBlock.Tag, + Content: content, + FContent: sqlBlock.FContent, + Markdown: markdown, + FMarkdown: sqlBlock.FMarkdown, + Type: treenode.FromAbbrType(sqlBlock.Type), + SubType: sqlBlock.SubType, } if "" != sqlBlock.IAL { block.IAL = map[string]string{} diff --git a/kernel/sql/block.go b/kernel/sql/block.go index f5c979c42..63bcc846a 100644 --- a/kernel/sql/block.go +++ b/kernel/sql/block.go @@ -21,27 +21,28 @@ import ( ) type Block struct { - ID string - ParentID string - RootID string - Hash string - Box string - Path string - HPath string - Name string - Alias string - Memo string - Tag string - Content string - FContent string - Markdown string - Length int - Type string - SubType string - IAL string - Sort int - Created string - Updated string + ID string + ParentID string + RootID string + Hash string + Box string + Path string + HPath string + Name string + Alias string + Memo string + Tag string + Content string + FContent string + Markdown string + FMarkdown string + Length int + Type string + SubType string + IAL string + Sort int + Created string + Updated string } func updateRootContent(tx *sql.Tx, content, id string) { diff --git a/kernel/sql/block_query.go b/kernel/sql/block_query.go index 84fd3b829..e5cca87ad 100644 --- a/kernel/sql/block_query.go +++ b/kernel/sql/block_query.go @@ -62,7 +62,7 @@ func QueryRootBlockByCondition(condition string) (ret []*Block) { for rows.Next() { var block Block var sepCount int - if err = rows.Scan(&block.ID, &block.ParentID, &block.RootID, &block.Hash, &block.Box, &block.Path, &block.HPath, &block.Name, &block.Alias, &block.Memo, &block.Tag, &block.Content, &block.FContent, &block.Markdown, &block.Length, &block.Type, &block.SubType, &block.IAL, &block.Sort, &block.Created, &block.Updated, &sepCount); nil != err { + if err = rows.Scan(&block.ID, &block.ParentID, &block.RootID, &block.Hash, &block.Box, &block.Path, &block.HPath, &block.Name, &block.Alias, &block.Memo, &block.Tag, &block.Content, &block.FContent, &block.Markdown, &block.FMarkdown, &block.Length, &block.Type, &block.SubType, &block.IAL, &block.Sort, &block.Created, &block.Updated, &sepCount); nil != err { logging.LogErrorf("query scan field failed: %s", err) return } @@ -484,7 +484,7 @@ func selectBlocksRawStmt(stmt string, limit int) (ret []*Block) { func scanBlockRows(rows *sql.Rows) (ret *Block) { var block Block - if err := rows.Scan(&block.ID, &block.ParentID, &block.RootID, &block.Hash, &block.Box, &block.Path, &block.HPath, &block.Name, &block.Alias, &block.Memo, &block.Tag, &block.Content, &block.FContent, &block.Markdown, &block.Length, &block.Type, &block.SubType, &block.IAL, &block.Sort, &block.Created, &block.Updated); nil != err { + if err := rows.Scan(&block.ID, &block.ParentID, &block.RootID, &block.Hash, &block.Box, &block.Path, &block.HPath, &block.Name, &block.Alias, &block.Memo, &block.Tag, &block.Content, &block.FContent, &block.Markdown, &block.FMarkdown, &block.Length, &block.Type, &block.SubType, &block.IAL, &block.Sort, &block.Created, &block.Updated); nil != err { logging.LogErrorf("query scan field failed: %s\n%s", err, logging.ShortStack()) return } @@ -494,7 +494,7 @@ func scanBlockRows(rows *sql.Rows) (ret *Block) { func scanBlockRow(row *sql.Row) (ret *Block) { var block Block - if err := row.Scan(&block.ID, &block.ParentID, &block.RootID, &block.Hash, &block.Box, &block.Path, &block.HPath, &block.Name, &block.Alias, &block.Memo, &block.Tag, &block.Content, &block.FContent, &block.Markdown, &block.Length, &block.Type, &block.SubType, &block.IAL, &block.Sort, &block.Created, &block.Updated); nil != err { + if err := row.Scan(&block.ID, &block.ParentID, &block.RootID, &block.Hash, &block.Box, &block.Path, &block.HPath, &block.Name, &block.Alias, &block.Memo, &block.Tag, &block.Content, &block.FContent, &block.Markdown, &block.FMarkdown, &block.Length, &block.Type, &block.SubType, &block.IAL, &block.Sort, &block.Created, &block.Updated); nil != err { if sql.ErrNoRows != err { logging.LogErrorf("query scan field failed: %s\n%s", err, logging.ShortStack()) } diff --git a/kernel/sql/block_ref_query.go b/kernel/sql/block_ref_query.go index 9d7d3425b..ce4b4a517 100644 --- a/kernel/sql/block_ref_query.go +++ b/kernel/sql/block_ref_query.go @@ -375,7 +375,7 @@ func DefRefs(condition string) (ret []map[*Block]*Block) { for rows.Next() { var ref Block var rel string - if err = rows.Scan(&ref.ID, &ref.ParentID, &ref.RootID, &ref.Hash, &ref.Box, &ref.Path, &ref.HPath, &ref.Name, &ref.Alias, &ref.Memo, &ref.Tag, &ref.Content, &ref.FContent, &ref.Markdown, &ref.Length, &ref.Type, &ref.SubType, &ref.IAL, &ref.Sort, &ref.Created, &ref.Updated, + if err = rows.Scan(&ref.ID, &ref.ParentID, &ref.RootID, &ref.Hash, &ref.Box, &ref.Path, &ref.HPath, &ref.Name, &ref.Alias, &ref.Memo, &ref.Tag, &ref.Content, &ref.FContent, &ref.Markdown, &ref.FMarkdown, &ref.Length, &ref.Type, &ref.SubType, &ref.IAL, &ref.Sort, &ref.Created, &ref.Updated, &rel); nil != err { logging.LogErrorf("query scan field failed: %s", err) return diff --git a/kernel/sql/database.go b/kernel/sql/database.go index 0439e0e72..d773c0a68 100644 --- a/kernel/sql/database.go +++ b/kernel/sql/database.go @@ -66,6 +66,7 @@ func InitDatabase(forceRebuild bool) (err error) { if util.DatabaseVer == getDatabaseVer() { return } + logging.LogInfof("the database structure is changed, rebuilding database...") } // 不存在库或者版本不一致都会走到这里 @@ -98,19 +99,19 @@ func initDBTables() { setDatabaseVer() db.Exec("DROP TABLE blocks") - _, err = db.Exec("CREATE TABLE blocks (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, length, type, subtype, ial, sort, created, updated)") + _, err = db.Exec("CREATE TABLE blocks (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, fmarkdown, length, type, subtype, ial, sort, created, updated)") if nil != err { logging.LogFatalf("create table [blocks] failed: %s", err) } db.Exec("DROP TABLE blocks_fts") - _, err = db.Exec("CREATE VIRTUAL TABLE blocks_fts USING fts5(id UNINDEXED, parent_id UNINDEXED, root_id UNINDEXED, hash UNINDEXED, box UNINDEXED, path UNINDEXED, hpath, name, alias, memo, tag, content, fcontent, markdown UNINDEXED, length UNINDEXED, type UNINDEXED, subtype UNINDEXED, ial, sort UNINDEXED, created UNINDEXED, updated UNINDEXED, tokenize=\"siyuan\")") + _, err = db.Exec("CREATE VIRTUAL TABLE blocks_fts USING fts5(id UNINDEXED, parent_id UNINDEXED, root_id UNINDEXED, hash UNINDEXED, box UNINDEXED, path UNINDEXED, hpath, name, alias, memo, tag, content, fcontent, markdown UNINDEXED, fmarkdown UNINDEXED, length UNINDEXED, type UNINDEXED, subtype UNINDEXED, ial, sort UNINDEXED, created UNINDEXED, updated UNINDEXED, tokenize=\"siyuan\")") if nil != err { logging.LogFatalf("create table [blocks_fts] failed: %s", err) } db.Exec("DROP TABLE blocks_fts_case_insensitive") - _, err = db.Exec("CREATE VIRTUAL TABLE blocks_fts_case_insensitive USING fts5(id UNINDEXED, parent_id UNINDEXED, root_id UNINDEXED, hash UNINDEXED, box UNINDEXED, path UNINDEXED, hpath, name, alias, memo, tag, content, fcontent, markdown UNINDEXED, length UNINDEXED, type UNINDEXED, subtype UNINDEXED, ial, sort UNINDEXED, created UNINDEXED, updated UNINDEXED, tokenize=\"siyuan case_insensitive\")") + _, err = db.Exec("CREATE VIRTUAL TABLE blocks_fts_case_insensitive USING fts5(id UNINDEXED, parent_id UNINDEXED, root_id UNINDEXED, hash UNINDEXED, box UNINDEXED, path UNINDEXED, hpath, name, alias, memo, tag, content, fcontent, markdown UNINDEXED, fmarkdown UNINDEXED, length UNINDEXED, type UNINDEXED, subtype UNINDEXED, ial, sort UNINDEXED, created UNINDEXED, updated UNINDEXED, tokenize=\"siyuan case_insensitive\")") if nil != err { logging.LogFatalf("create table [blocks_fts_case_insensitive] failed: %s", err) } @@ -711,18 +712,19 @@ func buildBlockFromNode(n *ast.Node, tree *parse.Tree) (block *Block, attributes memo := html.UnescapeString(n.IALAttr("memo")) tag := tagFromNode(n) - var content, fcontent, markdown, parentID string + var content, fcontent, markdown, fmarkdown, parentID string ialContent := treenode.IALStr(n) hash := treenode.NodeHash(n, tree, luteEngine) var length int if ast.NodeDocument == n.Type { content = n.IALAttr("title") fcontent = content + fmarkdown = content length = utf8.RuneCountInString(fcontent) } else if n.IsContainerBlock() { markdown, content = treenode.NodeStaticMdContent(n, luteEngine) fc := treenode.FirstLeafBlock(n) - fcontent = treenode.NodeStaticContent(fc) + fmarkdown, fcontent = treenode.NodeStaticMdContent(fc, luteEngine) parentID = n.Parent.ID // 将标题块作为父节点 if h := heading(n); nil != h { @@ -740,27 +742,28 @@ func buildBlockFromNode(n *ast.Node, tree *parse.Tree) (block *Block, attributes } block = &Block{ - ID: n.ID, - ParentID: parentID, - RootID: rootID, - Hash: hash, - Box: boxID, - Path: p, - HPath: tree.HPath, - Name: name, - Alias: alias, - Memo: memo, - Tag: tag, - Content: content, - FContent: fcontent, - Markdown: markdown, - Length: length, - Type: treenode.TypeAbbr(n.Type.String()), - SubType: treenode.SubTypeAbbr(n), - IAL: ialContent, - Sort: nSort(n), - Created: util.TimeFromID(n.ID), - Updated: n.IALAttr("updated"), + ID: n.ID, + ParentID: parentID, + RootID: rootID, + Hash: hash, + Box: boxID, + Path: p, + HPath: tree.HPath, + Name: name, + Alias: alias, + Memo: memo, + Tag: tag, + Content: content, + FContent: fcontent, + Markdown: markdown, + FMarkdown: fmarkdown, + Length: length, + Type: treenode.TypeAbbr(n.Type.String()), + SubType: treenode.SubTypeAbbr(n), + IAL: ialContent, + Sort: nSort(n), + Created: util.TimeFromID(n.ID), + Updated: n.IALAttr("updated"), } attrs := parse.IAL2Map(n.KramdownIAL) diff --git a/kernel/sql/upsert.go b/kernel/sql/upsert.go index 643ea1be4..20e6b920f 100644 --- a/kernel/sql/upsert.go +++ b/kernel/sql/upsert.go @@ -48,10 +48,10 @@ func InsertRefs(tx *sql.Tx, tree *parse.Tree) { } const ( - BlocksInsert = "INSERT INTO blocks (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, length, type, subtype, ial, sort, created, updated) VALUES %s" - BlocksFTSInsert = "INSERT INTO blocks_fts (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, length, type, subtype, ial, sort, created, updated) VALUES %s" - BlocksFTSCaseInsensitiveInsert = "INSERT INTO blocks_fts_case_insensitive (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, length, type, subtype, ial, sort, created, updated) VALUES %s" - BlocksPlaceholder = "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + BlocksInsert = "INSERT INTO blocks (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, fmarkdown, length, type, subtype, ial, sort, created, updated) VALUES %s" + BlocksFTSInsert = "INSERT INTO blocks_fts (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, fmarkdown, length, type, subtype, ial, sort, created, updated) VALUES %s" + BlocksFTSCaseInsensitiveInsert = "INSERT INTO blocks_fts_case_insensitive (id, parent_id, root_id, hash, box, path, hpath, name, alias, memo, tag, content, fcontent, markdown, fmarkdown, length, type, subtype, ial, sort, created, updated) VALUES %s" + BlocksPlaceholder = "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" SpansInsert = "INSERT INTO spans (id, block_id, root_id, box, path, content, markdown, type, ial) VALUES %s" SpansPlaceholder = "(?, ?, ?, ?, ?, ?, ?, ?, ?)" @@ -106,6 +106,7 @@ func insertBlocks0(tx *sql.Tx, bulk []*Block) (err error) { valueArgs = append(valueArgs, b.Content) valueArgs = append(valueArgs, b.FContent) valueArgs = append(valueArgs, b.Markdown) + valueArgs = append(valueArgs, b.FMarkdown) valueArgs = append(valueArgs, b.Length) valueArgs = append(valueArgs, b.Type) valueArgs = append(valueArgs, b.SubType) diff --git a/kernel/util/runtime.go b/kernel/util/runtime.go index 2b71bccfd..3618235bd 100644 --- a/kernel/util/runtime.go +++ b/kernel/util/runtime.go @@ -29,7 +29,7 @@ import ( "github.com/siyuan-note/logging" ) -const DatabaseVer = "20220501" // 修改表结构的话需要修改这里 +const DatabaseVer = "20220828" // 修改表结构的话需要修改这里 const ( ExitCodeReadOnlyDatabase = 20 // 数据库文件被锁