dbinspect_drift 0.1.0
dbinspect_drift: ^0.1.0 copied to clipboard
A Drift adapter for dbinspect_bridge, so a desktop client can browse your app's Drift database while it runs.
dbinspect_drift #
A Drift adapter for
dbinspect_bridge, so a desktop
client can browse your app's database while it runs.
import 'package:dbinspect_bridge/dbinspect_bridge.dart';
import 'package:dbinspect_drift/dbinspect_drift.dart';
await startBridge(
appName: 'example_app',
adapters: [
DriftAdapter(database: db, id: 'app', displayName: 'app.db'),
],
);
Stores come from allTables, the schema from the generated $columns, and
paging from LIMIT/OFFSET through customSelect. Blobs are truncated at
64 KB.
What this gives you that opening the file does not #
A Drift database is a SQLite file, and a client can open one directly with no help from your app. Three things only exist while your application is running, and they are the reason this adapter exists:
- the declared schema —
inferred: false, compiled in from your Dart table classes rather than read back fromPRAGMA table_info; - Drift's type mapping — a
DateTimeColumnis aninton disk and a date here, aBoolColumnis0/1on disk and a boolean here; - the change feed, with the honest caveat below.
Column names on the wire are the SQL names drift generated, not the Dart
ones: joinedAt in your table class is joined_at here, in sortBy, in
values and in every row.
Watching is in-process only, and the client is told so #
capabilities.watch is true and watchScope is "in-process".
tableUpdates() is an in-process event bus fed by notifyUpdates, not a
database trigger. It reports writes made through this Drift instance and
nothing else — a second isolate, another process, or a native writer produces no
event at all. The client labels the toggle Live (this app's writes only)
rather than Live, because the developer debugging exactly that cross-process
case is the one an unqualified badge would mislead.
There is a test for the limit itself: two Drift instances over one SQLite handle, a write through the second, and no event on the first.
Writes made through the bridge do fire it — customInsert and customUpdate
are called with updates:, so the bridge is not the one writer tableUpdates
never reports.
Events are tableChanged: a Set<TableUpdate> is per table, not per row, and
flattening it into insert would be inventing information the bus does not
carry.
Reading only, unless you say otherwise #
sql and edit are false by default, so the adapter browses and pages and
does nothing else.
DriftAdapter(database: db, id: 'app', displayName: 'app.db',
allowRawQuery: true, allowWrite: true);
allowRawQuery opens SELECT, WITH … SELECT and EXPLAIN. allowWrite
opens the row editor and, in the console, INSERT/UPDATE/DELETE/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.
Row identity is the table's single-column primary key. A table with no primary
key, or with a composite one, refuses updateRow and deleteRow naming which
case it is; insertRow still works on both.
Drift version floor, measured #
| Version | How it was established | |
|---|---|---|
| Analyzes clean from | 2.12.0 | dart analyze lib against 2.12.0, 2.16.0, 2.20.0 and 2.34.3, all clean. Below 2.12 drift's own sqlite3 constraint moves and the package stops resolving at all. |
| Suite runs green at | 2.34.3 | dart test, 2026-08-08 |
The two numbers differ for one reason worth knowing: test/fixture_database.g.dart
is generated code, and drift's generated output is shaped by the version that
produced it — the committed fixture does not compile on 2.20. That is drift's
compatibility story for generated code, not a limit of this adapter, and it is
why the tested floor cannot simply be lowered to the analyzed one.
drift_dev and build_runner are deliberately not dev dependencies here; see
the note in pubspec.yaml for how to regenerate the fixture.
Licence #
Apache-2.0.