From 1fbedab173ca3c57bbc0ed68193be8a7f44e566d Mon Sep 17 00:00:00 2001 From: mattn Date: Tue, 17 Nov 2020 01:54:21 +0900 Subject: [PATCH] Support vfs for Open (#877) Closes #876 --- sqlite3.go | 12 +++++++++++- sqlite3_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/sqlite3.go b/sqlite3.go index 63e1c4f..8cdceac 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -1041,6 +1041,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { secureDelete := "DEFAULT" synchronousMode := "NORMAL" writableSchema := -1 + vfsName := "" pos := strings.IndexRune(dsn, '?') if pos >= 1 { @@ -1364,6 +1365,10 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { } } + if val := params.Get("vfs"); val != "" { + vfsName = val + } + if !strings.HasPrefix(dsn, "file:") { dsn = dsn[:pos] } @@ -1372,9 +1377,14 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) + var vfs *C.char + if vfsName != "" { + vfs = C.CString(vfsName) + defer C.free(unsafe.Pointer(vfs)) + } rv := C._sqlite3_open_v2(name, &db, mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE, - nil) + vfs) if rv != 0 { // Save off the error _before_ closing the database. // This is safe even if db is nil. diff --git a/sqlite3_test.go b/sqlite3_test.go index d5b0cea..878ec49 100644 --- a/sqlite3_test.go +++ b/sqlite3_test.go @@ -19,6 +19,7 @@ import ( "os" "reflect" "regexp" + "runtime" "strconv" "strings" "sync" @@ -101,6 +102,43 @@ func TestOpen(t *testing.T) { } } +func TestOpenWithVFS(t *testing.T) { + filename := t.Name() + ".sqlite" + + if err := os.Remove(filename); err != nil && !os.IsNotExist(err) { + t.Fatal(err) + } + defer os.Remove(filename) + + db, err := sql.Open("sqlite3", fmt.Sprintf("file:%s?vfs=hello", filename)) + if err != nil { + t.Fatal("Failed to open", err) + } + err = db.Ping() + if err == nil { + t.Fatal("Failed to open", err) + } + db.Close() + + defer os.Remove(filename) + + var vfs string + if runtime.GOOS == "windows" { + vfs = "win32-none" + } else { + vfs = "unix-none" + } + db, err = sql.Open("sqlite3", fmt.Sprintf("file:%s?vfs=%s", filename, vfs)) + if err != nil { + t.Fatal("Failed to open", err) + } + err = db.Ping() + if err != nil { + t.Fatal("Failed to ping", err) + } + db.Close() +} + func TestOpenNoCreate(t *testing.T) { filename := t.Name() + ".sqlite"