knex-firebird-adapter
v1.0.3
Published
Firebird adapter for Knex.js
Maintainers
Readme
👾 knex-firebird-adapter
Note: This is a fork of https://codecov.io/gh/Tomas2D/knex-firebird-dialect/.
This library provides a Firebird dialect (client) for Knex.js, a SQL query builder.
It continues the work of previous, unmaintained libraries and is based on igorklopov/firebird-knex.
Under the hood it can use the node-firebird-driver-native driver. If that driver is not suitable for your environment, consider using a compatible 1.x release of this package which works with the older node-firebird driver.
If you find this fork useful, a ⭐️ is appreciated.
Installation
Install from npm if published, or use one of the local installation methods shown below for development.
🚀 Usage
Basic setup example (ESM):
import knexLib from "knex";
import knexFirebirdAdapter from "knex-firebird-adapter"; // or your local package name
const knex = knexLib({
client: knexFirebirdAdapter, // required – always pass the adapter class here
connection: {
host: "127.0.0.1",
port: 3050,
user: "SYSDBA",
password: "masterkey",
database: '/tmp/database.fdb',
},
createDatabaseIfNotExists: true,
debug: false,
});
export default knex;CommonJS example (require):
const knexLib = require('knex');
const knexFirebirdAdapter = require('knex-firebird-adapter').default;
const knex = knexLib({ client: knexFirebirdAdapter, connection: {/*...*/} });Important: The
clientoption is required. Omitting it will throwRequired configuration option 'client' is missing.
Identifier case sensitivity
All identifiers (table and column names) are wrapped in double quotes by this adapter. Firebird therefore treats them as case-sensitive.
Schema builder (lowercase by default)
The schema compiler lowercases every identifier before quoting it. Identifiers passed to the schema builder are always stored in lowercase, regardless of the casing you provide:
await knex.schema.createTable("my_table", (table) => {
table.string("lower_col");
table.string("MixedCase"); // stored as "mixedcase"
});
await knex.schema.hasColumn("my_table", "lower_col"); // true
await knex.schema.hasColumn("my_table", "MixedCase"); // false – stored as "mixedcase"
await knex.schema.hasColumn("my_table", "mixedcase"); // truePreserve exact casing with wrapIdentifier
To keep the original casing (e.g. tblFooBar, myField), pass a
wrapIdentifier function in the knex config. It receives the raw identifier
value and must return the final quoted string.
const knex = knexLib({
client: knexFirebirdAdapter,
connection: { /* ... */ },
// Skip lowercasing – wrap the value as-is in double quotes
wrapIdentifier: (value, origWrap) => origWrap(value),
});With this config, identifiers keep their original casing and the schema builder no longer lowercases them:
await knex.schema.createTable("tblFooBar", (table) => {
table.increments("id");
table.string("myField", 100);
});
// Exact casing is required for every access
await knex.schema.hasTable("tblFooBar"); // true
await knex.schema.hasTable("tblfoobar"); // false
await knex.schema.hasColumn("tblFooBar", "myField"); // true
await knex.schema.hasColumn("tblFooBar", "myfield"); // false
await knex("tblFooBar").insert({ id: 1, myField: "hello" });
const rows = await knex("tblFooBar").select("myField");
// rows[0].myField === "hello" (or rows[0].myfield with lowercase_keys: true)Note: When
lowercase_keys: trueis set in the connection config, Firebird returns column names in lowercase regardless of their stored casing. Uselowercase_keys: falseif you need the original casing in query results.
Mixed-case identifiers via raw SQL
Alternatively, create mixed-case objects with knex.raw() using explicit
double quotes — without needing to configure wrapIdentifier:
await knex.raw(`CREATE TABLE "tblFooBar" ("myField" VARCHAR(100))`);Transactions
For a general introduction to the Knex transaction API see the Knex transaction documentation. The section below describes Firebird-specific behaviour and the supported isolation levels.
Transactions are started with knex.transaction(fn, options). Pass the callback as the first argument and the options object — including isolationLevel — as the second.
await knex.transaction(
async (trx) => {
await knex("orders").transacting(trx).insert({ amount: 100 });
},
{ isolationLevel: "snapshot" },
);Isolation levels
The following Knex isolation level strings are supported. They map to Firebird's native transaction parameters as shown below.
| Knex isolationLevel | Firebird level | Notes |
|---|---|---|
| (not set) | SNAPSHOT | Firebird default |
| "snapshot" | SNAPSHOT | MVCC snapshot, no dirty/non-repeatable reads |
| "repeatable read" | SNAPSHOT | Closest Firebird equivalent |
| "read committed" | READ COMMITTED | Sees committed changes from concurrent transactions |
| "read uncommitted" | READ COMMITTED | Syntax synonym in Firebird – identical behaviour to read committed |
| "serializable" | SNAPSHOT TABLE STABILITY | Locks all accessed tables; prevents concurrent writes |
The isolationLevel string is matched case-insensitively and leading/trailing whitespace is ignored.
Read-only transactions
Pass readOnly: true to start a read-only transaction:
await knex.transaction(
async (trx) => {
const rows = await knex("orders").transacting(trx).select("*");
},
{ isolationLevel: "snapshot", readOnly: true },
);Default isolation level
When no isolationLevel is provided, the adapter uses Firebird's own default: SNAPSHOT (Multi Version Concurrency Control). This prevents dirty reads and non-repeatable reads without locking tables.
Using the module locally
If you want to use this fork locally from another project, you have a few options:
- Local file install (quick, no global linking):
# from your project directory
npm install --save ../path/to/knex-firebird-adapterOr add to your project's package.json:
"dependencies": {
"knex-firebird-adapter": "file:../knex-firebird-adapter"
}npm link(handy during development):
# in the fork repository
cd /path/to/knex-firebird-adapter
npm install
npm link
# in the target project
cd /path/to/your-project
npm link knex-firebird-adapter- Direct relative import for quick experiments or tests:
const knexFirebirdAdapter = require('../knex-firebird-adapter').default;Choose the method that fits your workflow.
Tests
Quick guide to run tests in this repository:
- Install dependencies:
npm install- Run the test suite:
npm test
# or directly with jest
npx jestRun a single test file:
npx jest tests/basic-operations.test.jsSee the tests folder for more examples and integration tests.
Publishing to npm
Before publishing, update package.json fields name, repository and homepage to point to your GitHub repository and bump the version accordingly. Ensure the package builds (npm run build) and that lib is included in the files field.
- Login to npm (if not already):
npm login- Build and publish:
npm run build
npm publish --access public- Tag and push the release:
git tag v<version>
git push origin --tagsNotes:
- The
publishConfig.accessfield is set topublicinpackage.jsonto allow public publishing. - For a scoped package (e.g.
@your-org/knex-firebird-adapter) adjustnameand access as needed.
For more information and examples, browse the tests folder and the source files.
