diff --git a/kernel/model/history.go b/kernel/model/history.go index b5f415f76..265ed4fc0 100644 --- a/kernel/model/history.go +++ b/kernel/model/history.go @@ -91,6 +91,8 @@ func ClearWorkspaceHistory() (err error) { logging.LogInfof("removed workspace history dir [%s]", historyDir) } + sql.InitHistoryDatabase(true) + // 以下部分是老版本的清理逻辑,暂时保留 notebooks, err := ListNotebooks() @@ -534,6 +536,26 @@ func clearOutdatedHistoryDir(historyDir string) { continue } //logging.LogInfof("auto removed history dir [%s]", dir) + + // 清理历史库 + + tx, txErr := sql.BeginHistoryTx() + if nil != txErr { + logging.LogErrorf("begin history tx failed: %s", txErr) + return + } + + p := strings.TrimPrefix(dir, util.HistoryDir) + p = filepath.ToSlash(p[1:]) + if txErr = sql.DeleteHistoriesByPathPrefix(tx, dir); nil != txErr { + sql.RollbackTx(tx) + logging.LogErrorf("delete history [%s] failed: %s", dir, txErr) + return + } + if txErr = sql.CommitTx(tx); nil != txErr { + logging.LogErrorf("commit history tx failed: %s", txErr) + return + } } } @@ -614,7 +636,7 @@ func indexHistory() { filepath.Walk(entryPath, func(path string, info os.FileInfo, err error) error { if strings.HasSuffix(info.Name(), ".sy") { docs = append(docs, path) - } else if strings.Contains(path, "assets"+string(os.PathSeparator)) { + } else if strings.Contains(path, "assets/") { assets = append(assets, path) } return nil @@ -623,29 +645,33 @@ func indexHistory() { var histories []*sql.History for _, doc := range docs { tree, loadErr := loadTree(doc, lutEngine) - if nil != err { + if nil != loadErr { logging.LogErrorf("load tree [%s] failed: %s", doc, loadErr) continue } title := tree.Root.IALAttr("title") content := tree.Root.Content() + p := strings.TrimPrefix(doc, util.HistoryDir) + p = filepath.ToSlash(p[1:]) histories = append(histories, &sql.History{ Type: 0, Op: op, Title: title, Content: content, - Path: doc, + Path: p, Created: created, }) } for _, asset := range assets { + p := strings.TrimPrefix(asset, util.HistoryDir) + p = filepath.ToSlash(p[1:]) histories = append(histories, &sql.History{ Type: 1, Op: op, Title: filepath.Base(asset), - Path: asset, + Path: p, Created: created, }) } @@ -660,5 +686,9 @@ func indexHistory() { sql.RollbackTx(tx) return } + if err = sql.CommitTx(tx); nil != err { + logging.LogErrorf("commit transaction failed: %s", err) + return + } } } diff --git a/kernel/sql/database.go b/kernel/sql/database.go index 5d792c3f6..0439e0e72 100644 --- a/kernel/sql/database.go +++ b/kernel/sql/database.go @@ -147,13 +147,27 @@ func initDBTables() { } func InitHistoryDatabase(forceRebuild bool) { + initHistoryDBConnection() + if !forceRebuild && gulu.File.IsExist(util.HistoryDBPath) { return } + historyDB.Close() + if err := os.RemoveAll(util.HistoryDBPath); nil != err { + logging.LogErrorf("remove history database file [%s] failed: %s", util.HistoryDBPath, err) + return + } + + initHistoryDBConnection() + initHistoryDBTables() +} + +func initHistoryDBConnection() { if nil != historyDB { historyDB.Close() } + dsn := util.HistoryDBPath + "?_journal_mode=OFF" + "&_synchronous=OFF" + "&_secure_delete=OFF" + @@ -172,9 +186,11 @@ func InitHistoryDatabase(forceRebuild bool) { historyDB.SetMaxIdleConns(1) historyDB.SetMaxOpenConns(1) historyDB.SetConnMaxLifetime(365 * 24 * time.Hour) +} +func initHistoryDBTables() { historyDB.Exec("DROP TABLE histories_fts_case_insensitive") - _, err = historyDB.Exec("CREATE VIRTUAL TABLE histories_fts_case_insensitive USING fts5(type UNINDEXED, op UNINDEXED, title, content, path UNINDEXED, created UNINDEXED, tokenize=\"siyuan case_insensitive\")") + _, err := historyDB.Exec("CREATE VIRTUAL TABLE histories_fts_case_insensitive USING fts5(type UNINDEXED, op UNINDEXED, title, content, path UNINDEXED, created UNINDEXED, tokenize=\"siyuan case_insensitive\")") if nil != err { logging.LogFatalf("create table [histories_fts_case_insensitive] failed: %s", err) } diff --git a/kernel/sql/history.go b/kernel/sql/history.go index ec2f6a99c..a8388d2a6 100644 --- a/kernel/sql/history.go +++ b/kernel/sql/history.go @@ -31,6 +31,14 @@ type History struct { Path string } +func DeleteHistoriesByPathPrefix(tx *sql.Tx, pathPrefix string) (err error) { + stmt := "DELETE FROM histories_fts_case_insensitive WHERE path LIKE ?" + if err = execStmtTx(tx, stmt, pathPrefix+"%"); nil != err { + return + } + return +} + const ( HistoriesFTSCaseInsensitiveInsert = "INSERT INTO histories_fts_case_insensitive (type, op, title, content, path, created) VALUES %s" HistoriesPlaceholder = "(?, ?, ?, ?, ?, ?)"