More type safe.

This commit is contained in:
Nuno Cruces
2025-02-17 12:00:55 +00:00
parent 975feb2fd4
commit 4dd7bd0ff2
8 changed files with 49 additions and 67 deletions

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), rc := res_t(c.call("sqlite3_db_config", stk_t(c.handle),
stk_t(op), stk_t(argsPtr))) 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. // 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", rc = res_t(c.call("sqlite3_file_control",
stk_t(c.handle), stk_t(schemaPtr), stk_t(c.handle), stk_t(schemaPtr),
stk_t(op), stk_t(ptr))) stk_t(op), stk_t(ptr)))
ret = util.Read32[uint32](c.mod, ptr) != 0 ret = util.ReadBool(c.mod, ptr)
case FCNTL_CHUNK_SIZE: case FCNTL_CHUNK_SIZE:
util.Write32(c.mod, ptr, int32(arg[0].(int))) 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 { if ptr := util.Read32[ptr_t](c.mod, collSeqPtr); ptr != 0 {
collSeq = util.ReadString(c.mod, ptr, _MAX_NAME) collSeq = util.ReadString(c.mod, ptr, _MAX_NAME)
} }
notNull = util.Read32[uint32](c.mod, notNullPtr) != 0 notNull = util.ReadBool(c.mod, notNullPtr)
autoInc = util.Read32[uint32](c.mod, autoIncPtr) != 0 autoInc = util.ReadBool(c.mod, autoIncPtr)
primaryKey = util.Read32[uint32](c.mod, primaryKeyPtr) != 0 primaryKey = util.ReadBool(c.mod, primaryKeyPtr)
} }
return return
} }

View File

