From 86684d665e2f2f9bb865004e8995a5c110ddcbc2 Mon Sep 17 00:00:00 2001
From: ax_rd <ax_rd@aisim.cn>
Date: Thu, 03 Sep 2026 11:56:04 +0800
Subject: [PATCH] feat: RWR 图结构排序 + CJK LIKE 混合检索 + 双信号加权 + aliases/status 参与排序

---
 internal/index/migrations.go |   33 +++++++++++++++++++++------------
 1 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/internal/index/migrations.go b/internal/index/migrations.go
index 25955b0..85dce28 100644
--- a/internal/index/migrations.go
+++ b/internal/index/migrations.go
@@ -35,7 +35,10 @@
 	return nil
 }
 
-// backupDB 迁移前备份 .db 文件(已有备份则跳过)
+// backupDB 迁移前备份 .db 文件(已有备份则跳过)。
+// 用 VACUUM INTO 而非 os.ReadFile:WAL 模式下未 checkpoint 的数据在
+// -wal 文件里,直读主文件会漏掉这部分,导致备份不一致;VACUUM INTO
+// 会合并 WAL 生成一份完整的独立库文件(SQLite 3.27+)。
 func (s *Store) backupDB() error {
 	if s.dbPath == "" {
 		return nil // 无路径信息时跳过备份(测试场景)
@@ -44,23 +47,19 @@
 	if _, err := os.Stat(dst); err == nil {
 		return nil // 已有备份
 	}
-	data, err := os.ReadFile(s.dbPath)
-	if err != nil {
-		return err
-	}
-	return os.WriteFile(dst, data, 0644)
+	_, err := s.db.Exec(`VACUUM INTO ?`, dst)
+	return err
 }
 
-// migrateV1toV2 执行 v1 → v2 的全部变更
+// migrateV1toV2 执行 v1 → v2 的全部变更。
+// 注意:版本号(schema_versions)必须在最后一步(FTS 重建)成功后才写入,
+// 否则中途失败时后续 Open 会读到 version=2 直接早退,半迁移状态无法重试。
 func (s *Store) migrateV1toV2() error {
-	// 1. schema_versions 表
+	// 1. schema_versions 表(只建表,版本号推迟到最后写入)
 	if _, err := s.db.Exec(`CREATE TABLE IF NOT EXISTS schema_versions (
 		key TEXT PRIMARY KEY, value TEXT NOT NULL)`); err != nil {
 		return err
 	}
-	if _, err := s.db.Exec(`INSERT OR REPLACE INTO schema_versions VALUES ('version', '2')`); err != nil {
-		return err
-	}
 
 	// 2. nodes 加列(逐列检查,幂等)
 	for _, col := range []struct{ name, def string }{
@@ -107,7 +106,17 @@
 	if err := s.CreateFTS(); err != nil {
 		return err
 	}
-	return s.PopulateFTS()
+	if err := s.PopulateFTS(); err != nil {
+		return err
+	}
+
+	// 6. 最后一步:全部成功后才写入版本号(参数化,引用常量 currentSchemaVersion)。
+	// 提前写入会导致中途失败时后续 Open 读到 version=2 直接早退,半迁移状态无法重试。
+	if _, err := s.db.Exec(`INSERT OR REPLACE INTO schema_versions VALUES ('version', ?)`,
+		currentSchemaVersion); err != nil {
+		return err
+	}
+	return nil
 }
 
 // nodeColumnExists 检查 nodes 表是否已有指定列

--
Gitblit v1.10.0