Procházet zdrojové kódy

test(migrate): 现场复验 — 59566B TEXT→Blob 迁移 + 驱动分页查询逐字节读回

DockerManager 报'读取 BLOB 列 param: EOF'的上游对照用例: 20 行 (19×59566B
+ 1 小值) 经 migrate 落 Blob 列, LIMIT/OFFSET 翻页全读回逐字节一致。
上游链路健康, EOF 源于目标文件被多次中断迁移叠加损伤 (同 B+树 panic
现场的次生伤)。
yl32940 před 3 týdny
rodič
revize
52b36b45a8
1 změnil soubory, kde provedl 79 přidání a 0 odebrání
  1. 79 0
      migrate/blob_paging_test.go

+ 79 - 0
migrate/blob_paging_test.go

@@ -0,0 +1,79 @@
+package migrate
+
+import (
+	"database/sql"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	_ "git.ycl.pub/yl32940/TsDB2/DB/driver"
+)
+
+// 现场复验: 59566B 的 TEXT param → 迁成 Blob → 驱动分页查询读回逐字节一致。
+func TestBlobPagingRepro(t *testing.T) {
+	dir := t.TempDir()
+	srcPath := filepath.Join(dir, "src.sqlite")
+	src, err := OpenSQLite(srcPath, quiet())
+	if err != nil {
+		t.Fatal(err)
+	}
+	big := strings.Repeat("P", 59566)
+	if _, err := src.db.Exec(`CREATE TABLE "sys_logs" ("id" INTEGER PRIMARY KEY, "param" TEXT, "msg" TEXT)`); err != nil {
+		t.Fatal(err)
+	}
+	for i := 1; i <= 20; i++ {
+		p := big
+		if i == 7 {
+			p = "small"
+		}
+		if _, err := src.db.Exec(`INSERT INTO "sys_logs" (id, param, msg) VALUES (?, ?, ?)`, i, p, "m"); err != nil {
+			t.Fatal(err)
+		}
+	}
+	src.Close()
+
+	dstPath := filepath.Join(dir, "dst.db")
+	s, _ := OpenSQLite(srcPath, quiet())
+	d, _ := OpenVRTX(dstPath, quiet())
+	if _, err := Run(s, d, quiet()); err != nil {
+		t.Fatal(err)
+	}
+	d.Close()
+	s.Close()
+
+	// 分页查询形态 (LIMIT/OFFSET 翻页读完 20 行, 每页 7 行)
+	vdb, err := sql.Open("vrtx", dstPath)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer vdb.Close()
+	var got []string
+	for page := 0; page < 3; page++ {
+		rows, err := vdb.Query(`SELECT id, param FROM sys_logs ORDER BY id LIMIT 7 OFFSET ?`, page*7)
+		if err != nil {
+			t.Fatalf("分页查询: %v", err)
+		}
+		for rows.Next() {
+			var id int
+			var p []byte
+			if err := rows.Scan(&id, &p); err != nil {
+				t.Fatalf("读取 BLOB 列 param: %v", err)
+			}
+			got = append(got, string(p))
+		}
+		rows.Close()
+	}
+	if len(got) != 20 {
+		t.Fatalf("行数 %d", len(got))
+	}
+	for i, g := range got {
+		want := big
+		if i == 6 {
+			want = "small"
+		}
+		if g != want {
+			t.Fatalf("第 %d 行 param 不一致 (len=%d want %d)", i+1, len(g), len(want))
+		}
+	}
+	t.Logf("20 行分页读回全部逐字节一致 (含 59566B 大 blob ×19)")
+}