Compare commits

...

17 Commits

Author SHA1 Message Date
Nuno Cruces
12034c4f0b Retract. 2025-02-24 14:09:55 +00:00
Nuno Cruces
b4e5d1a213 Issue #230. 2025-02-24 13:13:25 +00:00
Nuno Cruces
b06c7dda6c Checksum robustness. 2025-02-24 13:13:25 +00:00
Nuno Cruces
5e1909a20e Issue #230. 2025-02-24 13:13:25 +00:00
Nuno Cruces
77d74baca5 Fix potential leak. 2025-02-22 12:48:41 +00:00
Nuno Cruces
4142680d5a Updated modules. 2025-02-20 13:36:02 +00:00
Nuno Cruces
9f4fe6f27c SQLite 3.49.1. 2025-02-18 18:03:20 +00:00
Nuno Cruces
7870ce0690 wazero v1.9.0. 2025-02-18 16:36:22 +00:00
Nuno Cruces
ec3226e16e Fix CI. 2025-02-17 12:21:53 +00:00
Nuno Cruces
4dd7bd0ff2 More type safe. 2025-02-17 12:00:55 +00:00
Nuno Cruces
975feb2fd4 Issue #228. 2025-02-16 18:09:42 +00:00
Nuno Cruces
58f8c2d33e Ignore. 2025-02-15 01:12:38 +00:00
Nuno Cruces
019660eed6 Fix warning. 2025-02-12 09:58:58 +00:00
Nuno Cruces
30c1bcdbe9 Serdes robustness. 2025-02-12 00:41:16 +00:00
Nuno Cruces
9b4002f5ac Add missing consts. 2025-02-11 18:24:05 +00:00
Nuno Cruces
2a78d4bc2b Updated modules. 2025-02-11 18:15:14 +00:00
Nuno Cruces
c09623a903 binaryen-version_122. 2025-02-11 18:07:30 +00:00
43 changed files with 270 additions and 202 deletions

View File

@@ -1,11 +1,6 @@
name: VM Actions matrix
description: VM Actions matrix template
inputs:
run:
description: The CI command to run
required: true
runs:
using: composite
steps:
@@ -13,4 +8,4 @@ runs:
with:
usesh: true
copyback: false
run: ${{inputs.run}}
run: . ./test.sh

View File

@@ -3,13 +3,13 @@ set -euo pipefail
if [[ "$OSTYPE" == "linux"* ]]; then
WASI_SDK="https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-linux.tar.gz"
BINARYEN="https://github.com/WebAssembly/binaryen/releases/download/version_121/binaryen-version_121-x86_64-linux.tar.gz"
BINARYEN="https://github.com/WebAssembly/binaryen/releases/download/version_122/binaryen-version_122-x86_64-linux.tar.gz"
elif [[ "$OSTYPE" == "darwin"* ]]; then
WASI_SDK="https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-arm64-macos.tar.gz"
BINARYEN="https://github.com/WebAssembly/binaryen/releases/download/version_121/binaryen-version_121-arm64-macos.tar.gz"
BINARYEN="https://github.com/WebAssembly/binaryen/releases/download/version_122/binaryen-version_122-arm64-macos.tar.gz"
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then
WASI_SDK="https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/wasi-sdk-25.0-x86_64-windows.tar.gz"
BINARYEN="https://github.com/WebAssembly/binaryen/releases/download/version_121/binaryen-version_121-x86_64-windows.tar.gz"
BINARYEN="https://github.com/WebAssembly/binaryen/releases/download/version_122/binaryen-version_122-x86_64-windows.tar.gz"
fi
# Download tools

View File

@@ -7,12 +7,14 @@ on:
- '**.go'
- '**.mod'
- '**.wasm'
- '**.yml'
pull_request:
branches: [ 'main' ]
paths:
- '**.go'
- '**.mod'
- '**.wasm'
- '**.yml'
workflow_dispatch:
jobs:
@@ -70,7 +72,9 @@ jobs:
if: matrix.os != 'windows-latest'
- name: Collect coverage
run: go run github.com/dave/courtney@latest
run: |
go get -tool github.com/dave/courtney@v0.4.4
go tool courtney
if: |
github.event_name == 'push' &&
matrix.os == 'ubuntu-latest'
@@ -158,10 +162,6 @@ jobs:
- name: Test
uses: ./.github/actions/vmactions
with:
usesh: true
copyback: false
run: . ./test.sh
test-wasip1:
runs-on: ubuntu-latest
@@ -174,7 +174,7 @@ jobs:
with: { go-version: stable }
- name: Set path
run: echo "$(go env GOROOT)/misc/wasm" >> "$GITHUB_PATH"
run: echo "$(go env GOROOT)/lib/wasm" >> "$GITHUB_PATH"
- name: Test wasmtime
env:

12
.gitignore vendored
View File

@@ -5,9 +5,6 @@
*.so
*.dylib
# Go workspace
go.work*
# Test binary, built with `go test -c`
*.test
@@ -16,4 +13,11 @@ go.work*
# Dependency directories (remove the comment below to include it)
# vendor/
tools
tools
# Go workspace file
go.work
go.work.sum
# env file
.env

