We need the `sqlite3_get_autocomit()` helper in the TypeScript SDK, for
example. The fact that it's not exported seems to be just an omission so
let's add it.
Based on https://gist.github.com/psarna/0dbd95424fb7121bb54bf5f961e1e117
from SQLite3MultipleCiphers, let's try and make libsql flexible enough
to not require patching the amalgamation files at all in order to integrate
with SQLite3Multiple ciphers.
For starters, their codec functions are instead declared as libsql_pager_codec
and libsql_pager_has_codec. The idea for future integration is that
if an appropriate compilation flag is on, we assume that the code will be compiled
with additional symbols that provide all the implementation we need, e.g.
libsql_pager_codec_impl() will just transiently call sqlite3mcPagerCodec().
If the following directives are defined:
- LIBSQL_PRE_VFS_HOOK
- LIBSQL_EXTRA_PRAGMAS
- LIBSQL_EXTRA_URI_PARAMS
, a few new symbols need to be compiled in, respectively:
- libsql_pre_vfs_hook(const char *)
- libsql_extra_pragma(sqlite3 *, const char *, void *)
- libsql_handle_extra_uri_params(sqlite3 *, const char *),
libsql_handle_extra_attach_params(sqlite3 *, const char *,
const char *, sqlite3_value *, char **)
Those hooks, combined with virtual WAL, should be plenty enough to
integrate SQLite3MultipleCiphers without patching sqlite3.c code.
Those are really weird internally, and assume that the db path string
you pass as an argument resides in a very specific place in memory,
preceded by 4 zero bytes, and followed by journal and wal names.
The WALv2 rework broke this magic assumption, so we hereby restore it.
As follow-up, we should move this filename management to virtual WAL,
because with virtual WAL implementations you sometimes don't even have
a notion of "WAL file path".
Refactor of the virtual wal API. Drop global wals in favor of passing
the wal implementation as an argument to libsql_open.
The WAL interface is split in two sets of virtual methods:
- `create_wal` is passed when opening a sqlite connection. It's role is
to instantiate a wal.
- `libql_wal` is the wal itself, created by the `create_wal`.
The sqlite3_wal and `sqlite3_create_wal` implementation are completely
decoupled from the wal implementation. They are the default
implementation when using the traditional open methods, and
sqlite3_create_wal is exposed as a global variable, and can be composed
with other wal implementations.
On top of a special VFS, `make wasi` now also compiles-in
a specialized virtual WAL methods module. It doesn't do anything
right now (just falls back to the regular implementation),
but can be used to call back to the host, inject hooks, etc.
It's far from working, but it already properly calls back
from a WebAssembly instance to the host for VFS operations.
We also want the same for virtual WAL and we'll have a solid foundation
for running libSQL in a Wasm runtime.
It is not directly tested or usable yet, and depends on having
wasi-libc library available at /usr/share/wasi-sysroot.
Still, it compiled, so it's a nice start.
`make wasi` produces `libsql.wasm` module.
Future work includes using this module to run a WebAssembly app
in a runtime that supports WASI, using `libsql.wasm` as the database
implementation.
The patch is based on splitting SQLITE_OMIT_WAL into SQLITE_OMIT_SHARED_MEM,
so that we can still compile WAL mode, just without shared memory,
so still usable with exclusive mode or via libSQL's virtual WAL.