@@ -26,9 +26,6 @@ func View(mod api.Module, ptr Ptr_t, size int64) []byte {
if ptr == 0 { if ptr == 0 {
panic(NilErr) panic(NilErr)
} }
if size == 0 {
return nil
}
if uint64(size) > math.MaxUint32 { if uint64(size) > math.MaxUint32 {
panic(RangeErr) panic(RangeErr)
} }
@@ -110,6 +107,18 @@ func WriteFloat64(mod api.Module, ptr Ptr_t, v float64) {
Write64(mod, ptr, math.Float64bits(v)) 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 { func ReadString(mod api.Module, ptr Ptr_t, maxlen int64) string {
if ptr == 0 { if ptr == 0 {
panic(NilErr) panic(NilErr)

View File

@@ -130,10 +130,6 @@ func Test_sqlite_newBytes(t *testing.T) {
if ptr == 0 { if ptr == 0 {
t.Fatal("got nullptr, want a pointer") 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) { func Test_sqlite_newString(t *testing.T) {

View File

@@ -47,14 +47,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file was locked")
} }
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput) rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file was locked")
} }
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput) rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -74,14 +74,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file was locked")
} }
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput) rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file was locked")
} }
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput) rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -105,14 +105,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Log("file wasn't locked, locking is incompatible with SQLite")
} }
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput) rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file wasn't locked")
} }
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput) rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -132,14 +132,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Log("file wasn't locked, locking is incompatible with SQLite")
} }
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput) rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file wasn't locked")
} }
rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput) rc = vfsFileControl(ctx, mod, pFile2, _FCNTL_LOCKSTATE, pOutput)
@@ -159,14 +159,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Log("file wasn't locked, locking is incompatible with SQLite")
} }
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput) rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file wasn't locked")
} }
rc = vfsFileControl(ctx, mod, pFile1, _FCNTL_LOCKSTATE, pOutput) rc = vfsFileControl(ctx, mod, pFile1, _FCNTL_LOCKSTATE, pOutput)
@@ -186,14 +186,14 @@ func Test_vfsLock(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file was locked")
} }
rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput) rc = vfsCheckReservedLock(ctx, mod, pFile2, pOutput)
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("file was locked")
} }

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 { 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 const size = 32 / 8
tm := time.Unix(t, 0)
// https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html // https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
util.Write32(mod, pTm+0*size, int32(tm.Second())) util.Write32(mod, pTm+0*size, int32(tm.Second()))
util.Write32(mod, pTm+1*size, int32(tm.Minute())) 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+5*size, int32(tm.Year()-1900))
util.Write32(mod, pTm+6*size, int32(tm.Weekday()-time.Sunday)) 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+7*size, int32(tm.YearDay()-1))
util.Write32(mod, pTm+8*size, isdst) util.WriteBool(mod, pTm+8*size, tm.IsDST())
return _OK 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) path := util.ReadString(mod, zPath, _MAX_PATHNAME)
ok, err := vfs.Access(path, flags) ok, err := vfs.Access(path, flags)
var res int32 util.WriteBool(mod, pResOut, ok)
if ok {
res = 1
}
util.Write32(mod, pResOut, res)
return vfsErrorCode(err, _IOERR_ACCESS) 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) file.SetPowersafeOverwrite(b)
} }
} }
if file, ok := file.(FileSharedMemory); ok && if file, ok := file.(FileSharedMemory); ok && pOutVFS != 0 {
pOutVFS != 0 && file.SharedMemory() != nil { util.WriteBool(mod, pOutVFS, file.SharedMemory() != nil)
util.Write32(mod, pOutVFS, int32(1))
} }
if pOutFlags != 0 { if pOutFlags != 0 {
util.Write32(mod, pOutFlags, flags) 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 { func vfsCheckReservedLock(ctx context.Context, mod api.Module, pFile, pResOut ptr_t) _ErrorCode {
file := vfsFileGet(ctx, mod, pFile).(File) file := vfsFileGet(ctx, mod, pFile).(File)
locked, err := file.CheckReservedLock() locked, err := file.CheckReservedLock()
util.WriteBool(mod, pResOut, locked)
var res int32
if locked {
res = 1
}
util.Write32(mod, pResOut, res)
return vfsErrorCode(err, _IOERR_CHECKRESERVEDLOCK) 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: case _FCNTL_PERSIST_WAL:
if file, ok := file.(FilePersistWAL); ok { if file, ok := file.(FilePersistWAL); ok {
if i := util.Read32[int32](mod, pArg); i >= 0 { if i := util.Read32[int32](mod, pArg); i < 0 {
file.SetPersistWAL(i != 0) util.WriteBool(mod, pArg, file.PersistWAL())
} else if file.PersistWAL() {
util.Write32(mod, pArg, int32(1))
} else { } else {
util.Write32(mod, pArg, int32(0)) file.SetPersistWAL(i != 0)
} }
return _OK return _OK
} }
case _FCNTL_POWERSAFE_OVERWRITE: case _FCNTL_POWERSAFE_OVERWRITE:
if file, ok := file.(FilePowersafeOverwrite); ok { if file, ok := file.(FilePowersafeOverwrite); ok {
if i := util.Read32[int32](mod, pArg); i >= 0 { if i := util.Read32[int32](mod, pArg); i < 0 {
file.SetPowersafeOverwrite(i != 0) util.WriteBool(mod, pArg, file.PowersafeOverwrite())
} else if file.PowersafeOverwrite() {
util.Write32(mod, pArg, int32(1))
} else { } else {
util.Write32(mod, pArg, int32(0)) file.SetPowersafeOverwrite(i != 0)
} }
return _OK return _OK
} }
@@ -293,11 +274,7 @@ func vfsFileControlImpl(ctx context.Context, mod api.Module, file File, op _Fcnt
case _FCNTL_HAS_MOVED: case _FCNTL_HAS_MOVED:
if file, ok := file.(FileHasMoved); ok { if file, ok := file.(FileHasMoved); ok {
moved, err := file.HasMoved() moved, err := file.HasMoved()
var val uint32 util.WriteBool(mod, pArg, moved)
if moved {
val = 1
}
util.Write32(mod, pArg, val)
return vfsErrorCode(err, _IOERR_FSTAT) 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: case _FCNTL_LOCK_TIMEOUT:
if file, ok := file.(FileSharedMemory); ok { if file, ok := file.(FileSharedMemory); ok {
if shm, ok := file.SharedMemory().(blockingSharedMemory); ok { if shm, ok := file.SharedMemory().(blockingSharedMemory); ok {
shm.shmEnableBlocking(util.Read32[uint32](mod, pArg) != 0) shm.shmEnableBlocking(util.ReadBool(mod, pArg))
return _OK return _OK
} }
} }

View File

@@ -172,7 +172,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("directory did not exist")
} }
@@ -180,7 +180,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("can't access directory")
} }
@@ -189,7 +189,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("can't access file")
} }
@@ -207,7 +207,7 @@ func Test_vfsAccess(t *testing.T) {
if rc != _OK { if rc != _OK {
t.Fatal("returned", rc) 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") t.Error("can access file")
} }
} }

View File

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