Skip to content

Commit ec1ed22

Browse files
authored
Adiantum encrypting VFS. (#77)
1 parent e86789b commit ec1ed22

File tree

20 files changed

+479
-21
lines changed

20 files changed

+479
-21
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ Go module `github.com/ncruces/go-sqlite3` is a `cgo`-free [SQLite](https://sqlit
88
It provides a [`database/sql`](https://pkg.go.dev/database/sql) compatible driver,
99
as well as direct access to most of the [C SQLite API](https://sqlite.org/cintro.html).
1010

11-
It wraps a [Wasm](https://webassembly.org/) build of SQLite, and uses [wazero](https://wazero.io/) as the runtime.\
12-
Go, wazero and [`x/sys`](https://pkg.go.dev/golang.org/x/sys) are the _only_ runtime dependencies.
11+
It wraps a [Wasm](https://webassembly.org/) [build](embed/) of SQLite,
12+
and uses [wazero](https://wazero.io/) as the runtime.\
13+
Go, wazero and [`x/sys`](https://pkg.go.dev/golang.org/x/sys) are the _only_ runtime dependencies [^1].
1314

1415
### Packages
1516

@@ -54,6 +55,8 @@ Go, wazero and [`x/sys`](https://pkg.go.dev/golang.org/x/sys) are the _only_ run
5455
implements an in-memory VFS.
5556
- [`github.com/ncruces/go-sqlite3/vfs/readervfs`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/readervfs)
5657
implements a VFS for immutable databases.
58+
- [`github.com/ncruces/go-sqlite3/vfs/adiantum`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/adiantum)
59+
wraps a VFS to offer encryption at rest.
5760

5861
### Advanced features
5962

@@ -101,3 +104,6 @@ The Wasm and VFS layers are also tested by running SQLite's
101104
- [`crawshaw.io/sqlite`](https://pkg.go.dev/crawshaw.io/sqlite)
102105
- [`github.com/mattn/go-sqlite3`](https://pkg.go.dev/github.com/mattn/go-sqlite3)
103106
- [`github.com/zombiezen/go-sqlite`](https://pkg.go.dev/github.com/zombiezen/go-sqlite)
107+
108+
[^1]: anything else you find in [`go.mod`](./go.mod) is either a test dependency,
109+
or needed by one of the extensions.

embed/exports.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ sqlite3_errmsg
6161
sqlite3_error_offset
6262
sqlite3_errstr
6363
sqlite3_exec
64+
sqlite3_filename_database
65+
sqlite3_filename_journal
66+
sqlite3_filename_wal
6467
sqlite3_finalize
6568
sqlite3_get_autocommit
6669
sqlite3_get_auxdata

embed/sqlite3.wasm

631 Bytes
Binary file not shown.

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ require (
1010
golang.org/x/sync v0.7.0
1111
golang.org/x/sys v0.19.0
1212
golang.org/x/text v0.14.0
13+
lukechampine.com/adiantum v1.0.0
1314
)
1415

16+
require github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
17+
1518
retract v0.4.0 // tagged from the wrong branch

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1+
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
2+
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
13
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
24
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
35
github.com/psanford/httpreadat v0.1.0 h1:VleW1HS2zO7/4c7c7zNl33fO6oYACSagjJIyMIwZLUE=
46
github.com/psanford/httpreadat v0.1.0/go.mod h1:Zg7P+TlBm3bYbyHTKv/EdtSJZn3qwbPwpfZ/I9GKCRE=
57
github.com/tetratelabs/wazero v1.7.1 h1:QtSfd6KLc41DIMpDYlJdoMc6k7QTN246DM2+n2Y/Dx8=
68
github.com/tetratelabs/wazero v1.7.1/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
9+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
10+
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
711
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
812
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
13+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
914
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
1015
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
16+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
17+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
18+
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
1119
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
1220
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
21+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
1322
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
1423
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
24+
lukechampine.com/adiantum v1.0.0 h1:xxLFgKHyno8ES1XiKLbQfU9DGiMaM2xsIJI2czgT7es=
25+
lukechampine.com/adiantum v1.0.0/go.mod h1:kjMpBiZFjVX/FeEYcN81jyt3//7J3XjJgH9OkAXV4n0=

internal/util/mmap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func (s *mmapState) init(ctx context.Context, enabled bool) context.Context {
2525
return ctx
2626
}
2727

28-
func CanMap(ctx context.Context) bool {
28+
func CanMapFiles(ctx context.Context) bool {
2929
s := ctx.Value(moduleKey{}).(*moduleState)
3030
return s.mmapState.enabled
3131
}

internal/util/mmap_other.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ func (s *mmapState) init(ctx context.Context, _ bool) context.Context {
1010
return ctx
1111
}
1212

13-
func CanMap(ctx context.Context) bool {
13+
func CanMapFiles(ctx context.Context) bool {
1414
return false
1515
}

internal/util/unwrap.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package util
2+
3+
func Unwrap[T any](v T) T {
4+
if u, ok := any(v).(interface{ Unwrap() T }); ok {
5+
return u.Unwrap()
6+
}
7+
return v
8+
}

tests/db_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/ncruces/go-sqlite3"
1111
_ "github.com/ncruces/go-sqlite3/embed"
1212
_ "github.com/ncruces/go-sqlite3/tests/testcfg"
13+
_ "github.com/ncruces/go-sqlite3/vfs/adiantum"
1314
_ "github.com/ncruces/go-sqlite3/vfs/memdb"
1415
)
1516

@@ -56,10 +57,18 @@ func TestDB_utf16(t *testing.T) {
5657
testDB(t, tmp)
5758
}
5859

59-
func TestDB_vfs(t *testing.T) {
60+
func TestDB_memdb(t *testing.T) {
61+
t.Parallel()
6062
testDB(t, "file:test.db?vfs=memdb")
6163
}
6264

65+
func TestDB_adiantum(t *testing.T) {
66+
t.Parallel()
67+
testDB(t, "file:"+
68+
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db"))+
69+
"?vfs=adiantum&textkey=correct+horse+battery+staple")
70+
}
71+
6372
func testDB(t testing.TB, name string) {
6473
db, err := sqlite3.Open(name)
6574
if err != nil {

tests/parallel/parallel_test.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ import (
1414
_ "github.com/ncruces/go-sqlite3/embed"
1515
_ "github.com/ncruces/go-sqlite3/tests/testcfg"
1616
"github.com/ncruces/go-sqlite3/vfs"
17+
_ "github.com/ncruces/go-sqlite3/vfs/adiantum"
1718
"github.com/ncruces/go-sqlite3/vfs/memdb"
1819
)
1920

20-
func TestParallel(t *testing.T) {
21+
func Test_parallel(t *testing.T) {
2122
var iter int
2223
if testing.Short() {
2324
iter = 1000
@@ -34,7 +35,7 @@ func TestParallel(t *testing.T) {
3435
testIntegrity(t, name)
3536
}
3637

37-
func TestWAL(t *testing.T) {
38+
func Test_wal(t *testing.T) {
3839
if !vfs.SupportsSharedMemory {
3940
t.Skip("skipping without shared memory")
4041
}
@@ -48,7 +49,7 @@ func TestWAL(t *testing.T) {
4849
testIntegrity(t, name)
4950
}
5051

51-
func TestMemory(t *testing.T) {
52+
func Test_memdb(t *testing.T) {
5253
var iter int
5354
if testing.Short() {
5455
iter = 1000
@@ -61,6 +62,21 @@ func TestMemory(t *testing.T) {
6162
testIntegrity(t, name)
6263
}
6364

65+
func Test_adiantum(t *testing.T) {
66+
var iter int
67+
if testing.Short() {
68+
iter = 1000
69+
} else {
70+
iter = 5000
71+
}
72+
73+
name := "file:" +
74+
filepath.ToSlash(filepath.Join(t.TempDir(), "test.db")) +
75+
"?vfs=adiantum&textkey=correct+horse+battery+staple"
76+
testParallel(t, name, iter)
77+
testIntegrity(t, name)
78+
}
79+
6480
func TestMultiProcess(t *testing.T) {
6581
if testing.Short() {
6682
t.Skip("skipping in short mode")
@@ -112,7 +128,7 @@ func TestChildProcess(t *testing.T) {
112128
testParallel(t, name, 1000)
113129
}
114130

115-
func BenchmarkMemory(b *testing.B) {
131+
func Benchmark_memdb(b *testing.B) {
116132
memdb.Delete("test.db")
117133
name := "file:/test.db?vfs=memdb"
118134
testParallel(b, name, b.N)

0 commit comments

Comments
 (0)