mirror of
https://gitlab.com/cznic/sqlite.git
synced 2024-11-09 02:09:23 +00:00
153 lines
3.7 KiB
Go
153 lines
3.7 KiB
Go
// Copyright 2024 The Sqlite Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package sqlite // import "modernc.org/sqlite"
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestFcntlPersistWAL(t *testing.T) {
|
|
t.Run("WAL is cleaned up without persist WAL", func(t *testing.T) {
|
|
name := filepath.Join(t.TempDir(), "tmp.db")
|
|
walName := name + "-wal"
|
|
db, err := sql.Open(driverName, fmt.Sprintf("file:%s", name))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// enable WAL journal
|
|
if _, err := db.Exec("pragma journal_mode = WAL"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := db.Exec("create table t(b int)"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// database file must exist after creating a table
|
|
if _, err := os.Stat(name); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// wal file must exist after creating a table
|
|
if _, err := os.Stat(walName); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := db.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// database file must exist after closing it
|
|
if _, err := os.Stat(name); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// wal file must NOT exist after closing the db
|
|
if _, err := os.Stat(walName); err == nil {
|
|
t.Errorf("expected WAL file %s to not exist after closing db", walName)
|
|
} else if !errors.Is(err, os.ErrNotExist) {
|
|
t.Fatal(err)
|
|
}
|
|
})
|
|
|
|
t.Run("WAL is not cleaned up with persist WAL", func(t *testing.T) {
|
|
name := filepath.Join(t.TempDir(), "tmp.db")
|
|
walName := name + "-wal"
|
|
db, err := sql.Open(driverName, fmt.Sprintf("file:%s", name))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
conn, err := db.Conn(context.TODO())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// enable persist WAL for a connection, normally this is done with a hook
|
|
err = conn.Raw(func(driverConn any) error {
|
|
fc, ok := driverConn.(FileControl)
|
|
if !ok {
|
|
return fmt.Errorf("driver connection didn't implement FileControl")
|
|
}
|
|
|
|
// query
|
|
mode, err := fc.FileControlPersistWAL("main", -1)
|
|
if err != nil {
|
|
return fmt.Errorf("file control call failed: %w", err)
|
|
} else if mode != 0 {
|
|
return fmt.Errorf("file control call returned unexpected mode: %d", mode)
|
|
}
|
|
|
|
// enable
|
|
mode, err = fc.FileControlPersistWAL("main", 1)
|
|
if err != nil {
|
|
return fmt.Errorf("file control call failed: %w", err)
|
|
} else if mode != 1 {
|
|
return fmt.Errorf("file control call returned unexpected mode: %d", mode)
|
|
}
|
|
|
|
// verify
|
|
mode, err = fc.FileControlPersistWAL("main", -1)
|
|
if err != nil {
|
|
return fmt.Errorf("file control call failed: %w", err)
|
|
} else if mode != 1 {
|
|
return fmt.Errorf("file control call returned unexpected mode: %d", mode)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := conn.ExecContext(context.TODO(), "pragma journal_mode = WAL"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := conn.ExecContext(context.TODO(), "create table t(b int)"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// database file must exist after creating a table
|
|
if _, err := os.Stat(name); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// wal file must exist after creating a table
|
|
if _, err := os.Stat(walName); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// close connection, should persist WAL
|
|
if err := conn.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// close database, should persist WAL
|
|
if err := db.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// database file must exist after closing it
|
|
if _, err := os.Stat(name); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// wal file must exist after closing the db
|
|
if _, err := os.Stat(walName); err != nil {
|
|
t.Errorf("expected WAL file %s to exist after closing db: %s", walName, err.Error())
|
|
}
|
|
})
|
|
}
|