View File

@@ -45,7 +45,7 @@ func (c *Conn) Config(op DBConfig, arg ...bool) (bool, error) {
rc := res_t(c.call("sqlite3_db_config", stk_t(c.handle),
stk_t(op), stk_t(argsPtr)))
return util.Read32[uint32](c.mod, argsPtr) != 0, c.error(rc)
return util.ReadBool(c.mod, argsPtr), c.error(rc)
}
// ConfigLog sets up the error logging callback for the connection.
@@ -116,7 +116,7 @@ func (c *Conn) FileControl(schema string, op FcntlOpcode, arg ...any) (any, erro
rc = res_t(c.call("sqlite3_file_control",
stk_t(c.handle), stk_t(schemaPtr),
stk_t(op), stk_t(ptr)))
ret = util.Read32[uint32](c.mod, ptr) != 0
ret = util.ReadBool(c.mod, ptr)
case FCNTL_CHUNK_SIZE:
util.Write32(c.mod, ptr, int32(arg[0].(int)))

View File

@@ -492,9 +492,9 @@ func (c *Conn) TableColumnMetadata(schema, table, column string) (declType, coll
if ptr := util.Read32[ptr_t](c.mod, collSeqPtr); ptr != 0 {
collSeq = util.ReadString(c.mod, ptr, _MAX_NAME)
}
notNull = util.Read32[uint32](c.mod, notNullPtr) != 0
autoInc = util.Read32[uint32](c.mod, autoIncPtr) != 0
primaryKey = util.Read32[uint32](c.mod, primaryKeyPtr) != 0
notNull = util.ReadBool(c.mod, notNullPtr)
autoInc = util.ReadBool(c.mod, autoIncPtr)
primaryKey = util.ReadBool(c.mod, primaryKeyPtr)
}
return
}

View File

@@ -259,7 +259,10 @@ const (
DBCONFIG_TRUSTED_SCHEMA DBConfig = 1017
DBCONFIG_STMT_SCANSTATUS DBConfig = 1018
DBCONFIG_REVERSE_SCANORDER DBConfig = 1019
// DBCONFIG_MAX DBConfig = 1019
DBCONFIG_ENABLE_ATTACH_CREATE DBConfig = 1020
DBCONFIG_ENABLE_ATTACH_WRITE DBConfig = 1021
DBCONFIG_ENABLE_COMMENTS DBConfig = 1022
// DBCONFIG_MAX DBConfig = 1022
)
// FcntlOpcode are the available opcodes for [Conn.FileControl].

View File

