@@ -5,56 +5,37 @@ import (
55 "context"
66 _ "embed"
77 "encoding/binary"
8- "strconv"
98
109 "github.com/tetratelabs/wazero/api"
1110
1211 "github.com/ncruces/go-sqlite3/internal/util"
1312 "github.com/ncruces/go-sqlite3/util/sql3util"
1413)
1514
16- func cksmWrapFile (name * Filename , flags OpenFlag , file File ) File {
17- // Checksum only main databases and WALs .
18- if flags & ( OPEN_MAIN_DB | OPEN_WAL ) == 0 {
15+ func cksmWrapFile (file File , flags OpenFlag ) File {
16+ // Checksum only main databases.
17+ if flags & OPEN_MAIN_DB == 0 {
1918 return file
2019 }
21-
22- cksm := cksmFile {File : file }
23-
24- if flags & OPEN_WAL != 0 {
25- main , _ := name .DatabaseFile ().(cksmFile )
26- cksm .cksmFlags = main .cksmFlags
27- } else {
28- cksm .cksmFlags = new (cksmFlags )
29- cksm .isDB = true
30- }
31-
32- return cksm
20+ return & cksmFile {File : file }
3321}
3422
3523type cksmFile struct {
3624 File
37- * cksmFlags
38- isDB bool
39- }
40-
41- type cksmFlags struct {
42- computeCksm bool
4325 verifyCksm bool
44- inCkpt bool
45- pageSize int
26+ computeCksm bool
4627}
4728
48- func (c cksmFile ) ReadAt (p []byte , off int64 ) (n int , err error ) {
29+ func (c * cksmFile ) ReadAt (p []byte , off int64 ) (n int , err error ) {
4930 n , err = c .File .ReadAt (p , off )
5031 p = p [:n ]
5132
52- if isHeader (c . isDB , p , off ) {
33+ if isHeader (p , off ) {
5334 c .init ((* [100 ]byte )(p ))
5435 }
5536
5637 // Verify checksums.
57- if c .verifyCksm && ! c . inCkpt && len (p ) == c . pageSize {
38+ if c .verifyCksm && sql3util . ValidPageSize ( len (p )) {
5839 cksm1 := cksmCompute (p [:len (p )- 8 ])
5940 cksm2 := * (* [8 ]byte )(p [len (p )- 8 :])
6041 if cksm1 != cksm2 {
@@ -64,20 +45,20 @@ func (c cksmFile) ReadAt(p []byte, off int64) (n int, err error) {
6445 return n , err
6546}
6647
67- func (c cksmFile ) WriteAt (p []byte , off int64 ) (n int , err error ) {
68- if isHeader (c . isDB , p , off ) {
48+ func (c * cksmFile ) WriteAt (p []byte , off int64 ) (n int , err error ) {
49+ if isHeader (p , off ) {
6950 c .init ((* [100 ]byte )(p ))
7051 }
7152
7253 // Compute checksums.
73- if c .computeCksm && ! c . inCkpt && len (p ) == c . pageSize {
54+ if c .computeCksm && sql3util . ValidPageSize ( len (p )) {
7455 * (* [8 ]byte )(p [len (p )- 8 :]) = cksmCompute (p [:len (p )- 8 ])
7556 }
7657
7758 return c .File .WriteAt (p , off )
7859}
7960
80- func (c cksmFile ) Pragma (name string , value string ) (string , error ) {
61+ func (c * cksmFile ) Pragma (name string , value string ) (string , error ) {
8162 switch name {
8263 case "checksum_verification" :
8364 b , ok := sql3util .ParseBool (value )
@@ -90,29 +71,24 @@ func (c cksmFile) Pragma(name string, value string) (string, error) {
9071 return "1" , nil
9172
9273 case "page_size" :
93- if c .computeCksm {
74+ if c .computeCksm && value != "" {
9475 // Do not allow page size changes on a checksum database.
95- return strconv . Itoa ( c . pageSize ) , nil
76+ return "" , nil
9677 }
9778 }
9879 return "" , _NOTFOUND
9980}
10081
101- func (c cksmFile ) DeviceCharacteristics () DeviceCharacteristic {
82+ func (c * cksmFile ) DeviceCharacteristics () DeviceCharacteristic {
10283 ret := c .File .DeviceCharacteristics ()
10384 if c .verifyCksm {
10485 ret &^= IOCAP_SUBPAGE_READ
10586 }
10687 return ret
10788}
10889
109- func (c cksmFile ) fileControl (ctx context.Context , mod api.Module , op _FcntlOpcode , pArg ptr_t ) _ErrorCode {
110- switch op {
111- case _FCNTL_CKPT_START :
112- c .inCkpt = true
113- case _FCNTL_CKPT_DONE :
114- c .inCkpt = false
115- case _FCNTL_PRAGMA :
90+ func (c * cksmFile ) fileControl (ctx context.Context , mod api.Module , op _FcntlOpcode , pArg ptr_t ) _ErrorCode {
91+ if op == _FCNTL_PRAGMA {
11692 rc := vfsFileControlImpl (ctx , mod , c , op , pArg )
11793 if rc != _NOTFOUND {
11894 return rc
@@ -121,24 +97,26 @@ func (c cksmFile) fileControl(ctx context.Context, mod api.Module, op _FcntlOpco
12197 return vfsFileControlImpl (ctx , mod , c .File , op , pArg )
12298}
12399
124- func (f * cksmFlags ) init (header * [100 ]byte ) {
125- f .pageSize = 256 * int (binary .LittleEndian .Uint16 (header [16 :18 ]))
126- if r := header [20 ] == 8 ; r != f .computeCksm {
127- f .computeCksm = r
128- f .verifyCksm = r
129- }
130- if ! sql3util .ValidPageSize (f .pageSize ) {
131- f .computeCksm = false
132- f .verifyCksm = false
100+ func (c * cksmFile ) init (header * [100 ]byte ) {
101+ if r := header [20 ] == 8 ; r != c .computeCksm {
102+ c .computeCksm = r
103+ c .verifyCksm = r
133104 }
134105}
135106
136- func isHeader (isDB bool , p []byte , off int64 ) bool {
137- check := sql3util .ValidPageSize (len (p ))
138- if isDB {
139- check = off == 0 && len (p ) >= 100
107+ func (c * cksmFile ) SharedMemory () SharedMemory {
108+ if f , ok := c .File .(FileSharedMemory ); ok {
109+ return f .SharedMemory ()
140110 }
141- return check && bytes .HasPrefix (p , []byte ("SQLite format 3\000 " ))
111+ return nil
112+ }
113+
114+ func (c * cksmFile ) Unwrap () File {
115+ return c .File
116+ }
117+
118+ func isHeader (p []byte , off int64 ) bool {
119+ return off == 0 && len (p ) >= 100 && bytes .HasPrefix (p , []byte ("SQLite format 3\000 " ))
142120}
143121
144122func cksmCompute (a []byte ) (cksm [8 ]byte ) {
@@ -155,14 +133,3 @@ func cksmCompute(a []byte) (cksm [8]byte) {
155133 binary .LittleEndian .PutUint32 (cksm [4 :8 ], s2 )
156134 return
157135}
158-
159- func (c cksmFile ) SharedMemory () SharedMemory {
160- if f , ok := c .File .(FileSharedMemory ); ok {
161- return f .SharedMemory ()
162- }
163- return nil
164- }
165-
166- func (c cksmFile ) Unwrap () File {
167- return c .File
168- }
0 commit comments