From 4dd7bd0ff2ace82deb12519e4e1e52faaa9c9422 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 17 Feb 2025 12:00:55 +0000 Subject: [PATCH] More type safe. --- config.go | 4 ++-- conn.go | 6 +++--- internal/util/mem.go | 15 ++++++++++--- sqlite_test.go | 4 ---- vfs/lock_test.go | 24 ++++++++++----------- vfs/vfs.go | 51 ++++++++++++-------------------------------- vfs/vfs_test.go | 8 +++---- vtab.go | 4 ++-- 8 files changed, 49 insertions(+), 67 deletions(-) diff --git a/config.go b/config.go index 7fff6ea..17166b9 100644 --- a/config.go +++ b/config.go @@ -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))) diff --git a/conn.go b/conn.go index fffc741..4357202 100644 --- a/conn.go +++ b/conn.go @@ -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 } diff --git a/internal/util/mem.go b/internal/util/mem.go index bfb1a64..d2fea08 100644 --- a/internal/util/mem.go +++ b/internal/util/mem.go @@ -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) diff --git a/sqlite_test.go b/sqlite_test.go index 5b969de..8321275 100644 --- a/sqlite_test.go +++ b/sqlite_test.go @@ -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) { diff --git a/vfs/lock_test.go b/vfs/lock_test.go index e8dfe84..ec03881 100644 --- a/vfs/lock_test.go +++ b/vfs/lock_test.go @@ -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") } diff --git a/vfs/vfs.go b/vfs/vfs.go index ca105ff..c70507c 100644 --- a/vfs/vfs.go +++ b/vfs/vfs.go @@ -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 } } diff --git a/vfs/vfs_test.go b/vfs/vfs_test.go index 64d9a21..86f982d 100644 --- a/vfs/vfs_test.go +++ b/vfs/vfs_test.go @@ -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") } } diff --git a/vtab.go b/vtab.go index 278195e..884aaaa 100644 --- a/vtab.go +++ b/vtab.go @@ -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)