mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Localtime.
This commit is contained in:
8
conn.go
8
conn.go
@@ -40,7 +40,7 @@ func OpenFlags(filename string, flags OpenFlag) (conn *Conn, err error) {
|
||||
c := newConn(module)
|
||||
c.ctx = context.Background()
|
||||
namePtr := c.newString(filename)
|
||||
connPtr := c.new(ptrSize)
|
||||
connPtr := c.new(wordSize)
|
||||
defer c.free(namePtr)
|
||||
defer c.free(connPtr)
|
||||
|
||||
@@ -86,8 +86,8 @@ func (c *Conn) Prepare(sql string) (stmt *Stmt, tail string, err error) {
|
||||
|
||||
func (c *Conn) PrepareFlags(sql string, flags PrepareFlag) (stmt *Stmt, tail string, err error) {
|
||||
sqlPtr := c.newString(sql)
|
||||
stmtPtr := c.new(ptrSize)
|
||||
tailPtr := c.new(ptrSize)
|
||||
stmtPtr := c.new(wordSize)
|
||||
tailPtr := c.new(wordSize)
|
||||
defer c.free(sqlPtr)
|
||||
defer c.free(stmtPtr)
|
||||
defer c.free(tailPtr)
|
||||
@@ -218,4 +218,4 @@ func getString(memory api.Memory, ptr, maxlen uint32) string {
|
||||
}
|
||||
}
|
||||
|
||||
const ptrSize = 4
|
||||
const wordSize = 4
|
||||
|
||||
@@ -12,22 +12,7 @@ zig cc --target=wasm32-wasi -flto -g0 -O2 \
|
||||
-mmutable-globals \
|
||||
-mbulk-memory -mreference-types \
|
||||
-mnontrapping-fptoint -msign-ext \
|
||||
-DSQLITE_OS_OTHER=1 -DSQLITE_BYTEORDER=1234 \
|
||||
-DHAVE_ISNAN -DHAVE_USLEEP -DHAVE_MALLOC_USABLE_SIZE \
|
||||
-DSQLITE_DQS=0 \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_DEFAULT_MEMSTATUS=0 \
|
||||
-DSQLITE_DEFAULT_LOCKING_MODE=1 \
|
||||
-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 \
|
||||
-DSQLITE_LIKE_DOESNT_MATCH_BLOBS \
|
||||
-DSQLITE_MAX_EXPR_DEPTH=0 \
|
||||
-DSQLITE_OMIT_DECLTYPE \
|
||||
-DSQLITE_OMIT_DEPRECATED \
|
||||
-DSQLITE_OMIT_PROGRESS_CALLBACK \
|
||||
-DSQLITE_OMIT_SHARED_CACHE \
|
||||
-DSQLITE_OMIT_AUTOINIT \
|
||||
-DSQLITE_OMIT_UTF16 \
|
||||
-DSQLITE_USE_ALLOCA \
|
||||
-D_HAVE_SQLITE_CONFIG_H \
|
||||
-Wl,--export=malloc \
|
||||
-Wl,--export=free \
|
||||
-Wl,--export=malloc_destructor \
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sqlite3.h"
|
||||
|
||||
@@ -7,6 +8,8 @@ int main() {
|
||||
if (rc != SQLITE_OK) return 1;
|
||||
}
|
||||
|
||||
int go_localtime(sqlite3_int64, struct tm *);
|
||||
|
||||
int go_randomness(sqlite3_vfs *, int nByte, char *zOut);
|
||||
int go_sleep(sqlite3_vfs *, int microseconds);
|
||||
int go_current_time(sqlite3_vfs *, double *);
|
||||
@@ -48,6 +51,10 @@ static int no_file_control(sqlite3_file *pFile, int op, void *pArg) {
|
||||
static int no_sector_size(sqlite3_file *pFile) { return 0; }
|
||||
static int no_device_characteristics(sqlite3_file *pFile) { return 0; }
|
||||
|
||||
int localtime_s(struct tm *const pTm, time_t const *const pTime) {
|
||||
return go_localtime((sqlite3_int64)*pTime, pTm);
|
||||
}
|
||||
|
||||
static int go_open_c(sqlite3_vfs *vfs, sqlite3_filename zName,
|
||||
sqlite3_file *file, int flags, int *pOutFlags) {
|
||||
static const sqlite3_io_methods go_io = {
|
||||
|
||||
36
sqlite3/sqlite_cfg.h
Normal file
36
sqlite3/sqlite_cfg.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <time.h>
|
||||
|
||||
// Platform Configuration
|
||||
|
||||
#define SQLITE_OS_OTHER 1
|
||||
#define SQLITE_BYTEORDER 1234
|
||||
|
||||
#define HAVE_ISNAN 1
|
||||
#define HAVE_USLEEP 1
|
||||
#define HAVE_LOCALTIME_S 1
|
||||
#define HAVE_MALLOC_USABLE_SIZE 1
|
||||
|
||||
// Recommended Options
|
||||
|
||||
#define SQLITE_DQS 0
|
||||
#define SQLITE_THREADSAFE 0
|
||||
#define SQLITE_DEFAULT_MEMSTATUS 0
|
||||
#define SQLITE_DEFAULT_WAL_SYNCHRONOUS 1
|
||||
#define SQLITE_LIKE_DOESNT_MATCH_BLOBS
|
||||
#define SQLITE_MAX_EXPR_DEPTH 0
|
||||
#define SQLITE_OMIT_DECLTYPE
|
||||
#define SQLITE_OMIT_DEPRECATED
|
||||
#define SQLITE_OMIT_PROGRESS_CALLBACK
|
||||
#define SQLITE_OMIT_SHARED_CACHE
|
||||
#define SQLITE_OMIT_AUTOINIT
|
||||
#define SQLITE_USE_ALLOCA
|
||||
|
||||
// Need this to access WAL databases without the use of shared memory.
|
||||
#define SQLITE_DEFAULT_LOCKING_MODE 1
|
||||
// Go uses UTF-8 everywhere.
|
||||
#define SQLITE_OMIT_UTF16
|
||||
// Remove some testing code.
|
||||
#define SQLITE_UNTESTABLE
|
||||
|
||||
// Implemented in Go.
|
||||
int localtime_s(struct tm *const pTm, time_t const *const pTime);
|
||||
24
vfs.go
24
vfs.go
@@ -26,6 +26,7 @@ func vfsInstantiate(ctx context.Context, r wazero.Runtime) (err error) {
|
||||
}
|
||||
|
||||
env := r.NewHostModuleBuilder("env")
|
||||
env.NewFunctionBuilder().WithFunc(vfsLocaltime).Export("go_localtime")
|
||||
env.NewFunctionBuilder().WithFunc(vfsRandomness).Export("go_randomness")
|
||||
env.NewFunctionBuilder().WithFunc(vfsSleep).Export("go_sleep")
|
||||
env.NewFunctionBuilder().WithFunc(vfsCurrentTime).Export("go_current_time")
|
||||
@@ -54,6 +55,29 @@ func vfsExit(ctx context.Context, mod api.Module, exitCode uint32) {
|
||||
panic(sys.NewExitError(mod.Name(), exitCode))
|
||||
}
|
||||
|
||||
func vfsLocaltime(ctx context.Context, mod api.Module, t uint64, pTm uint32) uint32 {
|
||||
tm := time.Unix(int64(t), 0)
|
||||
var isdst int
|
||||
if tm.IsDST() {
|
||||
isdst = 1
|
||||
}
|
||||
|
||||
// https://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
|
||||
if mem := mod.Memory(); true &&
|
||||
mem.WriteUint32Le(pTm+0*wordSize, uint32(tm.Second())) &&
|
||||
mem.WriteUint32Le(pTm+1*wordSize, uint32(tm.Minute())) &&
|
||||
mem.WriteUint32Le(pTm+2*wordSize, uint32(tm.Hour())) &&
|
||||
mem.WriteUint32Le(pTm+3*wordSize, uint32(tm.Day())) &&
|
||||
mem.WriteUint32Le(pTm+4*wordSize, uint32(tm.Month()-time.January)) &&
|
||||
mem.WriteUint32Le(pTm+5*wordSize, uint32(tm.Year()-1900)) &&
|
||||
mem.WriteUint32Le(pTm+6*wordSize, uint32(tm.Weekday()-time.Sunday)) &&
|
||||
mem.WriteUint32Le(pTm+7*wordSize, uint32(tm.YearDay()-1)) &&
|
||||
mem.WriteUint32Le(pTm+8*wordSize, uint32(isdst)) {
|
||||
return _OK
|
||||
}
|
||||
panic(rangeErr)
|
||||
}
|
||||
|
||||
func vfsRandomness(ctx context.Context, mod api.Module, pVfs, nByte, zByte uint32) uint32 {
|
||||
mem, ok := mod.Memory().Read(zByte, nByte)
|
||||
if !ok {
|
||||
|
||||
@@ -92,7 +92,7 @@ func (p vfsFilePtr) OSFile() *os.File {
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) ID() uint32 {
|
||||
id, ok := p.Memory().ReadUint32Le(p.ptr + ptrSize)
|
||||
id, ok := p.Memory().ReadUint32Le(p.ptr + wordSize)
|
||||
if !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func (p vfsFilePtr) ID() uint32 {
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) Lock() uint32 {
|
||||
lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*ptrSize)
|
||||
lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*wordSize)
|
||||
if !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
@@ -108,14 +108,14 @@ func (p vfsFilePtr) Lock() uint32 {
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) SetID(id uint32) vfsFilePtr {
|
||||
if ok := p.Memory().WriteUint32Le(p.ptr+ptrSize, id); !ok {
|
||||
if ok := p.Memory().WriteUint32Le(p.ptr+wordSize, id); !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) SetLock(lock uint32) vfsFilePtr {
|
||||
if ok := p.Memory().WriteUint32Le(p.ptr+2*ptrSize, lock); !ok {
|
||||
if ok := p.Memory().WriteUint32Le(p.ptr+2*wordSize, lock); !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
return p
|
||||
|
||||
Reference in New Issue
Block a user