|
|
@@ -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)")
|
|
|
+}
|