dbinspect_sqflite
A sqflite adapter for
dbinspect_bridge, so a desktop
client can browse your app's SQLite database while it runs.
import 'package:dbinspect_bridge/dbinspect_bridge.dart';
import 'package:dbinspect_sqflite/dbinspect_sqflite.dart';
await startBridge(
appName: 'example_app',
adapters: [
SqfliteAdapter(executor: db, id: 'app', displayName: 'app.db'),
],
);
Stores come from sqlite_master, schema from PRAGMA table_info, and paging
from LIMIT/OFFSET. Blobs are truncated at 64 KB.
Written against DatabaseExecutor from sqflite_common rather than sqflite
itself, which means it takes a Database or a Transaction, and that its tests
run against real SQLite with no device and no plugin channel.
Reading only, unless you say otherwise
sql and edit are false by default, so the adapter browses and pages and
does nothing else. Raw SQL is a separate opt-in:
SqfliteAdapter(executor: db, id: 'app', displayName: 'app.db',
allowRawQuery: true);
That opens SELECT, WITH … SELECT and EXPLAIN, and nothing else. Adding
allowWrite: true opens the row editor — insertRow, updateRow, deleteRow —
and in the SQL console also permits INSERT, UPDATE, DELETE and REPLACE;
ATTACH, DETACH, PRAGMA, VACUUM, extension loading, DDL and a second
statement after a ; are refused whatever you turn on. The gate is an
allow-list over a real tokenizer in dbinspect_bridge, not a keyword scan —
ATTACH DATABASE '/path' reads any file this process can read, and it is not an
UPDATE, a DELETE or a DROP.
A consequence worth knowing before you file it as a bug: a bare pragma,
vacuum, attach, detach or load_extension is refused anywhere in a
statement, so a column with one of those names must be quoted — "pragma",
[pragma] or `pragma` all work. A bound parameter is not a bare word, so
:pragma is fine.
watch is absent and always will be — sqflite has no change feed, and the
client offers labelled polling instead of pretending otherwise.
A row editor addresses a row by the table's single-column primary key, which
is the rowid when it is an INTEGER PRIMARY KEY. A table with no primary key, or
with a composite one, refuses updateRow and deleteRow and says which case it
is — a page is SELECT *, so a client has no rowid to send and any other
addressing would be a guess. insertRow needs no key and works on such a table.
Store, sort-column and edited-column names coming off the wire are checked against the list SQLite itself reports, never interpolated into a statement.
Licence
Apache-2.0.
Libraries
- dbinspect_sqflite
- A sqflite adapter for
dbinspect_bridge.