Skip to content

Commit e7f8311

Browse files
committed
Fix readonly shared memory (see #94).
1 parent 35a3bfe commit e7f8311

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

tests/wal_test.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package tests
22

33
import (
4-
"os"
54
"path/filepath"
65
"testing"
76

87
"github.com/ncruces/go-sqlite3"
8+
"github.com/ncruces/go-sqlite3/driver"
99
_ "github.com/ncruces/go-sqlite3/embed"
1010
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
1111
"github.com/ncruces/go-sqlite3/vfs"
@@ -52,26 +52,55 @@ func TestWAL_readonly(t *testing.T) {
5252
}
5353
t.Parallel()
5454

55-
tmp := filepath.Join(t.TempDir(), "test.db")
56-
err := os.WriteFile(tmp, walDB, 0666)
55+
tmp := filepath.ToSlash(filepath.Join(t.TempDir(), "test.db"))
56+
57+
db1, err := driver.Open("file:"+tmp+"?_pragma=journal_mode(wal)&_txlock=immediate", nil)
5758
if err != nil {
5859
t.Fatal(err)
5960
}
61+
defer db1.Close()
6062

61-
db, err := sqlite3.OpenFlags(tmp, sqlite3.OPEN_READONLY)
63+
db2, err := driver.Open("file:"+tmp+"?_pragma=journal_mode(wal)&mode=ro", nil)
6264
if err != nil {
6365
t.Fatal(err)
6466
}
65-
defer db.Close()
67+
defer db2.Close()
68+
69+
// Create the table using the first (writable) connection.
70+
_, err = db1.Exec(`
71+
CREATE TABLE t(id INTEGER PRIMARY KEY, name TEXT);
72+
INSERT INTO t(name) VALUES('alice');
73+
`)
74+
if err != nil {
75+
t.Fatal(err)
76+
}
77+
78+
// Select the data using the second (readonly) connection.
79+
var name string
80+
err = db2.QueryRow("SELECT name FROM t").Scan(&name)
81+
if err != nil {
82+
t.Fatal(err)
83+
}
84+
if name != "alice" {
85+
t.Errorf("got %q want alice", name)
86+
}
6687

67-
stmt, _, err := db.Prepare(`SELECT * FROM sqlite_master`)
88+
// Update table.
89+
_, err = db1.Exec(`
90+
DELETE FROM t;
91+
INSERT INTO t(name) VALUES('bob');
92+
`)
6893
if err != nil {
6994
t.Fatal(err)
7095
}
71-
defer stmt.Close()
7296

73-
if stmt.Step() {
74-
t.Error("want no rows")
97+
// Select the data using the second (readonly) connection.
98+
err = db2.QueryRow("SELECT name FROM t").Scan(&name)
99+
if err != nil {
100+
t.Fatal(err)
101+
}
102+
if name != "bob" {
103+
t.Errorf("got %q want bob", name)
75104
}
76105
}
77106

vfs/shm.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, ext
125125
return 0, _IOERR_SHMMAP
126126
}
127127
s.regions = append(s.regions, r)
128+
if s.readOnly {
129+
return r.Ptr, _READONLY
130+
}
128131
return r.Ptr, _OK
129132
}
130133

vfs/shm_bsd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ func (s *vfsShm) shmMap(ctx context.Context, mod api.Module, id, size int32, ext
195195
return 0, _IOERR_SHMMAP
196196
}
197197
s.regions = append(s.regions, r)
198+
if s.readOnly {
199+
return r.Ptr, _READONLY
200+
}
198201
return r.Ptr, _OK
199202
}
200203

0 commit comments

Comments
 (0)