diff --git a/README.md b/README.md index 1939b36..a1863af 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,9 @@ and WAL databases are not supported. - [x] nested transactions - [ ] incremental BLOB I/O - [ ] online backup - - [ ] session extension - [ ] snapshots + - [ ] session extension + - [ ] resumable bulk update - [ ] SQL functions - [ ] custom VFSes - [ ] read-only VFS, wrapping an [`io.ReaderAt`](https://pkg.go.dev/io#ReaderAt) diff --git a/conn.go b/conn.go index 9a620c9..cdce31a 100644 --- a/conn.go +++ b/conn.go @@ -267,17 +267,18 @@ func (c *Conn) sendInterrupt() { // Pragma executes a PRAGMA statement and returns any result as a string. // // https://www.sqlite.org/pragma.html -func (c *Conn) Pragma(str string) string { +func (c *Conn) Pragma(str string) []string { stmt := c.MustPrepare(`PRAGMA ` + str) defer stmt.Close() - if stmt.Step() { - return stmt.ColumnText(0) + var pragmas []string + for stmt.Step() { + pragmas = append(pragmas, stmt.ColumnText(0)) } if err := stmt.Err(); err != nil { panic(err) } - return "" + return pragmas } func (c *Conn) error(rc uint64, sql ...string) error { diff --git a/driver/driver.go b/driver/driver.go index da013eb..13ec009 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -94,7 +94,7 @@ func (c conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, er if opts.ReadOnly { c.txCommit = ` ROLLBACK; - PRAGMA query_only=` + c.conn.Pragma("query_only") + PRAGMA query_only=` + c.conn.Pragma("query_only")[0] txBegin = ` BEGIN deferred; PRAGMA query_only=on` diff --git a/embed/sqlite3.wasm b/embed/sqlite3.wasm index d83ac83..56e68a9 100755 Binary files a/embed/sqlite3.wasm and b/embed/sqlite3.wasm differ diff --git a/sqlite3/qsort.c b/sqlite3/qsort.c new file mode 100644 index 0000000..129af1e --- /dev/null +++ b/sqlite3/qsort.c @@ -0,0 +1,14 @@ +#include + +void qsort_r(void *, size_t, size_t, + int (*)(const void *, const void *, void *), void *); + +typedef int (*cmpfun)(const void *, const void *); + +static int wrapper_cmp(const void *v1, const void *v2, void *cmp) { + return ((cmpfun)cmp)(v1, v2); +} + +void qsort(void *base, size_t nel, size_t width, cmpfun cmp) { + qsort_r(base, nel, width, wrapper_cmp, cmp); +} \ No newline at end of file diff --git a/sqlite3/sqlite_cfg.h b/sqlite3/sqlite_cfg.h index 2b00285..14746c8 100644 --- a/sqlite3/sqlite_cfg.h +++ b/sqlite3/sqlite_cfg.h @@ -28,18 +28,33 @@ #define SQLITE_OMIT_AUTOINIT #define SQLITE_USE_ALLOCA +// Because WASM does not support shared memory, +// SQLite disables it for WASM builds. +// We set the default locking mode to EXCLUSIVE instead. +// https://www.sqlite.org/wal.html#noshm +#undef SQLITE_OMIT_WAL +#define SQLITE_DEFAULT_LOCKING_MODE 1 + // Recommended Extensions -// #define SQLITE_ENABLE_MATH_FUNCTIONS 1 -// #define SQLITE_ENABLE_FTS3 1 -// #define SQLITE_ENABLE_FTS3_PARENTHESIS 1 -// #define SQLITE_ENABLE_FTS4 1 -// #define SQLITE_ENABLE_FTS5 1 -// #define SQLITE_ENABLE_RTREE 1 -// #define SQLITE_ENABLE_GEOPOLY 1 +#define SQLITE_ENABLE_MATH_FUNCTIONS 1 +#define SQLITE_ENABLE_JSON1 1 +#define SQLITE_ENABLE_FTS3 1 +#define SQLITE_ENABLE_FTS3_PARENTHESIS 1 +#define SQLITE_ENABLE_FTS4 1 +#define SQLITE_ENABLE_FTS5 1 +#define SQLITE_ENABLE_RTREE 1 +#define SQLITE_ENABLE_GEOPOLY 1 -// Need this to access WAL databases without the use of shared memory. -#define SQLITE_DEFAULT_LOCKING_MODE 1 +// Snapshot +// #define SQLITE_ENABLE_SNAPSHOT 1 + +// Session Extension +// #define SQLITE_ENABLE_SESSION 1 +// #define SQLITE_ENABLE_PREUPDATE_HOOK 1 + +// Resumable Bulk Update Extension +// #define SQLITE_ENABLE_RBU 1 // Implemented in Go. int localtime_s(struct tm *const pTm, time_t const *const pTime); \ No newline at end of file