This commit is contained in:
Liang Ding 2022-08-28 09:00:01 +08:00
parent 04e7a931f3
commit 8391638731
No known key found for this signature in database
GPG key ID: 136F30F901A2231D
8 changed files with 103 additions and 96 deletions

View file

@ -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 {

View file

@ -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{}

View file

@ -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) {

View file

@ -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())
}

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -29,7 +29,7 @@ import (
"github.com/siyuan-note/logging"
)
const DatabaseVer = "20220501" // 修改表结构的话需要修改这里
const DatabaseVer = "20220828" // 修改表结构的话需要修改这里
const (
ExitCodeReadOnlyDatabase = 20 // 数据库文件被锁