SQLite Wasm Rust
Provide sqlite solution for wasm32-unknown-unknown
target.
Shim Usage
[]
= "0.2"
use ;
async
Wrapper Usage
[]
= { = "0.2", = false, = ["wrapper"] }
Then see Wrapper Usage
Use external libc (shim only)
As mentioned below, sqlite is now directly linked to emscripten's libc. But we provide the ability to customize libc.
Cargo provides a links
field that can be used to specify which library to link to.
We created a new sqlite-wasm-libc
library with no implementation and only a links = "libc"
configuration.
Then with the help of Overriding Build Scripts
, you can overriding its configuration in your crate and link sqlite to your custom libc.
More see custom-libc example
.
Multithreading
When target-feature=+atomics
is enabled, sqlite-wasm-rs
support multithreading, see multithread example
.
Shim VS Wrapper
Shim
Compile sqlite with -DSQLITE_OS_OTHER
, linking and implement the external functions required by sqlite
(malloc
, realloc
, sqlite3_os_init
etc..). And because the wasm32-unknown-unknown
target does not have libc
, string functions such as strcmp
need to be implemented. Finally, some web platform-specific functions need to be implemented, such as time-related functions.
Given that sqlite mainly supports emscripten, linking emscripten to wasm32-unknown-unknown
is the best approach (otherwise you need to implement some methods of libc
yourself). But here is a question, is wasm32-unknown-unknown
now C-ABI compatible?
The rustwasm team has done a lot of work and is now compatible with the -Zwasm-c-abi
compiler flag, see https://github.com/rustwasm/wasm-bindgen/issues/3454. But it doesn't mean that there will be problems if you don't use the -Zwasm-c-abi
flags, see https://github.com/rustwasm/wasm-bindgen/pull/2209. At least after testing, it works without -Zwasm-c-abi
.
Advantages
- No additional wrapper, providing the highest performance.
- The C interface does not require manual maintenance, just bindgen.
- No need to
init_sqlite()
before use.
Disadvantages
The only disvantage is that VFS needs to be implemented manually, but I have implemented two pure rust version of vfs:
memory-vfs
: as the default vfs, no additional conditions are required, just use.opfs-sahpool
: ported from sqlite-wasm, it provides the best performance persistent storage method.
Wrapper
Wrap the official sqlite-wasm
, and expect to provide a usable C-like API.
Advantages
- There are a variety of official persistent VFS implementations to choose from. (memvfs, opfs, opfs-sahpool, kvvfs).
Disadvantages
- Asynchronous initialization is required before using sqlite (because sqlite.wasm needs to be initialized), which is inconvenient to use.
- The C interface needs to be added manually, which is prone to errors.
- Interaction with
sqlite.wasm
requires memory copying and memory management, which affects performance in some scenarios.
Why vendor sqlite-wasm
- sqlite-wasm wrap some codes that are very convenient for JS, but difficult to use for rust.
- Some sqlite C-API are not exported.
Change history: https://github.com/Spxg/sqlite
Related Project
sqlite-wasm
: SQLite Wasm conveniently wrapped as an ES Module.sqlite-web-rs
: A SQLite WebAssembly backend for Diesel.rusqlite
: Ergonomic bindings to SQLite for Rust.