diff --git a/context.go b/context.go index 8d7604c..a18211d 100644 --- a/context.go +++ b/context.go @@ -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. diff --git a/internal/util/error_test.go b/internal/util/error_test.go new file mode 100644 index 0000000..e2b8e51 --- /dev/null +++ b/internal/util/error_test.go @@ -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() + } + } +} diff --git a/tests/func_test.go b/tests/func_test.go index 130c419..921b3ef 100644 --- a/tests/func_test.go +++ b/tests/func_test.go @@ -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) + } +} diff --git a/vfs/const_test.go b/vfs/const_test.go new file mode 100644 index 0000000..0676d40 --- /dev/null +++ b/vfs/const_test.go @@ -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) + } + }) + } +} diff --git a/vfs/memdb/memdb.go b/vfs/memdb/memdb.go index 027fb7f..cfab2fd 100644 --- a/vfs/memdb/memdb.go +++ b/vfs/memdb/memdb.go @@ -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 } diff --git a/vfs/os_unix_lock.go b/vfs/os_unix_lock.go index 85a7b0f..ffa1f5e 100644 --- a/vfs/os_unix_lock.go +++ b/vfs/os_unix_lock.go @@ -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 } diff --git a/vfs/os_windows.go b/vfs/os_windows.go index 83b952b..7425b55 100644 --- a/vfs/os_windows.go +++ b/vfs/os_windows.go @@ -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 } }