Skip to content

refactor: add SQLite adapter to decouple from bun:sqlite#968

Closed
BYK wants to merge 1 commit into
chore/switch-to-pnpmfrom
refactor/sqlite-adapter
Closed

refactor: add SQLite adapter to decouple from bun:sqlite#968
BYK wants to merge 1 commit into
chore/switch-to-pnpmfrom
refactor/sqlite-adapter

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented May 15, 2026

Summary

Second step of the Bun → Node.js migration. Introduces a SQLite adapter layer that decouples the codebase from direct bun:sqlite imports, making the database layer portable across runtimes.

Depends on: #967 (pnpm switch)

Changes

  • New: src/lib/db/sqlite.ts — runtime-detecting adapter
    • Under Bun: re-exports bun:sqlite's Database directly (zero overhead)
    • Under Node.js: wraps node:sqlite's DatabaseSync with the same .query() / .exec() / .close() / .transaction() API
    • Exports SQLQueryBindings type for parameter binding
  • Updated imports in 4 source files: db/index.ts, schema.ts, migration.ts, utils.ts
  • Updated imports in 3 test files: fix.test.ts, telemetry.test.ts, schema.test.ts
  • Added: MIGRATION-PLAN.md documenting remaining migration steps

Design

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() and db.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:sqlite imports remain in src/ or test/.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-968/

Built to branch gh-pages at 2026-05-15 16:24 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Comment thread src/lib/db/sqlite.ts
return this.stmt.get(...params) as
| Record<string, SQLQueryBindings>
| undefined;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f6160a2. Configure here.

@BYK BYK force-pushed the chore/switch-to-pnpm branch from 004a3b2 to 124766a Compare May 15, 2026 15:05
@BYK BYK force-pushed the refactor/sqlite-adapter branch from f6160a2 to d52bacb Compare May 15, 2026 15:05
@BYK BYK force-pushed the chore/switch-to-pnpm branch from 124766a to 919d9f3 Compare May 15, 2026 15:13
@BYK BYK force-pushed the refactor/sqlite-adapter branch 2 times, most recently from 2e5f89d to 50c3f3f Compare May 15, 2026 15:16
@BYK BYK force-pushed the chore/switch-to-pnpm branch from 919d9f3 to 0c43a41 Compare May 15, 2026 15:17
@BYK BYK force-pushed the refactor/sqlite-adapter branch 2 times, most recently from ef0f238 to 61d0ddb Compare May 15, 2026 15:23
@BYK BYK force-pushed the chore/switch-to-pnpm branch from 0c43a41 to ba2f136 Compare May 15, 2026 15:24
@BYK BYK force-pushed the refactor/sqlite-adapter branch from 61d0ddb to ae19a55 Compare May 15, 2026 15:24
Comment thread src/lib/db/schema.ts
Comment on lines 11 to 17
* - 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";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@BYK BYK force-pushed the chore/switch-to-pnpm branch 2 times, most recently from 31af6ff to 0e57afd Compare May 15, 2026 15:46
@BYK BYK force-pushed the refactor/sqlite-adapter branch from ae19a55 to 3986387 Compare May 15, 2026 15:46
@BYK BYK force-pushed the chore/switch-to-pnpm branch from 0e57afd to 0ed7979 Compare May 15, 2026 15:52
@BYK BYK force-pushed the refactor/sqlite-adapter branch from 3986387 to 574771e Compare May 15, 2026 15:52
@BYK BYK force-pushed the chore/switch-to-pnpm branch 3 times, most recently from b1acf35 to c2d8d09 Compare May 15, 2026 16:15
@BYK BYK force-pushed the refactor/sqlite-adapter branch from 574771e to 2c1fc71 Compare May 15, 2026 16:15
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

Codecov Results 📊

6969 passed | Total: 6969 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

❌ Patch coverage is 45.24%. Project has 14127 uncovered lines.
✅ Project coverage is 77.07%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
src/lib/db/sqlite.ts 43.90% ⚠️ 23 Missing
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

@BYK BYK force-pushed the refactor/sqlite-adapter branch from 2c1fc71 to 9f63f37 Compare May 15, 2026 16:23
@BYK BYK force-pushed the chore/switch-to-pnpm branch from c2d8d09 to 414cd3a Compare May 15, 2026 16:23
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
@BYK BYK force-pushed the refactor/sqlite-adapter branch from 9f63f37 to 298f436 Compare May 15, 2026 16:24
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ 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.

Comment thread src/lib/db/sqlite.ts
throw error;
}
};
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 298f436. Configure here.

@BYK BYK deleted the branch chore/switch-to-pnpm May 15, 2026 17:50
@BYK BYK closed this May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant