WAL mode serdes.

This commit is contained in:
Nuno Cruces
2025-08-02 11:48:37 +01:00
parent 789e2dc136
commit 20a67ca669
3 changed files with 36 additions and 8 deletions

View File

@@ -21,7 +21,7 @@ var fileToOpen = make(chan *[]byte, 1)
func Serialize(db *sqlite3.Conn, schema string) ([]byte, error) { func Serialize(db *sqlite3.Conn, schema string) ([]byte, error) {
var file []byte var file []byte
fileToOpen <- &file fileToOpen <- &file
err := db.Backup(schema, "file:serdes.db?vfs="+vfsName) err := db.Backup(schema, "file:serdes.db?nolock=1&vfs="+vfsName)
return file, err return file, err
} }
@@ -41,7 +41,7 @@ func Serialize(db *sqlite3.Conn, schema string) ([]byte, error) {
// ["reader"]: https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/readervfs // ["reader"]: https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/readervfs
func Deserialize(db *sqlite3.Conn, schema string, data []byte) error { func Deserialize(db *sqlite3.Conn, schema string, data []byte) error {
fileToOpen <- &data fileToOpen <- &data
return db.Restore(schema, "file:serdes.db?vfs="+vfsName) return db.Restore(schema, "file:serdes.db?immutable=1&vfs="+vfsName)
} }
type sliceVFS struct{} type sliceVFS struct{}

View File

@@ -1,6 +1,7 @@
package serdes_test package serdes_test
import ( import (
_ "embed"
"errors" "errors"
"io" "io"
"net/http" "net/http"
@@ -11,7 +12,30 @@ import (
"github.com/ncruces/go-sqlite3/ext/serdes" "github.com/ncruces/go-sqlite3/ext/serdes"
) )
func TestDeserialize(t *testing.T) { //go:embed testdata/wal.db
var walDB []byte
func Test_wal(t *testing.T) {
db, err := sqlite3.Open("testdata/wal.db")
if err != nil {
t.Fatal(err)
}
defer db.Close()
data, err := serdes.Serialize(db, "main")
if err != nil {
t.Fatal(err)
}
compareDBs(t, data, walDB)
err = serdes.Deserialize(db, "main", walDB)
if err != nil {
t.Fatal(err)
}
}
func Test_northwind(t *testing.T) {
if testing.Short() { if testing.Short() {
t.Skip("skipping in short mode") t.Skip("skipping in short mode")
} }
@@ -37,10 +61,14 @@ func TestDeserialize(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if len(input) != len(output) { compareDBs(t, input, output)
}
func compareDBs(t *testing.T, a, b []byte) {
if len(a) != len(b) {
t.Fatal("lengths are different") t.Fatal("lengths are different")
} }
for i := range input { for i := range a {
// These may be different. // These may be different.
switch { switch {
case 24 <= i && i < 28: case 24 <= i && i < 28:
@@ -53,14 +81,14 @@ func TestDeserialize(t *testing.T) {
// SQLite version that wrote the file. // SQLite version that wrote the file.
continue continue
} }
if input[i] != output[i] { if a[i] != b[i] {
t.Errorf("difference at %d: %d %d", i, input[i], output[i]) t.Errorf("difference at %d: %d %d", i, a[i], b[i])
} }
} }
} }
func httpGet() ([]byte, error) { func httpGet() ([]byte, error) {
res, err := http.Get("https://raw.githubusercontent.com/jpwhite3/northwind-SQLite3/refs/heads/main/dist/northwind.db") res, err := http.Get("https://github.com/jpwhite3/northwind-SQLite3/raw/refs/heads/main/dist/northwind.db")
if err != nil { if err != nil {
return nil, err return nil, err
} }

BIN
ext/serdes/testdata/wal.db vendored Normal file

Binary file not shown.