@@ -1,6 +1,6 @@
# Embeddable Wasm build of SQLite
This folder includes an embeddable Wasm build of SQLite 3.49.0 for use with
This folder includes an embeddable Wasm build of SQLite 3.49.1 for use with
[`github.com/ncruces/go-sqlite3`](https://pkg.go.dev/github.com/ncruces/go-sqlite3).
The following optional features are compiled in:

Binary file not shown.

View File

@@ -53,7 +53,7 @@ func Test_bcw2(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if version != "3.49.0" {
if version != "3.50.0" {
t.Error(version)
}
}

View File

@@ -13,8 +13,8 @@ mkdir -p build/ext/
cp "$ROOT"/sqlite3/*.[ch] build/
cp "$ROOT"/sqlite3/*.patch build/
# https://sqlite.org/src/info/cc3ce784b0feea2f
curl -# https://sqlite.org/src/tarball/sqlite.tar.gz?r=cc3ce784 | tar xz
# https://sqlite.org/src/info/c09656c62155a6e8
curl -# https://sqlite.org/src/tarball/sqlite.tar.gz?r=c09656c6 | tar xz
cd sqlite
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" ]]; then

View File

@@ -1,14 +1,14 @@
module github.com/ncruces/go-sqlite3/embed/bcw2
go 1.22
go 1.22.0
toolchain go1.23.0
toolchain go1.24.0
require github.com/ncruces/go-sqlite3 v0.22.0
require github.com/ncruces/go-sqlite3 v0.23.1
require (
github.com/ncruces/julianday v1.0.0 // indirect
github.com/ncruces/sort v0.1.2 // indirect
github.com/tetratelabs/wazero v1.8.2 // indirect
github.com/ncruces/sort v0.1.5 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
golang.org/x/sys v0.30.0 // indirect
)

View File

@@ -1,12 +1,12 @@
github.com/ncruces/go-sqlite3 v0.22.0 h1:FkGSBhd0TY6e66k1LVhyEpA+RnG/8QkQNed5pjIk4cs=
github.com/ncruces/go-sqlite3 v0.22.0/go.mod h1:ueXOZXYZS2OFQirCU3mHneDwJm5fGKHrtccYBeGEV7M=
github.com/ncruces/go-sqlite3 v0.23.1 h1:zGAd76q+Tr18z/xKGatUlzBQdjR3J+rexfANUcjAgkY=
github.com/ncruces/go-sqlite3 v0.23.1/go.mod h1:Xg3FyAZl25HcBSFmcbymdfoTqD7jRnBUmv1jSrbIjdE=
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
github.com/ncruces/sort v0.1.2 h1:zKQ9CA4fpHPF6xsUhRTfi5EEryspuBpe/QA4VWQOV1U=
github.com/ncruces/sort v0.1.2/go.mod h1:vEJUTBJtebIuCMmXD18GKo5GJGhsay+xZFOoBEIXFmE=
github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/ncruces/sort v0.1.5 h1:fiFWXXAqKI8QckPf/6hu/bGFwcEPrirIOFaJqWujs4k=
github.com/ncruces/sort v0.1.5/go.mod h1:obJToO4rYr6VWP0Uw5FYymgYGt3Br4RXcs/JdKaXAPk=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=

View File

@@ -19,7 +19,7 @@ func Test_init(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if version != "3.49.0" {
if version != "3.49.1" {
t.Error(version)
}
}

Binary file not shown.

View File

@@ -36,4 +36,13 @@ you can load into your database connections.
- [`github.com/ncruces/go-sqlite3/ext/uuid`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/uuid)
generates [UUIDs](https://en.wikipedia.org/wiki/Universally_unique_identifier).
- [`github.com/ncruces/go-sqlite3/ext/zorder`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/zorder)
maps multidimensional data to one dimension.
maps multidimensional data to one dimension.
### Pakages
These packages may also be useful to work with SQLite:
- [`github.com/ncruces/decimal`](https://pkg.go.dev/github.com/ncruces/decimal)
decimal arithmetic.
- [`github.com/ncruces/julianday`](https://pkg.go.dev/github.com/ncruces/julianday)
Julian day math.

View File

@@ -8,17 +8,21 @@ import (
"github.com/ncruces/go-sqlite3/vfs"
)
const vfsName = "github.com/ncruces/go-sqlite3/ext/serdes.sliceVFS"
func init() {
vfs.Register(vfsName, sliceVFS{})
}
var fileToOpen = make(chan *sliceFile, 1)
// Serialize backs up a database into a byte slice.
//
// https://sqlite.org/c3ref/serialize.html
func Serialize(db *sqlite3.Conn, schema string) ([]byte, error) {
var file sliceFile
fileToOpen <- &file
err := db.Backup(schema, "file:db?vfs="+vfsName)
err := db.Backup(schema, "file:serdes.db?vfs="+vfsName)
return file.data, err
}
@@ -38,21 +42,21 @@ func Serialize(db *sqlite3.Conn, schema string) ([]byte, error) {
// ["reader"]: https://pkg.go.dev/github.com/ncruces/go-sqlite3/vfs/readervfs
func Deserialize(db *sqlite3.Conn, schema string, data []byte) error {
fileToOpen <- &sliceFile{data}
return db.Restore(schema, "file:db?vfs="+vfsName)
return db.Restore(schema, "file:serdes.db?vfs="+vfsName)
}
var fileToOpen = make(chan *sliceFile, 1)
const vfsName = "github.com/ncruces/go-sqlite3/ext/deserialize.sliceVFS"
type sliceVFS struct{}
func (sliceVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, error) {
if flags&vfs.OPEN_MAIN_DB == 0 {
// notest // OPEN_MEMORY
if flags&vfs.OPEN_MAIN_DB == 0 || name != "serdes.db" {
return nil, flags, sqlite3.CANTOPEN
}
return <-fileToOpen, flags | vfs.OPEN_MEMORY, nil
select {
case file := <-fileToOpen:
return file, flags | vfs.OPEN_MEMORY, nil
default:
return nil, flags, sqlite3.MISUSE
}
}
func (sliceVFS) Delete(name string, dirSync bool) error {
@@ -61,7 +65,7 @@ func (sliceVFS) Delete(name string, dirSync bool) error {
}
func (sliceVFS) Access(name string, flag vfs.AccessFlag) (bool, error) {
return name == "db", nil
return name == "serdes.db", nil
}
func (sliceVFS) FullPathname(name string) (string, error) {

View File

@@ -1,6 +1,7 @@
package serdes_test
import (
"errors"
"io"
"net/http"
"testing"
@@ -66,3 +67,21 @@ func httpGet() ([]byte, error) {
defer res.Body.Close()
return io.ReadAll(res.Body)
}
func TestOpen_errors(t *testing.T) {
_, err := sqlite3.Open("file:test.db?vfs=github.com/ncruces/go-sqlite3/ext/serdes.sliceVFS")
if err == nil {
t.Error("want error")
}
if !errors.Is(err, sqlite3.CANTOPEN) {
t.Errorf("got %v, want sqlite3.CANTOPEN", err)
}
_, err = sqlite3.Open("file:serdes.db?vfs=github.com/ncruces/go-sqlite3/ext/serdes.sliceVFS")
if err == nil {
t.Error("want error")
}
if !errors.Is(err, sqlite3.MISUSE) {
t.Errorf("got %v, want sqlite3.MISUSE", err)
}
}

25
func.go
View File

@@ -2,6 +2,7 @@ package sqlite3
import (
"context"
"io"
"sync"
"github.com/tetratelabs/wazero/api"
@@ -85,12 +86,18 @@ func (c *Conn) CreateWindowFunction(name string, nArg int, flag FunctionFlag, fn
var funcPtr ptr_t
defer c.arena.mark()()
namePtr := c.arena.string(name)
if fn != nil {
funcPtr = util.AddHandle(c.ctx, fn)
}
call := "sqlite3_create_aggregate_function_go"
if _, ok := fn().(WindowFunction); ok {
call = "sqlite3_create_window_function_go"
if fn != nil {
agg := fn()
if c, ok := agg.(io.Closer); ok {
if err := c.Close(); err != nil {
return err
}
}
if _, ok := agg.(WindowFunction); ok {
call = "sqlite3_create_window_function_go"
}
funcPtr = util.AddHandle(c.ctx, fn)
}
rc := res_t(c.call(call,
stk_t(c.handle), stk_t(namePtr), stk_t(nArg),
@@ -172,7 +179,13 @@ func finalCallback(ctx context.Context, mod api.Module, pCtx, pAgg, pApp ptr_t)
db := ctx.Value(connKey{}).(*Conn)
fn, handle := callbackAggregate(db, pAgg, pApp)
fn.Value(Context{db, pCtx})
if err := util.DelHandle(ctx, handle); err != nil {
var err error
if handle != 0 {
err = util.DelHandle(ctx, handle)
} else if c, ok := fn.(io.Closer); ok {
err = c.Close()
}
if err != nil {
Context{db, pCtx}.ResultError(err)
return // notest
}

11
go.mod
View File

@@ -1,13 +1,13 @@
module github.com/ncruces/go-sqlite3
go 1.22
go 1.22.0
toolchain go1.23.0
toolchain go1.24.0
require (
github.com/ncruces/julianday v1.0.0
github.com/ncruces/sort v0.1.5
github.com/tetratelabs/wazero v1.8.2
github.com/tetratelabs/wazero v1.9.0
golang.org/x/crypto v0.33.0
golang.org/x/sys v0.30.0
)
@@ -21,4 +21,7 @@ require (
lukechampine.com/adiantum v1.1.1 // vfs/adiantum
)
retract v0.4.0 // tagged from the wrong branch
retract (
v0.23.2 // tagged from the wrong branch
v0.4.0 // tagged from the wrong branch
)

4
go.sum
View File

@@ -8,8 +8,8 @@ github.com/ncruces/sort v0.1.5 h1:fiFWXXAqKI8QckPf/6hu/bGFwcEPrirIOFaJqWujs4k=
github.com/ncruces/sort v0.1.5/go.mod h1:obJToO4rYr6VWP0Uw5FYymgYGt3Br4RXcs/JdKaXAPk=
github.com/psanford/httpreadat v0.1.0 h1:VleW1HS2zO7/4c7c7zNl33fO6oYACSagjJIyMIwZLUE=
github.com/psanford/httpreadat v0.1.0/go.mod h1:Zg7P+TlBm3bYbyHTKv/EdtSJZn3qwbPwpfZ/I9GKCRE=
github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=

View File

@@ -1,11 +1,11 @@
module github.com/ncruces/go-sqlite3/gormlite
go 1.22
go 1.22.0
toolchain go1.23.0
toolchain go1.24.0
require (
github.com/ncruces/go-sqlite3 v0.22.0
github.com/ncruces/go-sqlite3 v0.23.1
gorm.io/gorm v1.25.12
)
@@ -13,7 +13,7 @@ require (
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/ncruces/julianday v1.0.0 // indirect
github.com/tetratelabs/wazero v1.8.2 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
)

View File

@@ -2,12 +2,12 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/ncruces/go-sqlite3 v0.22.0 h1:FkGSBhd0TY6e66k1LVhyEpA+RnG/8QkQNed5pjIk4cs=
github.com/ncruces/go-sqlite3 v0.22.0/go.mod h1:ueXOZXYZS2OFQirCU3mHneDwJm5fGKHrtccYBeGEV7M=
github.com/ncruces/go-sqlite3 v0.23.1 h1:zGAd76q+Tr18z/xKGatUlzBQdjR3J+rexfANUcjAgkY=
github.com/ncruces/go-sqlite3 v0.23.1/go.mod h1:Xg3FyAZl25HcBSFmcbymdfoTqD7jRnBUmv1jSrbIjdE=
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=

View File

@@ -7,18 +7,12 @@ import (
"github.com/tetratelabs/wazero"
"github.com/ncruces/go-sqlite3"
"github.com/ncruces/go-sqlite3/internal/util"
)
// notest
func init() {
if util.CompilerSupported() {
sqlite3.RuntimeConfig = wazero.NewRuntimeConfigCompiler()
} else {
sqlite3.RuntimeConfig = wazero.NewRuntimeConfigInterpreter()
}
sqlite3.RuntimeConfig = sqlite3.RuntimeConfig.WithMemoryLimitPages(512)
sqlite3.RuntimeConfig = wazero.NewRuntimeConfig().WithMemoryLimitPages(512)
if os.Getenv("CI") != "" {
path := filepath.Join(os.TempDir(), "wazero")
if err := os.MkdirAll(path, 0777); err == nil {

View File

@@ -1,27 +0,0 @@
package util
import (
"runtime"
"golang.org/x/sys/cpu"
)
func CompilerSupported() bool {
switch runtime.GOOS {
case "linux", "android",
"windows", "darwin",
"freebsd", "netbsd", "dragonfly",
"solaris", "illumos":
break
default:
return false
}
switch runtime.GOARCH {
case "amd64":
return cpu.X86.HasSSE41
case "arm64":
return true
default:
return false
}
}

View File

@@ -26,9 +26,6 @@ func View(mod api.Module, ptr Ptr_t, size int64) []byte {
if ptr == 0 {
panic(NilErr)
}
if size == 0 {
return nil
}
if uint64(size) > math.MaxUint32 {
panic(RangeErr)
}
@@ -110,6 +107,18 @@ func WriteFloat64(mod api.Module, ptr Ptr_t, v float64) {
Write64(mod, ptr, math.Float64bits(v))
}
func ReadBool(mod api.Module, ptr Ptr_t) bool {
return Read32[int32](mod, ptr) != 0
}
func WriteBool(mod api.Module, ptr Ptr_t, v bool) {
var i int32
if v {
i = 1
}
Write32(mod, ptr, i)
}
func ReadString(mod api.Module, ptr Ptr_t, maxlen int64) string {
if ptr == 0 {
panic(NilErr)

View File

@@ -47,11 +47,7 @@ func compileSQLite() {
ctx := context.Background()
cfg := RuntimeConfig
if cfg == nil {
if util.CompilerSupported() {
cfg = wazero.NewRuntimeConfigCompiler()
} else {
cfg = wazero.NewRuntimeConfigInterpreter()
}
cfg = wazero.NewRuntimeConfig()
if bits.UintSize < 64 {
cfg = cfg.WithMemoryLimitPages(512) // 32MB
} else {

View File

@@ -2,7 +2,7 @@
# handle, and interrupt, sqlite3_busy_timeout.
--- sqlite3.c.orig
+++ sqlite3.c
@@ -183054,7 +183054,7 @@
@@ -183355,7 +183355,7 @@
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
if( ms>0 ){

View File

@@ -3,7 +3,7 @@ set -euo pipefail
cd -P -- "$(dirname -- "$0")"
curl -#OL "https://sqlite.org/2025/sqlite-amalgamation-3490000.zip"
curl -#OL "https://sqlite.org/2025/sqlite-amalgamation-3490100.zip"
unzip -d . sqlite-amalgamation-*.zip
mv sqlite-amalgamation-*/sqlite3.c .
mv sqlite-amalgamation-*/sqlite3.h .
@@ -19,30 +19,30 @@ rm -rf sqlite-amalgamation-*
mkdir -p ext/
cd ext/
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/anycollseq.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/base64.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/decimal.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/ieee754.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/regexp.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/series.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/spellfix.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/ext/misc/uint.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/anycollseq.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/base64.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/decimal.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/ieee754.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/regexp.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/series.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/spellfix.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/ext/misc/uint.c"
cd ~-
cd ../vfs/tests/mptest/testdata/
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/mptest/config01.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/mptest/config02.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/mptest/crash01.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/mptest/crash02.subtest"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/mptest/multiwrite01.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/mptest/config01.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/mptest/config02.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/mptest/crash01.test"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/mptest/crash02.subtest"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/mptest/multiwrite01.test"
cd ~-
cd ../vfs/tests/mptest/wasm/
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/mptest/mptest.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/mptest/mptest.c"
cd ~-
cd ../vfs/tests/speedtest1/wasm/
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.0/test/speedtest1.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.49.1/test/speedtest1.c"
cd ~-
cat *.patch | patch -p0 --no-backup-if-mismatch

View File

@@ -1,7 +1,7 @@
# Remove VFS registration. Go handles it.
--- sqlite3.c.orig
+++ sqlite3.c
@@ -26623,7 +26623,7 @@
@@ -26725,7 +26725,7 @@
sqlite3_free(p);
return sqlite3_os_init();
}
@@ -10,7 +10,7 @@
/*
** The list of all registered VFS implementations.
*/
@@ -26720,7 +26720,7 @@
@@ -26822,7 +26822,7 @@
sqlite3_mutex_leave(mutex);
return SQLITE_OK;
}

