refactor: add SQLite adapter to decouple from bun:sqlite#968
Conversation
|
| return this.stmt.get(...params) as | ||
| | Record<string, SQLQueryBindings> | ||
| | undefined; | ||
| } |
There was a problem hiding this comment.
Adapter get() returns undefined vs null across runtimes
Medium Severity
The adapter's goal is a "unified API surface," but NodeStatementWrapper.get() passes through node:sqlite's return value of undefined for no-row-found, while under Bun the re-exported bun:sqlite Statement.get() returns null. This means .get() has different no-match semantics depending on which runtime is active. The current codebase happens to use ??, ?., and truthiness checks that tolerate both, but any future code using === null would silently break under Node.js. Normalizing the return (e.g., ?? null or converting null to undefined) would make the adapter truly portable.
Reviewed by Cursor Bugbot for commit f6160a2. Configure here.
f6160a2 to
d52bacb
Compare
2e5f89d to
50c3f3f
Compare
ef0f238 to
61d0ddb
Compare
61d0ddb to
ae19a55
Compare
| * - Migration checks | ||
| */ | ||
|
|
||
| import type { Database } from "bun:sqlite"; | ||
| import type { Database } from "./sqlite.js"; | ||
| import { getEnv } from "../env.js"; | ||
| import { stringifyUnknown } from "../errors.js"; | ||
| import { logger } from "../logger.js"; |
There was a problem hiding this comment.
Bug: The check for error.name === "SQLiteError" may fail for errors from node:sqlite, silently disabling database error handling and auto-repair for Node.js users.
Severity: HIGH
Suggested Fix
Instead of checking error.name, consider checking a more reliable property on the error object from node:sqlite, such as error.code. Alternatively, wrap errors from node:sqlite in a custom error class that correctly sets the name property to "SQLiteError" before they are processed by the error handling logic.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: src/lib/db/schema.ts#L11-L17
Potential issue: The `isSchemaError` and `isReadonlyError` functions check if
`error.name === "SQLiteError"` to identify specific database issues. However, errors
originating from the `node:sqlite` library may not have this `name` property. Standard
JavaScript Error subclasses require the `name` property to be set explicitly. If
`node:sqlite`'s native `SQLiteError` does not do this, these checks will consistently
fail for users on Node.js. This will silently disable critical error handling logic,
such as the database auto-repair mechanism used in `tryRepairAndRetry`.
Did we get this right? 👍 / 👎 to inform future reviews.
31af6ff to
0e57afd
Compare
ae19a55 to
3986387
Compare
3986387 to
574771e
Compare
b1acf35 to
c2d8d09
Compare
574771e to
2c1fc71
Compare
Codecov Results 📊✅ 6969 passed | Total: 6969 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
✨ No test changes detected All tests are passing successfully. ❌ Patch coverage is 45.24%. Project has 14127 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 77.06% 77.07% +0.01%
==========================================
Files 320 321 +1
Lines 61608 61611 +3
Branches 0 0 —
==========================================
+ Hits 47475 47484 +9
- Misses 14133 14127 -6
- Partials 0 0 —Generated by Codecov Action |
2c1fc71 to
9f63f37
Compare
Introduce src/lib/db/sqlite.ts — a runtime-detecting adapter that provides a unified Database API for SQLite access. Under Bun it re-exports bun:sqlite directly (zero overhead). Under Node.js it wraps node:sqlite's DatabaseSync with the same .query()/.exec()/ .close()/.transaction() interface. This eliminates all direct bun:sqlite imports from src/ and test/, making the DB layer portable across runtimes without changing any call sites. Changes: - New: src/lib/db/sqlite.ts (adapter with runtime detection) - Updated: db/index.ts, schema.ts, migration.ts, utils.ts imports - Updated: 3 test files to import from adapter - Added: MIGRATION-PLAN.md documenting remaining migration steps
9f63f37 to
298f436
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 298f436. Configure here.
| throw error; | ||
| } | ||
| }; | ||
| } |
There was a problem hiding this comment.
transaction() doesn't forward arguments to callback
Low Severity
bun:sqlite's transaction() signature is (fn: (...args: A) => T): (...args: A) => T, forwarding arguments from the returned wrapper to the inner callback. The NodeDatabase.transaction() uses (fn: () => T): () => T, discarding any arguments. All current call sites use zero-argument callbacks so this doesn't break today, but it makes the adapter incompatible with the full bun:sqlite transaction API.
Reviewed by Cursor Bugbot for commit 298f436. Configure here.


Summary
Second step of the Bun → Node.js migration. Introduces a SQLite adapter layer that decouples the codebase from direct
bun:sqliteimports, making the database layer portable across runtimes.Changes
src/lib/db/sqlite.ts— runtime-detecting adapterbun:sqlite'sDatabasedirectly (zero overhead)node:sqlite'sDatabaseSyncwith the same.query()/.exec()/.close()/.transaction()APISQLQueryBindingstype for parameter bindingdb/index.ts,schema.ts,migration.ts,utils.tsfix.test.ts,telemetry.test.ts,schema.test.tsMIGRATION-PLAN.mddocumenting remaining migration stepsDesign
The adapter uses runtime detection (
typeof globalThis.Bun !== "undefined") to pick the right implementation at module load time. No call sites need to change — they continue using.query(sql).get()/.all()/.run()anddb.transaction()exactly as before.Test results
All 261 DB tests pass. Full suite: 6968 pass, 1 fail (same pre-existing pnpm issue from #967).
Zero
bun:sqliteimports remain insrc/ortest/.