Fix Context.ResultPointer.

This commit is contained in:
Nuno Cruces
2024-07-20 12:52:25 +01:00
parent 28f225b32e
commit 06f58c35e3
7 changed files with 83 additions and 2 deletions

View File

@@ -165,7 +165,8 @@ func (ctx Context) resultRFC3339Nano(value time.Time) {
// https://sqlite.org/c3ref/result_blob.html
func (ctx Context) ResultPointer(ptr any) {
valPtr := util.AddHandle(ctx.c.ctx, ptr)
ctx.c.call("sqlite3_result_pointer_go", uint64(valPtr))
ctx.c.call("sqlite3_result_pointer_go",
uint64(ctx.handle), uint64(valPtr))
}
// ResultJSON sets the result of the function to the JSON encoding of value.

View File

@@ -0,0 +1,13 @@
package util
import "testing"
func TestErrorJoiner(t *testing.T) {
var errs ErrorJoiner
errs.Join(NilErr, OOMErr)
for i, e := range []error{NilErr, OOMErr} {
if e != errs[i] {
t.Fail()
}
}
}

View File

@@ -279,3 +279,41 @@ func TestAnyCollationNeeded(t *testing.T) {
t.Fatal(err)
}
}
func TestPointer(t *testing.T) {
t.Parallel()
db, err := sqlite3.Open(":memory:")
if err != nil {
t.Fatal(err)
}
defer db.Close()
var want any = "xpto"
err = db.CreateFunction("ident", 1, 0, func(ctx sqlite3.Context, arg ...sqlite3.Value) {
got := arg[0].Pointer()
if got != want {
t.Errorf("want %v, got %v", want, got)
}
ctx.ResultPointer(got)
})
if err != nil {
t.Fatal(err)
}
stmt, _, err := db.Prepare(`SELECT ident(ident(?))`)
if err != nil {
t.Fatal(err)
}
err = stmt.BindPointer(1, want)
if err != nil {
t.Fatal(err)
}
err = stmt.Exec()
if err != nil {
t.Error(err)
}
}

24
vfs/const_test.go Normal file
View File

@@ -0,0 +1,24 @@
package vfs
import (
"math"
"testing"
)
func Test_ErrorCode_Error(t *testing.T) {
tests := []struct {
code _ErrorCode
want string
}{
{_OK, "sqlite3: not an error"},
{_ERROR, "sqlite3: SQL logic error"},
{math.MaxUint32, "sqlite3: unknown error"},
}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
if got := tt.code.Error(); got != tt.want {
t.Errorf("_ErrorCode.Error() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -30,7 +30,7 @@ func (memVFS) Open(name string, flags vfs.OpenFlag) (vfs.File, vfs.OpenFlag, err
vfs.OPEN_TEMP_DB |
vfs.OPEN_TEMP_JOURNAL
if flags&types == 0 {
// notest
// notest // OPEN_MEMORY
return nil, flags, sqlite3.CANTOPEN
}
@@ -270,6 +270,7 @@ func (m *memFile) Unlock(lock vfs.LockLevel) error {
}
func (m *memFile) CheckReservedLock() (bool, error) {
// notest // OPEN_MEMORY
if m.lock >= vfs.LOCK_RESERVED {
return true, nil
}
@@ -279,6 +280,7 @@ func (m *memFile) CheckReservedLock() (bool, error) {
}
func (m *memFile) SectorSize() int {
// notest // IOCAP_POWERSAFE_OVERWRITE
return sectorSize
}

View File

@@ -50,6 +50,7 @@ func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode {
// indicates that the other process is not following the locking
// protocol. If this happens, return IOERR_RDLOCK. Returning
// BUSY would confuse the upper layer.
// notest
return _IOERR_RDLOCK
}
}
@@ -98,6 +99,7 @@ func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
case unix.EPERM:
return _PERM
}
// notest // usually EWOULDBLOCK == EAGAIN
if errno == unix.EWOULDBLOCK && unix.EWOULDBLOCK != unix.EAGAIN {
return _BUSY
}

View File

@@ -66,6 +66,7 @@ func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode {
if rc := osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0); rc != _OK {
// This should never happen.
// We should always be able to reacquire the read lock.
// notest
return _IOERR_RDLOCK
}
}