Skip to content

feat(knex-schema): define queries before binding a connection - #242

Merged
andrewzolotukhin merged 1 commit into
developmentfrom
feat/connection-independent-queries
Oct 3, 2026
Merged

andrewzolotukhin merged 1 commit into
developmentfrom
feat/connection-independent-queries

Conversation

@andrewzolotukhin

@andrewzolotukhin andrewzolotukhin commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add connection-independent query definitions so reads can be defined once in a data module and receive an injected Knex connection or transaction at execution.

// data/user-queries.ts
export const findUser = query(UserSchema)
    .where(user => user.id, parameter('id'));

// A separately defined handler supplies its injected connection.
const users = await findUser(knex, userId);
const user = await findUser.query(knex, userId).first();
const { sql, bindings } = findUser.toSQL(knex, userId);

await findUser.query(trx, userId).update({ name: 'Updated' });

Parameterless definitions use the same API: query(UserSchema)(knex) or .query(knex).

Behavior and implementation

  • Definitions are immutable and non-thenable. Row schemas and variant metadata are available before binding; construction does not instantiate a Knex client.
  • Capture a connection-independent SQL operation graph. Selectors, scopes, predicate groups and relation/variant customizers run during definition, not again during connection binding or execution.
  • Preserve positional parameter inference, projection types, nested includes, aliases/joins, aggregates and STI/CTI variants through the existing typed builders.
  • Cache compiled PostgreSQL SELECTs per immutable definition and actual Knex instance using weak references. Bind fresh values for every invocation; no result caching or implicit connection/transaction ownership.
  • .query(knex, ...values) returns an independent ordinary reader. Bind before pagination, permitted writes, native subqueries, ref(), apply() or raw projections. Native escape hatches expose real Knex snapshots, including normal listener semantics.
  • Keep query(knex, Schema), createQuery(knex) and connection-bound ORM DbSet APIs supported. Standalone reads remain detached from ORM identity tracking.
  • Keep ordinary connection-bound type resolution fast and derive ORM row metadata directly, avoiding recursive expansion of the complete fluent API in generic context factories.

Documentation and release

  • Public JSDoc and package READMEs, including separate data-module/controller examples and a contract-typed HTTP handler.
  • Documentation-site examples and explicit cache/transaction/escape-hatch semantics.
  • Minor changeset for @cleverbrush/knex-schema and @cleverbrush/orm; existing release grouping and pending changesets are unchanged.
  • No database migration, package publishing or deployment is performed by this PR.

Validation

  • npm run lint
  • npm run build
  • npm run test: 4,759 passing tests across 241 files; no type errors
  • npm run typecheck:schema-site
  • npm run typecheck:docs-site
  • Full PostgreSQL query integration suite: 100 tests passed in both UTC and America/Los_Angeles, including connection-independent definitions, concurrent calls, separate clients, transaction visibility/rollback, writes, offset/cursor pagination, native composition, scopes, relations, joins/aggregates and STI/CTI variants.

Capability-named regression tests cover metadata without a connection, callback capture, inference, invalid arguments, immutable values, compilation reuse/isolation and native SQL escape hatches.

GitHub CI passed on cb5d6222: lint/build/tests and both site typechecks, PostgreSQL query/scheduler integration and durable-job demos, and S3 storage integration.

@andrewzolotukhin
andrewzolotukhin merged commit 6c8498e into development Oct 3, 2026
3 checks passed
@andrewzolotukhin
andrewzolotukhin deleted the feat/connection-independent-queries branch October 3, 2026 17:57
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