Conversation
simolus3
left a comment
There was a problem hiding this comment.
Thanks!
I used
sqlite3_db_statusinstead ofsqlite3_db_status64, since the 64-bit variant also only exists since 3.51.0 and would breaksource: systemwith older system libraries
I would actually prefer using the 64-bit function instead of truncating silently. Binding to a non-existing function only fails when that function is actually called, so this wouldn't break existing apps.
We can document this limitation on status.
WASM: native-only like
backup, since the web would need new exports from the WASM build.
I'm not sure we need releaseMemory() on the web, but having the status interface available on all platforms would be nice and I think we should do it in one PR.
Exporting new symbols works by adding them to unstable in wasm_symbols.dart and re-running generate_bindings.dart. But I can also take care of that once the native parts are done.
| /// Unlike `sqlite3_release_memory`, this works without SQLite being compiled | ||
| /// with `SQLITE_ENABLE_MEMORY_MANAGEMENT`. |
There was a problem hiding this comment.
Given that we have no bindings to that function, we shouldn't mention it in this documentation comment.
|
Thanks for the review! Pushed 3ba0474:
One thing I noticed: the |
Binds sqlite3_db_release_memory and sqlite3_db_status on native platforms. Unlike sqlite3_release_memory and the heap limits, both work with the default compile-time options (no SQLITE_ENABLE_MEMORY_MANAGEMENT, SQLITE_DEFAULT_MEMSTATUS=0).
Also document that tempBufferSpill requires SQLite 3.51.0, and that older libraries make Database.status throw for it.
Database.status becomes CommonDatabase.status, backed by a new RawSqliteDatabase.sqlite3_db_status64 binding on both FFI and WASM. Using the 64-bit function avoids silently truncating values. It requires SQLite 3.51.0, which is documented on status(); the binding only fails when called, so older system libraries keep working otherwise. On the web, sqlite3_db_status64 is added to the unstable WASM exports. Older sqlite3.wasm bundles without it throw an UnsupportedError. releaseMemory stays native-only. The status tests move to the common database tests so that they also run on the web.
3ba0474 to
569432d
Compare
|
Thanks for your contributions! I have merged this PR with minor changes in dc7facb. |
|
Is there an expected release date for a new version? I am eagerly looking forward to it for my app! |
|
I have just released version |
This adds two native-only methods to
Database, next tobackup:void releaseMemory()callssqlite3_db_release_memory, which frees unused pages from theconnection's page cache. This helps long-lived connections in memory-constrained apps, for
example after a large scan or when a mobile app goes to the background.
({int current, int highwater}) status(DatabaseStatus option, {bool reset = false})callssqlite3_db_status. The newDatabaseStatusenum mirrorsSQLITE_DBSTATUS_*(values 0 to 13,as of SQLite 3.53). Apps can use it to measure how much memory the cache, schema and statements
of a connection use, and to track cache hit/miss/spill counters.
Details:
sqlite3_db_statusdoesn't set an error message on the connection, so a non-OK result code isreported through
createExceptionOutsideOfDatabase. In practice this only happens forDatabaseStatus.tempBufferSpillon SQLite versions older than 3.51.0 (which is documented on theenum value).
sqlite3_db_statusinstead ofsqlite3_db_status64, since the 64-bit variant also onlyexists since 3.51.0 and would break
source: systemwith older system libraries.Linux symbols
The Linux builds link with a version script generated from
used_symbols.dart(seehook/build.dart), so only those symbols are exported. The released 3.6.0libsqlite3.x64.linux.sotherefore doesn't exportsqlite3_db_statusorsqlite3_db_release_memory.I added both functions to
assets/sqlite3.hand regeneratedlibsqlite3.g.dartandused_symbols.dartwithtool/generate_bindings.dart. Rerunning the tool gives no further diff.tool/build_sqlite.dartruns the same build hook, and thecompile_sqlite.ymlcache key includessqlite3/lib/src/hook/compile/**. So the next prebuilt release exports both symbols, and this PR'sCI already tests them on Linux against freshly compiled libraries. Because
asset_hashes.darttieseach package version to the binaries from its own release, a published version with this API
won't download binaries that lack the symbols. No additional change is needed.
Not included
sqlite3_interrupt/sqlite3_is_interrupted: covered by feat: Add native bindings forsqlite3_interruptandsqlite3_is_interrupted#404.sqlite3_release_memory,sqlite3_soft_heap_limit64andsqlite3_hard_heap_limit64: with theprebuilt compile-time options these would be no-ops, so exposing them would be misleading.
sqlite3_release_memoryneedsSQLITE_ENABLE_MEMORY_MANAGEMENT, and the heap limits are onlyenforced with memory statistics, which
SQLITE_DEFAULT_MEMSTATUS=0turns off. Thedb_*variants work regardless.
backup, since the web would need new exports from the WASM build. I canadd that in a follow-up if you'd like.
Tests
New tests in
test/ffi/database_test.dartuse a file database with about 400 KB of blobs. Theycheck that
cacheUsedreflects the cache, thatreset: trueclearscacheHit, thatreleaseMemory()shrinkscacheUsedby more than 10x while the connection keeps working, and thatthe bundled SQLite accepts every
DatabaseStatusvalue (taggedrequire_built, so older systemlibraries skip it).
dart analyze --fatal-infos,dart format --set-exit-if-changedandclang-format --style=googleonassets/*.h: clean.dart testinsqlite3(VM, Windows): 195 passed, 5 skipped.dart test -P systemwithtool/hook_overrides.dart system-os-specific(winsqlite3 3.51.1):188 passed, 12 skipped.
dart testinsqlite3_connection_pool: 28 passed.dart run run.dartinnative_tests(AOT): 180 passed, 5 skipped.The CHANGELOG entry is under
3.6.1-wip. Since this adds API toDatabase, feel free to move it toa minor version.
🤖 Generated with Claude Code