Skip to content

Commit 1b9c058

Browse files
tianzhouclaude
andauthored
feat: migrate SQLite connector to built-in node:sqlite (#317) (#330)
* feat: migrate SQLite connector to built-in node:sqlite (#317) Replace better-sqlite3 with Node's built-in node:sqlite module, eliminating native C++ compilation (node-gyp) and prebuild friction. SQLite now needs no driver package and is always available. API mapping: - new Database(path, {readonly}) -> new DatabaseSync(path, {readOnly}) - db.defaultSafeIntegers(true) -> stmt.setReadBigInts(true) (per-statement, centralized in a private prepare() helper) - db.inTransaction -> db.isTransaction Behavior preserved vs better-sqlite3: - run() returns BigInt `changes` with setReadBigInts; normalized via Number() - foreign keys default off (enableForeignKeyConstraints: false) Build/runtime gotchas fixed: - tsup removeNodeProtocol stripped `node:sqlite` -> `sqlite` (unresolvable); set removeNodeProtocol: false - node:sqlite emits ExperimentalWarning at load time; install a targeted warning filter (suppress-experimental-warning.ts) before loading node:sqlite, and load it via a non-hoisted lazy dynamic import() inside connect() Other: - drop better-sqlite3 / @types/better-sqlite3; bump engines.node to >=22.5.0 - CI run-tests Node 20 -> 22; update install/quickstart docs - remove better-sqlite3 native-build approvals from pnpm-workspace.yaml BREAKING CHANGE: requires Node.js >= 22.5.0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: consolidate SQLite introspection queries behind typed helpers Schema introspection reads small integer flags (notnull, pk, unique) that must be plain numbers for `=== 1` / `> 0` comparisons to work, while executeSQL needs BigInt to preserve 64-bit user-data precision. The migration left this split implicit and inconsistent: some methods used this.prepare() (BigInt) and others this.db.prepare() (number), and getTableSchema was on the wrong side — its `notnull === 1` check silently failed against BigInt. - Add private queryAll<T>/queryOne<T> helpers for introspection (plain numbers, centralizing the repeated `as unknown as X` casts and the not-connected guard) - Route all introspection (getTables, getViews, tableExists, getTableIndexes, getTableSchema) through them; getTableSchema now compares plain numbers - Keep prepare() (BigInt) for executeSQL only, with a clarified doc comment No behavior change for covered cases; corrects the latent NOT NULL detection for non-PK columns in getTableSchema. All SQLite tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: state Node.js >= 22.5.0 requirement for the npm method The engine floor now applies to running DBHub via npm/npx (node:sqlite), not just SQLite. Note it in the README quick-start and dev sections, and add a callout in installation.mdx clarifying Docker users don't need local Node. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: install node:sqlite warning hook lazily, not at startup The experimental-warning suppression was a top-level side-effect import, so loadConnectors patched process.emitWarning globally at every startup — even for instances that never use SQLite. Now that node:sqlite is loaded lazily inside connect(), the hook can be too: convert the suppress module to an idempotent function and call it right before the dynamic import. Non-SQLite processes no longer touch process.emitWarning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3d68763 commit 1b9c058

12 files changed

Lines changed: 157 additions & 242 deletions

File tree

.github/workflows/run-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Setup Node.js
2727
uses: actions/setup-node@v3
2828
with:
29-
node-version: '20'
29+
node-version: '22'
3030
cache: 'pnpm'
3131

3232
- name: Get pnpm store directory
@@ -71,7 +71,7 @@ jobs:
7171
- name: Setup Node.js
7272
uses: actions/setup-node@v3
7373
with:
74-
node-version: '20'
74+
node-version: '22'
7575
cache: 'pnpm'
7676

7777
- name: Get pnpm store directory

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ docker run --rm --init \
7474
--dsn "postgres://user:password@localhost:5432/dbname?sslmode=disable"
7575
```
7676

77-
**NPM:**
77+
**NPM:** (requires Node.js >= 22.5.0)
7878

7979
```bash
8080
npx @bytebase/dbhub@latest --transport http --port 8080 --dsn "postgres://user:password@localhost:5432/dbname?sslmode=disable"
@@ -104,6 +104,8 @@ See [Multi-Database Configuration](https://dbhub.ai/config/toml) for complete se
104104

105105
## Development
106106

107+
Requires Node.js >= 22.5.0 (DBHub uses the built-in `node:sqlite` module).
108+
107109
```bash
108110
# Install dependencies
109111
pnpm install

docs/installation.mdx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ title: "Installation"
44

55
## npm
66

7+
<Note>
8+
The npm method requires **Node.js >= 22.5.0** (DBHub uses Node's built-in `node:sqlite` module). The Docker image bundles a compatible Node runtime, so no local Node install is needed when running via Docker.
9+
</Note>
10+
711
<Tabs>
812
<Tab title="npx">
913
```bash
@@ -51,10 +55,11 @@ Available driver packages:
5155
- `mysql2` — MySQL
5256
- `mariadb` — MariaDB
5357
- `mssql` — SQL Server
54-
- `better-sqlite3` — SQLite
58+
59+
SQLite uses the built-in `node:sqlite` module (Node.js 22.5+), so it requires no driver package or native compilation and is always available.
5560

5661
<Note>
57-
When a driver is not installed or a required dependency is missing (e.g., a transitive dependency like `@azure/core-client` for the SQL Server driver), DBHub will skip that connector at startup and log a message. All other connectors will work normally. Note that `--demo` mode requires the `better-sqlite3` driver.
62+
When a driver is not installed or a required dependency is missing (e.g., a transitive dependency like `@azure/core-client` for the SQL Server driver), DBHub will skip that connector at startup and log a message. All other connectors will work normally. SQLite (including `--demo` mode) needs no extra driver — it relies on the built-in `node:sqlite` module.
5863
</Note>
5964

6065
## Docker

docs/quickstart.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This guide will walk you through setting up DBHub and connecting it to an AI too
77
## Prerequisites
88

99
Before starting, ensure you have:
10-
- Node.js 20+ installed (for NPM method) **OR** Docker installed
10+
- Node.js 22.5+ installed (for NPM method) **OR** Docker installed
1111
- Access to an AI tool (Claude Desktop, Claude Code, Cursor, or VS Code)
1212
- Optionally: A PostgreSQL, MySQL, or other supported database
1313

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"test:build": "node scripts/smoke-test-build.mjs"
3535
},
3636
"engines": {
37-
"node": ">=20"
37+
"node": ">=22.5.0"
3838
},
3939
"keywords": [],
4040
"author": "",
@@ -51,7 +51,6 @@
5151
"optionalDependencies": {
5252
"@aws-sdk/rds-signer": "^3.1001.0",
5353
"@azure/identity": "^4.8.0",
54-
"better-sqlite3": "^11.9.0",
5554
"mariadb": "^3.4.0",
5655
"mssql": "^11.0.1",
5756
"mysql2": "^3.13.0",
@@ -62,7 +61,6 @@
6261
"@testcontainers/mssqlserver": "^11.0.3",
6362
"@testcontainers/mysql": "^11.0.3",
6463
"@testcontainers/postgresql": "^11.0.3",
65-
"@types/better-sqlite3": "^7.6.12",
6664
"@types/express": "^4.17.21",
6765
"@types/mssql": "^9.1.7",
6866
"@types/node": "^22.13.10",

0 commit comments

Comments
 (0)