Simplify URI parameters.

This commit is contained in:
Nuno Cruces
2024-04-27 10:32:06 +01:00
parent 019246d1be
commit 3c21784aee
9 changed files with 52 additions and 46 deletions

View File

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

Binary file not shown.

View File

@@ -15,7 +15,7 @@ The main differences are [file locking](#file-locking) and [WAL mode](write-ahea
### File Locking
POSIX advisory locks, which SQLite uses on Unix, are
[broken by design](https://sqlite.org/src/artifact/2e8b12?ln=1073-1161).
[broken by design](https://github.com/sqlite/sqlite/blob/b74eb0/src/os_unix.c#L1073-L1161).
On Linux and macOS, this module uses
[OFD locks](https://www.gnu.org/software/libc/manual/html_node/Open-File-Description-Locks.html)

View File

@@ -103,27 +103,32 @@ func (n *Filename) URIParameter(key string) string {
}
uriKey := n.mod.ExportedFunction("sqlite3_uri_key")
uriParam := n.mod.ExportedFunction("sqlite3_uri_parameter")
n.stack[0] = uint64(n.zPath)
n.stack[1] = uint64(0)
if err := uriKey.CallWithStack(n.ctx, n.stack[:]); err != nil {
panic(err)
}
for i := 0; ; i++ {
n.stack[1] = uint64(i)
n.stack[0] = uint64(n.zPath)
if err := uriKey.CallWithStack(n.ctx, n.stack[:]); err != nil {
panic(err)
}
if n.stack[0] == 0 {
ptr := uint32(n.stack[0])
if ptr == 0 {
return ""
}
// Parse the format from:
// https://github.com/sqlite/sqlite/blob/b74eb0/src/pager.c#L4797-L4840
// This avoids having to alloc/free the key just to find a value.
for {
k := util.ReadString(n.mod, ptr, _MAX_NAME)
if k == "" {
return ""
}
if key != util.ReadString(n.mod, uint32(n.stack[0]), _MAX_NAME) {
continue
}
ptr += uint32(len(k)) + 1
n.stack[1] = n.stack[0]
n.stack[0] = uint64(n.zPath)
if err := uriParam.CallWithStack(n.ctx, n.stack[:]); err != nil {
panic(err)
v := util.ReadString(n.mod, ptr, _MAX_NAME)
if k == key {
return v
}
return util.ReadString(n.mod, uint32(n.stack[0]), _MAX_NAME)
ptr += uint32(len(v)) + 1
}
}
@@ -135,32 +140,35 @@ func (n *Filename) URIParameters() url.Values {
return nil
}
var params url.Values
uriKey := n.mod.ExportedFunction("sqlite3_uri_key")
uriParam := n.mod.ExportedFunction("sqlite3_uri_parameter")
n.stack[0] = uint64(n.zPath)
n.stack[1] = uint64(0)
if err := uriKey.CallWithStack(n.ctx, n.stack[:]); err != nil {
panic(err)
}
for i := 0; ; i++ {
n.stack[1] = uint64(i)
n.stack[0] = uint64(n.zPath)
if err := uriKey.CallWithStack(n.ctx, n.stack[:]); err != nil {
panic(err)
}
if n.stack[0] == 0 {
ptr := uint32(n.stack[0])
if ptr == 0 {
return nil
}
var params url.Values
// Parse the format from:
// https://github.com/sqlite/sqlite/blob/b74eb0/src/pager.c#L4797-L4840
// This is the only way to support multiple valued keys.
for {
k := util.ReadString(n.mod, ptr, _MAX_NAME)
if k == "" {
return params
}
key := util.ReadString(n.mod, uint32(n.stack[0]), _MAX_NAME)
if params.Has(key) {
continue
}
ptr += uint32(len(k)) + 1
n.stack[1] = n.stack[0]
n.stack[0] = uint64(n.zPath)
if err := uriParam.CallWithStack(n.ctx, n.stack[:]); err != nil {
panic(err)
}
v := util.ReadString(n.mod, ptr, _MAX_NAME)
if params == nil {
params = url.Values{}
}
params.Set(key, util.ReadString(n.mod, uint32(n.stack[0]), _MAX_NAME))
params.Add(k, v)
ptr += uint32(len(v)) + 1
}
}

View File

@@ -23,7 +23,7 @@ func (memVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, err
// This is not a problem for most SQLite file types:
// - databases, which only do page aligned reads/writes;
// - temp journals, as used by the sorter, which does the same:
// https://sqlite.org/src/artifact/237840?ln=409-412
// https://github.com/sqlite/sqlite/blob/b74eb0/src/vdbesort.c#L409-L412
//
// We refuse to open all other file types,
// but returning OPEN_MEMORY means SQLite won't ask us to.

View File

@@ -2,5 +2,4 @@ aligned_alloc
free
malloc
sqlite3_database_file_object
sqlite3_uri_key
sqlite3_uri_parameter
sqlite3_uri_key

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3fc3e666b2bb3e0e27622d43ab35f802111c59155c592a7c822f09d1229e8700
size 470668
oid sha256:1de925ac1b2a15c0e0ac4231a507d31bdf1ea576f0d768f5f4bf5c3436a1eece
size 470117

View File

@@ -2,5 +2,4 @@ aligned_alloc
free
malloc
sqlite3_database_file_object
sqlite3_uri_key
sqlite3_uri_parameter
sqlite3_uri_key

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4573183e549df979c07040d92c3b2de72b5dd49ad0d8e779de63ed95fba4e898
size 484084
oid sha256:262f1702de606413a92fbb9d7d58b812140d072cacabe79556d5fa38e00461d0
size 483792