View File

@@ -130,10 +130,6 @@ func Test_sqlite_newBytes(t *testing.T) {
if ptr == 0 {
t.Fatal("got nullptr, want a pointer")
}
if got := util.View(sqlite.mod, ptr, 0); got != nil {
t.Errorf("got %q, want nil", got)
}
}
func Test_sqlite_newString(t *testing.T) {

View File

@@ -47,11 +47,12 @@ type cksmFlags struct {
func (c cksmFile) ReadAt(p []byte, off int64) (n int, err error) {
n, err = c.File.ReadAt(p, off)
p = p[:n]
// SQLite is reading the header of a database file.
if c.isDB && off == 0 && len(p) >= 100 &&
bytes.HasPrefix(p, []byte("SQLite format 3\000")) {
c.init(p)
c.init((*[100]byte)(p))
}
// Verify checksums.
@@ -69,7 +70,7 @@ func (c cksmFile) WriteAt(p []byte, off int64) (n int, err error) {
// SQLite is writing the first page of a database file.
if c.isDB && off == 0 && len(p) >= 100 &&
bytes.HasPrefix(p, []byte("SQLite format 3\000")) {
c.init(p)
c.init((*[100]byte)(p))
}
// Compute checksums.
@@ -122,12 +123,16 @@ func (c cksmFile) fileControl(ctx context.Context, mod api.Module, op _FcntlOpco
return vfsFileControlImpl(ctx, mod, c.File, op, pArg)
}
func (f *cksmFlags) init(header []byte) {
func (f *cksmFlags) init(header *[100]byte) {
f.pageSize = 256 * int(binary.LittleEndian.Uint16(header[16:18]))
if r := header[20] == 8; r != f.computeCksm {
f.computeCksm = r
f.verifyCksm = r
}
if !sql3util.ValidPageSize(f.pageSize) {
f.computeCksm = false
f.verifyCksm = false
}
}
func cksmCompute(a []byte) (cksm [8]byte) {

View File

@@ -31,6 +31,7 @@ const (
_READONLY _ErrorCode = util.READONLY
_IOERR _ErrorCode = util.IOERR
_NOTFOUND _ErrorCode = util.NOTFOUND
_FULL _ErrorCode = util.FULL
_CANTOPEN _ErrorCode = util.CANTOPEN
_IOERR_READ _ErrorCode = util.IOERR_READ
_IOERR_SHORT_READ _ErrorCode = util.IOERR_SHORT_READ
@@ -57,10 +58,12 @@ const (
_IOERR_COMMIT_ATOMIC _ErrorCode = util.IOERR_COMMIT_ATOMIC
_IOERR_ROLLBACK_ATOMIC _ErrorCode = util.IOERR_ROLLBACK_ATOMIC
_IOERR_DATA _ErrorCode = util.IOERR_DATA
_IOERR_CORRUPTFS _ErrorCode = util.IOERR_CORRUPTFS
_BUSY_SNAPSHOT _ErrorCode = util.BUSY_SNAPSHOT
_CANTOPEN_FULLPATH _ErrorCode = util.CANTOPEN_FULLPATH
_CANTOPEN_ISDIR _ErrorCode = util.CANTOPEN_ISDIR
_READONLY_CANTINIT _ErrorCode = util.READONLY_CANTINIT
_READONLY_DIRECTORY _ErrorCode = util.READONLY_DIRECTORY
_OK_SYMLINK _ErrorCode = util.OK_SYMLINK
)

View File

@@ -88,10 +88,13 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
oflags |= os.O_RDWR
}
isCreate := flags&(OPEN_CREATE) != 0
isJournl := flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0
var err error
var f *os.File
if name == nil {
f, err = os.CreateTemp("", "*.db")
f, err = os.CreateTemp(os.Getenv("SQLITE_TMPDIR"), "*.db")
} else {
f, err = osutil.OpenFile(name.String(), oflags, 0666)
}
@@ -102,6 +105,10 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
if errors.Is(err, syscall.EISDIR) {
return nil, flags, _CANTOPEN_ISDIR
}
if isCreate && isJournl && errors.Is(err, fs.ErrPermission) &&
osAccess(name.String(), ACCESS_EXISTS) != nil {
return nil, flags, _READONLY_DIRECTORY
}
return nil, flags, err
}
@@ -119,10 +126,8 @@ func (vfsOS) OpenFilename(name *Filename, flags OpenFlag) (File, OpenFlag, error
File: f,
psow: true,
readOnly: flags&OPEN_READONLY != 0,
syncDir: canSyncDirs &&
flags&(OPEN_MAIN_JOURNAL|OPEN_SUPER_JOURNAL|OPEN_WAL) != 0 &&
flags&(OPEN_CREATE) != 0,
shm: NewSharedMemory(name.String()+"-shm", flags),
syncDir: canSyncDirs && isCreate && isJournl,
shm: NewSharedMemory(name.String()+"-shm", flags),
}
return &file, flags, nil
}
@@ -154,6 +159,14 @@ func (f *vfsFile) Close() error {
return f.File.Close()
}
func (f *vfsFile) ReadAt(p []byte, off int64) (n int, err error) {
return osReadAt(f.File, p, off)
}
func (f *vfsFile) WriteAt(p []byte, off int64) (n int, err error) {
return osWriteAt(f.File, p, off)
}
func (f *vfsFile) Sync(flags SyncFlag) error {
dataonly := (flags & SYNC_DATAONLY) != 0
fullsync := (flags & 0x0f) == SYNC_FULL

View File

@@ -47,14 +47,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got != LOCK_NONE {
if got := util.ReadBool(mod, pOutput); got {
t.Error("file was locked")
}
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got != LOCK_NONE {
if got := util.ReadBool(mod, pOutput); got {
t.Error("file was locked")
}
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -74,14 +74,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got != LOCK_NONE {
if got := util.ReadBool(mod, pOutput); got {
t.Error("file was locked")
}
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got != LOCK_NONE {
if got := util.ReadBool(mod, pOutput); got {
t.Error("file was locked")
}
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -105,14 +105,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got == LOCK_NONE {
if got := util.ReadBool(mod, pOutput); !got {
t.Log("file wasn't locked, locking is incompatible with SQLite")
}
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got == LOCK_NONE {
if got := util.ReadBool(mod, pOutput); !got {
t.Error("file wasn't locked")
}
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -132,14 +132,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got == LOCK_NONE {
if got := util.ReadBool(mod, pOutput); !got {
t.Log("file wasn't locked, locking is incompatible with SQLite")
}
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got == LOCK_NONE {
if got := util.ReadBool(mod, pOutput); !got {
t.Error("file wasn't locked")
}
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -159,14 +159,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got == LOCK_NONE {
if got := util.ReadBool(mod, pOutput); !got {
t.Log("file wasn't locked, locking is incompatible with SQLite")
}
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got == LOCK_NONE {
if got := util.ReadBool(mod, pOutput); !got {
t.Error("file wasn't locked")
}
rc = vfsFileControl(ctx, mod, pFile1, _FCNTL_LOCKSTATE, pOutput)
@@ -186,14 +186,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got != LOCK_NONE {
if got := util.ReadBool(mod, pOutput); got {
t.Error("file was locked")
}
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[LockLevel](mod, pOutput); got != LOCK_NONE {
if got := util.ReadBool(mod, pOutput); got {
t.Error("file was locked")
}

13
vfs/os_std_rw.go Normal file
View File

@@ -0,0 +1,13 @@
//go:build !unix && (!windows || sqlite3_dotlk)
package vfs
import "os"
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
return file.ReadAt(p, off)
}
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
return file.WriteAt(p, off)
}

View File

@@ -25,6 +25,28 @@ func osAccess(path string, flags AccessFlag) error {
return unix.Access(path, access)
}
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
n, err := file.ReadAt(p, off)
if errno, ok := err.(unix.Errno); ok {
switch errno {
case
unix.ERANGE,
unix.EIO,
unix.ENXIO:
return n, _IOERR_CORRUPTFS
}
}
return n, err
}
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
n, err := file.WriteAt(p, off)
if errno, ok := err.(unix.Errno); ok && errno == unix.ENOSPC {
return n, _FULL
}
return n, err
}
func osSetMode(file *os.File, modeof string) error {
fi, err := os.Stat(modeof)
if err != nil {

View File

@@ -9,6 +9,23 @@ import (
"golang.org/x/sys/windows"
)
func osReadAt(file *os.File, p []byte, off int64) (int, error) {
return file.ReadAt(p, off)
}
func osWriteAt(file *os.File, p []byte, off int64) (int, error) {
n, err := file.WriteAt(p, off)
if errno, ok := err.(windows.Errno); ok {
switch errno {
case
windows.ERROR_HANDLE_DISK_FULL,
windows.ERROR_DISK_FULL:
return n, _FULL
}
}
return n, err
}
func osGetSharedLock(file *os.File) _ErrorCode {
// Acquire the PENDING lock temporarily before acquiring a new SHARED lock.
rc := osReadLock(file, _PENDING_BYTE, 1, 0)

Binary file not shown.

View File

@@ -58,13 +58,8 @@ func vfsFind(ctx context.Context, mod api.Module, zVfsName ptr_t) uint32 {
}
func vfsLocaltime(ctx context.Context, mod api.Module, pTm ptr_t, t int64) _ErrorCode {
tm := time.Unix(t, 0)
var isdst int32
if tm.IsDST() {
isdst = 1
}
const size = 32 / 8
tm := time.Unix(t, 0)
// https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
util.Write32(mod, pTm+0*size, int32(tm.Second()))
util.Write32(mod, pTm+1*size, int32(tm.Minute()))
@@ -74,7 +69,7 @@ func vfsLocaltime(ctx context.Context, mod api.Module, pTm ptr_t, t int64) _Erro
util.Write32(mod, pTm+5*size, int32(tm.Year()-1900))
util.Write32(mod, pTm+6*size, int32(tm.Weekday()-time.Sunday))
util.Write32(mod, pTm+7*size, int32(tm.YearDay()-1))
util.Write32(mod, pTm+8*size, isdst)
util.WriteBool(mod, pTm+8*size, tm.IsDST())
return _OK
}
@@ -123,11 +118,7 @@ func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath ptr_t, flags Acc
path := util.ReadString(mod, zPath, _MAX_PATHNAME)
ok, err := vfs.Access(path, flags)
var res int32
if ok {
res = 1
}
util.Write32(mod, pResOut, res)
util.WriteBool(mod, pResOut, ok)
return vfsErrorCode(err, _IOERR_ACCESS)
}
@@ -151,9 +142,8 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zPath, pFile ptr_t, flag
file.SetPowersafeOverwrite(b)
}
}
if file, ok := file.(FileSharedMemory); ok &&
pOutVFS != 0 && file.SharedMemory() != nil {
util.Write32(mod, pOutVFS, int32(1))
if file, ok := file.(FileSharedMemory); ok && pOutVFS != 0 {
util.WriteBool(mod, pOutVFS, file.SharedMemory() != nil)
}
if pOutFlags != 0 {
util.Write32(mod, pOutFlags, flags)
@@ -225,12 +215,7 @@ func vfsUnlock(ctx context.Context, mod api.Module, pFile ptr_t, eLock LockLevel
func vfsCheckReservedLock(ctx context.Context, mod api.Module, pFile, pResOut ptr_t) _ErrorCode {
file := vfsFileGet(ctx, mod, pFile).(File)
locked, err := file.CheckReservedLock()
var res int32
if locked {
res = 1
}
util.Write32(mod, pResOut, res)
util.WriteBool(mod, pResOut, locked)
return vfsErrorCode(err, _IOERR_CHECKRESERVEDLOCK)
}
@@ -254,24 +239,20 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_PERSIST_WAL:
if file, ok := file.(FilePersistWAL); ok {
if i := util.Read32[int32](mod, pArg); i >= 0 {
file.SetPersistWAL(i != 0)
} else if file.PersistWAL() {
util.Write32(mod, pArg, int32(1))
if i := util.Read32[int32](mod, pArg); i < 0 {
util.WriteBool(mod, pArg, file.PersistWAL())
} else {
util.Write32(mod, pArg, int32(0))
file.SetPersistWAL(i != 0)
}
return _OK
}
case _FCNTL_POWERSAFE_OVERWRITE:
if file, ok := file.(FilePowersafeOverwrite); ok {
if i := util.Read32[int32](mod, pArg); i >= 0 {
file.SetPowersafeOverwrite(i != 0)
} else if file.PowersafeOverwrite() {
util.Write32(mod, pArg, int32(1))
if i := util.Read32[int32](mod, pArg); i < 0 {
util.WriteBool(mod, pArg, file.PowersafeOverwrite())
} else {
util.Write32(mod, pArg, int32(0))
file.SetPowersafeOverwrite(i != 0)
}
return _OK
}
@@ -293,11 +274,7 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_HAS_MOVED:
if file, ok := file.(FileHasMoved); ok {
moved, err := file.HasMoved()
var val uint32
if moved {
val = 1
}
util.Write32(mod, pArg, val)
util.WriteBool(mod, pArg, moved)
return vfsErrorCode(err, _IOERR_FSTAT)
}
@@ -394,7 +371,7 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_LOCK_TIMEOUT:
if file, ok := file.(FileSharedMemory); ok {
if shm, ok := file.SharedMemory().(blockingSharedMemory); ok {
shm.shmEnableBlocking(util.Read32[uint32](mod, pArg) != 0)
shm.shmEnableBlocking(util.ReadBool(mod, pArg))
return _OK
}
}

View File

@@ -172,7 +172,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[int32](mod, 4); got != 1 {
if got := util.ReadBool(mod, 4); !got {
t.Error("directory did not exist")
}
@@ -180,7 +180,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[int32](mod, 4); got != 1 {
if got := util.ReadBool(mod, 4); !got {
t.Error("can't access directory")
}
@@ -189,7 +189,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[int32](mod, 4); got != 1 {
if got := util.ReadBool(mod, 4); !got {
t.Error("can't access file")
}
@@ -207,7 +207,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK {
t.Fatal("returned", rc)
}
if got := util.Read32[int32](mod, 4); got != 0 {
if got := util.ReadBool(mod, 4); got {
t.Error("can access file")
}
}

View File

@@ -399,10 +399,10 @@ func (idx *IndexInfo) save() {
util.Write32(mod, ptr+20, int32(idx.IdxNum))
if idx.IdxStr != "" {
util.Write32(mod, ptr+24, idx.c.newString(idx.IdxStr))
util.Write32(mod, ptr+28, int32(1)) // needToFreeIdxStr
util.WriteBool(mod, ptr+28, true) // needToFreeIdxStr
}
if idx.OrderByConsumed {
util.Write32(mod, ptr+32, int32(1))
util.WriteBool(mod, ptr+32, true)
}
util.WriteFloat64(mod, ptr+40, idx.EstimatedCost)
util.Write64(mod, ptr+48, idx.EstimatedRows)