8000 feat: run queries on a knex instance or transaction by colinhacks · Pull Request #233 · colinhacks/reylo · GitHub
[go: up one dir, main page]

Skip to content

feat: run queries on a knex instance or transaction - #233

Merged
colinhacks merged 6 commits into
mainfrom
knex-client
Nov 11, 2026
Merged

colinhacks merged 6 commits into
mainfrom
knex-client

Conversation

@colinhacks
Copy link
Copy Markdown
Owner

Closes #1

A Knex instance, transaction or savepoint can now be passed to .run(), .try() and .with(). Reylo takes one of the driver connections Knex holds, runs its compiled statement on it as it would on that driver directly, and hands the connection back. Inside a transaction it runs on the transaction's own connection. Knex's query builder is not involved, so values, nullability and cardinality behave as on the driver itself.

import knex from "knex";
import getUser from "./get_user.sql";

const db = knex({ client: "pg", connection: process.env.DATABASE_URL });
const user = await getUser.run(db, { id: 1 });

await db.transaction(async (trx) => {
  await getUser.run(trx, { id: 1 });
});
  • Works over pg, mysql2, mariadb, better-sqlite3 and sqlite3.
  • Knex's types don't say which database an instance is for, so a statement for another database is refused when it runs.
  • A transaction that has already committed or rolled back is refused, as Knex refuses it.
  • .runSync() takes no Knex instance, since Knex hands out connections through a promise.

Before this, a Knex instance, which is a function, was taken for Neon's neon() and called, so Postgres answered with "relation does not exist".

The tests run each driver through Knex against a live database, with knex added to lab/drivers. The docs gain a Knex tab in each driver list and a Knex section on each dialect page, and the README and the skill list it.

A Knex instance, transaction or savepoint passes as the client of .run(): the statement runs on the connection Knex hands out, over pg, mysql2, mariadb, better-sqlite3 or sqlite3, and the values decode as on that driver. A Knex instance is a function, so it was taken for Neon's neon() and called, which built a select from a table named by the statement.
Copilot AI balanced review requested due to automatic review settings November 11, 2026 03:58
@vercel
vercel Bot commented Nov 11, 2026 •
Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
reylo Ready Ready Preview Nov 11, 2026 4:13am UTC

Request Review

Copilot AI left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@pullfrog pullfrog Bot left a comment
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.

ℹ️ No critical issues. One rough edge inline: two of the Knex drivers listed don't actually run correctly.

Reviewed changes

Reviewed the Knex support in src/execute.ts, its live tests and the docs, README and skill updates.

  • Knex detection: isKnex recognizes a callable instance, transaction or savepoint by raw, transaction and client.acquireConnection/releaseConnection. It runs before every other client check, so a Knex instance is no longer taken for Neon's neon().
  • Running on a Knex connection: onKnexConnection refuses a statement for another database (using client.driverName) and refuses a transaction that has already finished. Otherwise it acquires a connection, runs the statement on the raw driver connection and releases the connection in finally. I checked this against knex 3.3.0's makeTxClient: inside a transaction, acquire returns the transaction's own connection and release does nothing.
  • Types: KnexClient is added to the Postgres, MySQL and SQLite client unions but not to SyncClientFor, so .runSync() rejects a Knex instance both at compile time and at run time.
  • Tests: live tests in tests/execute.test.ts cover better-sqlite3, sqlite3, pg, mysql2 and mariadb. They check pool usage, a rollback that undoes Reylo's writes, savepoints, a finished transaction and a dialect mismatch. knex is added to lab/drivers.
  • Docs: each driver list in 02-usage.mdx gets a Knex tab, and each dialect page gets a ### Knex section. The README and the skill mention Knex.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread src/execute.ts Resolved
@pullfrog pullfrog Bot left a comment
Copy link
8000 Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ No new bugs. The fixes are correct. One small docs gap: the new pg.native refusal isn't documented yet.

Reviewed changes

This review covers the two commits since the last review. Both act on the earlier feedback about Knex drivers that Reylo cannot read.

  • Knex driver allowlist: knexDrivers now lists only pg, mysql2, mariadb, better-sqlite3 and sqlite3. Any other driverName, such as pgnative, mysql or cockroachdb, is refused before a connection is acquired. A stubbed test covers this.
  • pg.native refused everywhere: isPgNative in src/decode.ts catches pg's native Client and PoolClient through their native binding. It catches a pool of them through Client.prototype._hasActiveQuery. I checked pg's sources: only lib/native/client.js defines either of these, and lib/client.js has neither, so pg's JavaScript Client, Neon's and @vercel/postgres's are not affected. pg-promise with pgNative: true is refused as well. A stubbed test covers all three.

ℹ️ The new pg.native refusal is missing from the driver docs

This refusal applies to every pg and pg-promise user, not only to Knex. An app that ran on pg.native used to get values decoded the wrong way and now gets an error. The dialect page already lists what isn't supported for each driver, such as binary: true for pg and a rewriting receive for pg-promise, but the native client isn't on that list. The rspack example also still describes using pg.native.

Technical details
# Document the pg.native refusal

## Affected sites
- site/content/docs/postgres.mdx:1217 — the `### pg` section lists `binary: true` as unsupported, but not `pg.native`
- site/content/docs/postgres.mdx:1261 — the `### pg-promise` section lists `receive`, but not `pgNative: true`
- examples/rspack/README.md:53 — says an app using `pg.native` installs `pg-native` and lists it in `externals`, but Reylo now refuses that client

## Required outcome
- The `pg` and `pg-promise` sections say that pg's native client (`pg.native`, or pg-promise's `pgNative: true`) isn't supported, in the same brief style as the existing `binary: true` line
- The rspack note no longer suggests a setup that Reylo refuses, or it says Reylo refuses that setup

Pullfrog  | Fix it ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

@colinhacks
Copy link
Copy Markdown
Owner Author

Docs gap on pg's native client fixed in 9bbb5a9. The pg and pg-promise sections now list it as unsupported, and the rspack note no longer suggests bundling it.

@pullfrog pullfrog Bot left a comment
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.

✅ No new issues found. The docs gap from the last review is fixed.

Reviewed changes

This review covers the one docs commit since the last review. It documents the pg.native refusal.

  • pg section: the Postgres page now says pg's native client, pg.native, isn't supported, next to the existing binary: true line, and says why: it ignores the type parsers a query passes.
  • pg-promise section: the page now says a database initialized with pgNative: true isn't supported either.
  • Rspack example: the note no longer suggests installing pg-native for pg.native. It now says Reylo refuses pg's native client.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@colinhacks
colinhacks merged commit b3a7f87 into main Nov 11, 2026
10 checks passed
@colinhacks
colinhacks deleted the knex-client branch November 11, 2026 04:16
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.

[question] Can I use this with knex.raw? Could you provide an example?

2 participants

0