ts-prorm-orm 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1111 -0
- package/LICENSE +21 -0
- package/README.md +573 -0
- package/dist/audit/history-query.js +180 -0
- package/dist/audit/index.js +23 -0
- package/dist/audit/logger.js +236 -0
- package/dist/cache/cache-manager.js +84 -0
- package/dist/cache/index.js +16 -0
- package/dist/cache/redis-cluster-cache.js +557 -0
- package/dist/cli.js +2200 -0
- package/dist/compliance/audit-trail.js +68 -0
- package/dist/compliance/backup-verification.js +685 -0
- package/dist/compliance/breach-detector.js +505 -0
- package/dist/compliance/consent-record.js +227 -0
- package/dist/compliance/consent-versioning.js +331 -0
- package/dist/compliance/cross-border-log.js +530 -0
- package/dist/compliance/data-classifier.js +258 -0
- package/dist/compliance/data-lineage.js +565 -0
- package/dist/compliance/data-masker.js +303 -0
- package/dist/compliance/data-portability.js +265 -0
- package/dist/compliance/data-retention.js +195 -0
- package/dist/compliance/dsar-workflow.js +342 -0
- package/dist/compliance/field-encryption.js +223 -0
- package/dist/compliance/immutable-record.js +148 -0
- package/dist/compliance/index.js +260 -0
- package/dist/compliance/privacy-impact-assessment.js +364 -0
- package/dist/compliance/pseudonymization.js +269 -0
- package/dist/compliance/query-firewall.js +1182 -0
- package/dist/compliance/rate-limiter.js +580 -0
- package/dist/compliance/right-to-erasure.js +117 -0
- package/dist/compliance/row-level-security.js +246 -0
- package/dist/compliance/security-decorator.js +574 -0
- package/dist/compliance/security-monitor.js +525 -0
- package/dist/compliance/sensitive-data-discovery.js +476 -0
- package/dist/compliance/session-isolation.js +472 -0
- package/dist/compliance/tls-enforcer.js +108 -0
- package/dist/compliance/worm-storage.js +712 -0
- package/dist/connection-manager.js +198 -0
- package/dist/connection-pool.js +519 -0
- package/dist/decorators/audit.js +136 -0
- package/dist/decorators/belongs-to-many.js +115 -0
- package/dist/decorators/belongs-to.js +115 -0
- package/dist/decorators/check.js +435 -0
- package/dist/decorators/collate.js +329 -0
- package/dist/decorators/comment.js +205 -0
- package/dist/decorators/database-settings.js +236 -0
- package/dist/decorators/default.js +244 -0
- package/dist/decorators/encryption.js +235 -0
- package/dist/decorators/engine.js +97 -0
- package/dist/decorators/fk-constraints.js +594 -0
- package/dist/decorators/foreign-table.js +136 -0
- package/dist/decorators/generated.js +274 -0
- package/dist/decorators/has-many.js +127 -0
- package/dist/decorators/has-one.js +116 -0
- package/dist/decorators/hstore.js +129 -0
- package/dist/decorators/index.js +355 -0
- package/dist/decorators/json-column.js +83 -0
- package/dist/decorators/jsonb.js +101 -0
- package/dist/decorators/orm-decorators.js +425 -0
- package/dist/decorators/permissions.js +294 -0
- package/dist/decorators/procedure.js +210 -0
- package/dist/decorators/query-options.js +556 -0
- package/dist/decorators/range.js +167 -0
- package/dist/decorators/set-column.js +83 -0
- package/dist/decorators/spatial.js +114 -0
- package/dist/decorators/storage.js +580 -0
- package/dist/decorators/timezone.js +512 -0
- package/dist/decorators/trigger.js +90 -0
- package/dist/decorators/uuid.js +135 -0
- package/dist/decorators/view.js +258 -0
- package/dist/diagrams/chen-diagram.js +354 -0
- package/dist/diagrams/class-diagram.js +384 -0
- package/dist/diagrams/dependency-diagram.js +432 -0
- package/dist/diagrams/er-diagram.js +605 -0
- package/dist/diagrams/flow-diagram.js +394 -0
- package/dist/diagrams/gantt-diagram.js +411 -0
- package/dist/diagrams/index-diagram.js +353 -0
- package/dist/diagrams/index.js +184 -0
- package/dist/diagrams/migration-diagram.js +316 -0
- package/dist/diagrams/model-diagram.js +616 -0
- package/dist/diagrams/package-diagram.js +376 -0
- package/dist/diagrams/palette.js +85 -0
- package/dist/diagrams/relational-diagram.js +455 -0
- package/dist/diagrams/schemadoc-diagram.js +309 -0
- package/dist/diagrams/sequence-diagram.js +307 -0
- package/dist/diagrams/state-diagram.js +344 -0
- package/dist/diagrams/svg-dom.js +111 -0
- package/dist/diagrams/tree-diagram.js +250 -0
- package/dist/dialects/clickhouse/index.js +1742 -0
- package/dist/dialects/cockroachdb/index.js +4677 -0
- package/dist/dialects/cratedb/index.js +441 -0
- package/dist/dialects/databricks/index.js +517 -0
- package/dist/dialects/db2/index.js +2225 -0
- package/dist/dialects/dialect.js +720 -0
- package/dist/dialects/duckdb/index.js +2014 -0
- package/dist/dialects/exasol/index.js +357 -0
- package/dist/dialects/firebird/index.js +495 -0
- package/dist/dialects/greenplum/index.js +457 -0
- package/dist/dialects/hana/index.js +1741 -0
- package/dist/dialects/mariadb/index.js +3590 -0
- package/dist/dialects/mssql/index.js +2296 -0
- package/dist/dialects/mysql/index.js +4058 -0
- package/dist/dialects/oracle/index.js +2999 -0
- package/dist/dialects/postgres/index.js +5319 -0
- package/dist/dialects/query-stream-helper.js +152 -0
- package/dist/dialects/questdb/index.js +433 -0
- package/dist/dialects/redshift/index.js +2277 -0
- package/dist/dialects/singlestore/index.js +354 -0
- package/dist/dialects/snowflake/index.js +2082 -0
- package/dist/dialects/spanner/index.js +1768 -0
- package/dist/dialects/sqlite/index.js +3382 -0
- package/dist/dialects/tidb/index.js +377 -0
- package/dist/dialects/timescaledb/index.js +164 -0
- package/dist/dialects/trino/index.js +420 -0
- package/dist/dialects/turso/index.js +227 -0
- package/dist/dialects/vertica/index.js +317 -0
- package/dist/dialects/yugabytedb/index.js +424 -0
- package/dist/errors/index.js +472 -0
- package/dist/errors/utils.js +340 -0
- package/dist/errors.js +21 -0
- package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
- package/dist/extensions/catalog/mssql-features.js +147 -0
- package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
- package/dist/extensions/catalog/oracle-db2-features.js +196 -0
- package/dist/extensions/catalog/postgres-extensions.js +516 -0
- package/dist/extensions/index.js +71 -0
- package/dist/extensions/types.js +13 -0
- package/dist/foreign-data.js +173 -0
- package/dist/hooks/hooks-manager.js +350 -0
- package/dist/hooks/index.js +37 -0
- package/dist/index.js +463 -0
- package/dist/logging.js +335 -0
- package/dist/migrations/index.js +40 -0
- package/dist/migrations/migration.js +196 -0
- package/dist/migrations/migrator.js +411 -0
- package/dist/migrations/prormmigration.js +275 -0
- package/dist/migrations/query-interface.js +435 -0
- package/dist/migrations/seeder.js +353 -0
- package/dist/models/associations.js +852 -0
- package/dist/models/constraints.js +288 -0
- package/dist/models/data-types.js +2518 -0
- package/dist/models/decorators.js +445 -0
- package/dist/models/index.js +33 -0
- package/dist/models/indexes.js +531 -0
- package/dist/models/methods.js +382 -0
- package/dist/models/model-manager.js +103 -0
- package/dist/models/model.js +5349 -0
- package/dist/models/operators.js +67 -0
- package/dist/models/scopes.js +189 -0
- package/dist/models/typescript-types.js +26 -0
- package/dist/nosql/aerospike/index.js +205 -0
- package/dist/nosql/allegrograph/index.js +169 -0
- package/dist/nosql/arangodb/index.js +364 -0
- package/dist/nosql/azure-blob/index.js +206 -0
- package/dist/nosql/beanstalkd/index.js +231 -0
- package/dist/nosql/beequeue/index.js +210 -0
- package/dist/nosql/bigchaindb/index.js +195 -0
- package/dist/nosql/bigtable/index.js +224 -0
- package/dist/nosql/blazegraph/index.js +173 -0
- package/dist/nosql/bullmq/index.js +191 -0
- package/dist/nosql/cassandra/index.js +174 -0
- package/dist/nosql/chroma/index.js +190 -0
- package/dist/nosql/cloudflare-kv/index.js +220 -0
- package/dist/nosql/coherence/index.js +200 -0
- package/dist/nosql/cosmosdb/index.js +157 -0
- package/dist/nosql/couchbase/index.js +213 -0
- package/dist/nosql/dax/index.js +212 -0
- package/dist/nosql/deno-kv/index.js +206 -0
- package/dist/nosql/dgraph/index.js +171 -0
- package/dist/nosql/doris/index.js +169 -0
- package/dist/nosql/druid/index.js +162 -0
- package/dist/nosql/dynamodb/index.js +937 -0
- package/dist/nosql/elasticsearch/index.js +377 -0
- package/dist/nosql/etcd/index.js +502 -0
- package/dist/nosql/eventhubs/index.js +213 -0
- package/dist/nosql/eventstore/index.js +254 -0
- package/dist/nosql/faunadb/index.js +188 -0
- package/dist/nosql/firestore/index.js +177 -0
- package/dist/nosql/fluree/index.js +148 -0
- package/dist/nosql/fuseki/index.js +170 -0
- package/dist/nosql/gcs/index.js +172 -0
- package/dist/nosql/gearman/index.js +160 -0
- package/dist/nosql/geode/index.js +196 -0
- package/dist/nosql/graphdb/index.js +169 -0
- package/dist/nosql/graylog/index.js +188 -0
- package/dist/nosql/gridgain/index.js +171 -0
- package/dist/nosql/hazelcast/index.js +162 -0
- package/dist/nosql/hbase/index.js +230 -0
- package/dist/nosql/ignite/index.js +173 -0
- package/dist/nosql/immudb/index.js +184 -0
- package/dist/nosql/index.js +232 -0
- package/dist/nosql/infinispan/index.js +200 -0
- package/dist/nosql/influxdb/index.js +0 -0
- package/dist/nosql/kafka/index.js +234 -0
- package/dist/nosql/keyspaces/index.js +189 -0
- package/dist/nosql/kinesis/index.js +253 -0
- package/dist/nosql/leveldb/index.js +153 -0
- package/dist/nosql/lmdb/index.js +160 -0
- package/dist/nosql/loki/index.js +201 -0
- package/dist/nosql/marklogic/index.js +204 -0
- package/dist/nosql/materialize/index.js +145 -0
- package/dist/nosql/meilisearch/index.js +154 -0
- package/dist/nosql/memcached/index.js +223 -0
- package/dist/nosql/milvus/index.js +410 -0
- package/dist/nosql/minio/index.js +265 -0
- package/dist/nosql/momento/index.js +179 -0
- package/dist/nosql/mongodb/index.js +461 -0
- package/dist/nosql/nats/index.js +247 -0
- package/dist/nosql/nedb/index.js +164 -0
- package/dist/nosql/neo4j/index.js +450 -0
- package/dist/nosql/neptune/index.js +470 -0
- package/dist/nosql/nsq/index.js +200 -0
- package/dist/nosql/opensearch/index.js +186 -0
- package/dist/nosql/orientdb/index.js +175 -0
- package/dist/nosql/papertrail/index.js +200 -0
- package/dist/nosql/pinecone/index.js +0 -0
- package/dist/nosql/pinot/index.js +133 -0
- package/dist/nosql/pouchdb/index.js +172 -0
- package/dist/nosql/prometheus/index.js +174 -0
- package/dist/nosql/provendb/index.js +147 -0
- package/dist/nosql/pubsub/index.js +187 -0
- package/dist/nosql/pulsar/index.js +232 -0
- package/dist/nosql/qdrant/index.js +295 -0
- package/dist/nosql/qldb/index.js +192 -0
- package/dist/nosql/r2/index.js +281 -0
- package/dist/nosql/rabbitmq/index.js +237 -0
- package/dist/nosql/ravendb/index.js +175 -0
- package/dist/nosql/redis/index.js +607 -0
- package/dist/nosql/redpanda/index.js +237 -0
- package/dist/nosql/resque/index.js +203 -0
- package/dist/nosql/rethinkdb/index.js +232 -0
- package/dist/nosql/rocksdb/index.js +152 -0
- package/dist/nosql/rockset/index.js +126 -0
- package/dist/nosql/s3/index.js +298 -0
- package/dist/nosql/scylladb/index.js +178 -0
- package/dist/nosql/signoz/index.js +227 -0
- package/dist/nosql/sns/index.js +201 -0
- package/dist/nosql/solr/index.js +231 -0
- package/dist/nosql/splunk/index.js +227 -0
- package/dist/nosql/sqs/index.js +246 -0
- package/dist/nosql/stardog/index.js +169 -0
- package/dist/nosql/starrocks/index.js +170 -0
- package/dist/nosql/store.js +2 -0
- package/dist/nosql/sumologic/index.js +213 -0
- package/dist/nosql/surrealdb/index.js +179 -0
- package/dist/nosql/terminusdb/index.js +151 -0
- package/dist/nosql/tigergraph/index.js +469 -0
- package/dist/nosql/typesense/index.js +148 -0
- package/dist/nosql/unqlite/index.js +157 -0
- package/dist/nosql/upstash/index.js +167 -0
- package/dist/nosql/vercel-kv/index.js +166 -0
- package/dist/nosql/victoriametrics/index.js +213 -0
- package/dist/nosql/virtuoso/index.js +169 -0
- package/dist/nosql/weaviate/index.js +276 -0
- package/dist/operators/index.js +108 -0
- package/dist/operators.js +2690 -0
- package/dist/prisma-migrate/index.js +38 -0
- package/dist/prisma-migrate/migration-generator.js +125 -0
- package/dist/prisma-migrate/model-generator.js +172 -0
- package/dist/prisma-migrate/relations.js +100 -0
- package/dist/prisma-migrate/schema-parser.js +167 -0
- package/dist/prisma-migrate/type-mapper.js +40 -0
- package/dist/prorm.js +6832 -0
- package/dist/query-builders/cte-builder.js +80 -0
- package/dist/query-builders/functions/aggregate.js +390 -0
- package/dist/query-builders/functions/conditional.js +503 -0
- package/dist/query-builders/functions/datetime.js +695 -0
- package/dist/query-builders/functions/fulltext.js +439 -0
- package/dist/query-builders/functions/index.js +93 -0
- package/dist/query-builders/functions/json.js +427 -0
- package/dist/query-builders/functions/math.js +399 -0
- package/dist/query-builders/functions/string.js +518 -0
- package/dist/query-builders/functions/window.js +328 -0
- package/dist/query-builders/include-builder.js +323 -0
- package/dist/query-builders/index-expression-builder.js +242 -0
- package/dist/query-builders/index.js +161 -0
- package/dist/query-builders/insert-builder.js +164 -0
- package/dist/query-builders/model-helpers.js +38 -0
- package/dist/query-builders/order-limit-builder.js +239 -0
- package/dist/query-builders/sql-compiler.js +2040 -0
- package/dist/query-builders/subquery-builder.js +152 -0
- package/dist/query-builders/update-builder.js +182 -0
- package/dist/query-builders/view-builder.js +218 -0
- package/dist/query-builders/where-builder.js +1532 -0
- package/dist/query-interface.js +622 -0
- package/dist/query-optimizers/batch-optimizer.js +426 -0
- package/dist/query-optimizers/explain-plans.js +415 -0
- package/dist/query-optimizers/index.js +51 -0
- package/dist/query-optimizers/prepared-statement-cache.js +423 -0
- package/dist/query-optimizers/query-hints.js +438 -0
- package/dist/query-optimizers/query-optimizer.js +278 -0
- package/dist/query-optimizers/slow-query-logger.js +271 -0
- package/dist/replica-manager.js +507 -0
- package/dist/schema/index.js +15 -0
- package/dist/schema/migration-generator.js +374 -0
- package/dist/schema/schema-differ.js +549 -0
- package/dist/schema/types.js +6 -0
- package/dist/sql-constants.js +300 -0
- package/dist/sqlite-advanced.js +1047 -0
- package/dist/streams/index.js +12 -0
- package/dist/streams/transforms.js +178 -0
- package/dist/transaction.js +456 -0
- package/dist/types/index.js +180 -0
- package/dist/user-management.js +127 -0
- package/dist/utils/date.js +300 -0
- package/dist/utils/index.js +1079 -0
- package/dist/utils/string.js +161 -0
- package/dist/validators/index.js +19 -0
- package/dist/validators/validator.js +911 -0
- package/package.json +190 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Firebird dialect implementation for the TypeScript ORM
|
|
4
|
+
*
|
|
5
|
+
* This dialect provides Firebird SQL generation. A real deployment would use a
|
|
6
|
+
* dedicated Firebird driver (e.g. `node-firebird`); here it extends the
|
|
7
|
+
* PostgreSQL dialect and overrides only the SQL grammar that differs, reusing
|
|
8
|
+
* PostgresDialect's query-builder scaffolding for everything Firebird shares
|
|
9
|
+
* with standard SQL.
|
|
10
|
+
*
|
|
11
|
+
* Notable Firebird SQL differences overridden below:
|
|
12
|
+
*
|
|
13
|
+
* - Row limiting: Firebird has no `LIMIT ... OFFSET ...` clause. It uses
|
|
14
|
+
* `SELECT FIRST n SKIP m ...` placed right after the `SELECT` keyword (e.g.
|
|
15
|
+
* `SELECT FIRST 10 SKIP 20 * FROM ...`). We override `buildLimitOffset` to
|
|
16
|
+
* emit nothing (so the base's trailing LIMIT/OFFSET disappears) and
|
|
17
|
+
* `buildSelectQuery` to inject the `FIRST/SKIP` fragment after the top-level
|
|
18
|
+
* `SELECT`. `UPDATE`/`DELETE` row limiting uses `ROWS n` (not `LIMIT n`),
|
|
19
|
+
* handled in `buildUpdateQuery`/`buildDeleteQuery`.
|
|
20
|
+
* - Upsert: Firebird has no PostgreSQL `INSERT ... ON CONFLICT`. It uses
|
|
21
|
+
* `UPDATE OR INSERT INTO t (...) VALUES (...) MATCHING (...)` instead, where
|
|
22
|
+
* `MATCHING` names the key columns (defaulting to the primary key when
|
|
23
|
+
* omitted). `buildUpsertQuery` and the upsert branch of `buildInsertQuery`
|
|
24
|
+
* emit this form. Because `UPDATE OR INSERT` always overwrites every listed
|
|
25
|
+
* column, `updateOnDuplicate` (a subset of columns to update) has no Firebird
|
|
26
|
+
* equivalent and is ignored.
|
|
27
|
+
* - Auto-increment: Firebird 3+ uses `GENERATED BY DEFAULT AS IDENTITY` rather
|
|
28
|
+
* than PostgreSQL's `SERIAL`. `getDataTypeSql` maps auto-increment
|
|
29
|
+
* INTEGER/BIGINT accordingly, `getIdentityColumnSql` builds a full identity
|
|
30
|
+
* column definition, and `createTable`/`addColumn` emit IDENTITY (not SERIAL)
|
|
31
|
+
* for auto-increment columns.
|
|
32
|
+
* - Column DDL: Firebird omits the `COLUMN` keyword in `ALTER TABLE`. Adding a
|
|
33
|
+
* column is `ALTER TABLE t ADD col type` and dropping is `ALTER TABLE t DROP
|
|
34
|
+
* col` (PostgreSQL spells these `ADD COLUMN` / `DROP COLUMN`).
|
|
35
|
+
* - Generators/sequences: Firebird's sequence objects are historically called
|
|
36
|
+
* "generators". `createGenerator(name)` emits `CREATE SEQUENCE name` (the
|
|
37
|
+
* modern, SQL-standard spelling Firebird accepts).
|
|
38
|
+
* - Type mapping: Firebird uses `BLOB SUB_TYPE TEXT` for long text (no `TEXT`
|
|
39
|
+
* type), `DOUBLE PRECISION`, `TIMESTAMP`, `BOOLEAN`, and `INTEGER`/`BIGINT`.
|
|
40
|
+
* `getDataTypeSql` overrides the relevant mappings.
|
|
41
|
+
* - Identifiers: Firebird upper-cases unquoted identifiers; quoting an
|
|
42
|
+
* identifier with double quotes makes it case-sensitive. We keep the base's
|
|
43
|
+
* double-quote quoting (`"identifier"`), which preserves case as written.
|
|
44
|
+
* - RETURNING: Firebird DOES support `RETURNING` on INSERT/UPDATE/DELETE (for
|
|
45
|
+
* singleton statements), so the inherited RETURNING handling is kept.
|
|
46
|
+
*
|
|
47
|
+
* The default SQL port is 3050 (Firebird's default), not PostgreSQL's 5432.
|
|
48
|
+
*/
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.FirebirdDialect = void 0;
|
|
51
|
+
exports.createFirebirdDialect = createFirebirdDialect;
|
|
52
|
+
const postgres_1 = require("../postgres");
|
|
53
|
+
const prorm_1 = require("../../prorm");
|
|
54
|
+
/**
|
|
55
|
+
* Firebird dialect class. Extends the PostgreSQL dialect and overrides the SQL
|
|
56
|
+
* grammar that Firebird spells differently.
|
|
57
|
+
*/
|
|
58
|
+
class FirebirdDialect extends postgres_1.PostgresDialect {
|
|
59
|
+
constructor(config = {}) {
|
|
60
|
+
// Firebird's default SQL service port is 3050 (not PostgreSQL's 5432).
|
|
61
|
+
super({ port: 3050, ...config });
|
|
62
|
+
this.name = 'firebird';
|
|
63
|
+
}
|
|
64
|
+
// ==========================================================================
|
|
65
|
+
// Row limiting (FIRST / SKIP)
|
|
66
|
+
// ==========================================================================
|
|
67
|
+
/**
|
|
68
|
+
* Firebird does not support a trailing `LIMIT ... OFFSET ...` clause, so we
|
|
69
|
+
* emit nothing here. The actual row-limiting keywords (`FIRST`/`SKIP`) are
|
|
70
|
+
* injected right after the `SELECT` keyword by `buildSelectQuery` below.
|
|
71
|
+
*/
|
|
72
|
+
buildLimitOffset(_limit, _offset) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build the Firebird `FIRST n SKIP m` fragment (without surrounding spaces).
|
|
77
|
+
* Returns an empty string when neither limit nor offset is provided.
|
|
78
|
+
*
|
|
79
|
+
* Firebird allows `SKIP` on its own (`SELECT SKIP 20 ...`), so an offset with
|
|
80
|
+
* no limit is emitted as just `SKIP m`. `FIRST` always precedes `SKIP`.
|
|
81
|
+
*/
|
|
82
|
+
buildFirstSkip(limit, offset) {
|
|
83
|
+
const parts = [];
|
|
84
|
+
if (limit !== undefined) {
|
|
85
|
+
parts.push(`FIRST ${Number(limit)}`);
|
|
86
|
+
}
|
|
87
|
+
if (offset !== undefined) {
|
|
88
|
+
parts.push(`SKIP ${Number(offset)}`);
|
|
89
|
+
}
|
|
90
|
+
return parts.join(' ');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Find the index just past the top-level `SELECT ` keyword in a compiled
|
|
94
|
+
* query so the `FIRST/SKIP` fragment can be inserted there. Scans at
|
|
95
|
+
* parenthesis depth 0 so that `SELECT`s inside CTEs/sub-selects (which live
|
|
96
|
+
* inside parentheses) are skipped and the main query's `SELECT` is targeted.
|
|
97
|
+
* Returns -1 if no top-level `SELECT ` is found.
|
|
98
|
+
*/
|
|
99
|
+
mainSelectInsertIndex(sql) {
|
|
100
|
+
let depth = 0;
|
|
101
|
+
for (let i = 0; i < sql.length; i++) {
|
|
102
|
+
const ch = sql[i];
|
|
103
|
+
if (ch === '(') {
|
|
104
|
+
depth++;
|
|
105
|
+
}
|
|
106
|
+
else if (ch === ')') {
|
|
107
|
+
depth--;
|
|
108
|
+
}
|
|
109
|
+
else if (depth === 0 &&
|
|
110
|
+
(ch === 'S' || ch === 's') &&
|
|
111
|
+
/^select\s/i.test(sql.slice(i, i + 7)) &&
|
|
112
|
+
(i === 0 || !/[A-Za-z0-9_]/.test(sql[i - 1]))) {
|
|
113
|
+
// Skip past `SELECT` plus the single following whitespace char.
|
|
114
|
+
return i + 'SELECT '.length;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return -1;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build a SELECT query using Firebird's `FIRST n SKIP m` row limiting instead
|
|
121
|
+
* of a trailing `LIMIT/OFFSET`. Delegates the heavy lifting to the base
|
|
122
|
+
* PostgreSQL builder (whose `buildLimitOffset` we've neutralized above), then
|
|
123
|
+
* injects the `FIRST/SKIP` fragment right after the top-level `SELECT` — so
|
|
124
|
+
* it works uniformly for plain SELECTs, JOINs, GROUP BY/HAVING, DISTINCT, and
|
|
125
|
+
* queries fronted by a `WITH` CTE (whose inner SELECTs are parenthesized and
|
|
126
|
+
* therefore skipped by `mainSelectInsertIndex`).
|
|
127
|
+
*/
|
|
128
|
+
buildSelectQuery(options) {
|
|
129
|
+
const built = super.buildSelectQuery(options);
|
|
130
|
+
const firstSkip = this.buildFirstSkip(options.limit, options.offset);
|
|
131
|
+
if (!firstSkip) {
|
|
132
|
+
return built;
|
|
133
|
+
}
|
|
134
|
+
const insertAt = this.mainSelectInsertIndex(built.sql);
|
|
135
|
+
if (insertAt < 0) {
|
|
136
|
+
// Defensive: no top-level SELECT found (shouldn't happen for a SELECT).
|
|
137
|
+
return built;
|
|
138
|
+
}
|
|
139
|
+
const sql = `${built.sql.slice(0, insertAt)}${firstSkip} ${built.sql.slice(insertAt)}`;
|
|
140
|
+
return { sql, values: built.values };
|
|
141
|
+
}
|
|
142
|
+
// ==========================================================================
|
|
143
|
+
// INSERT / UPSERT
|
|
144
|
+
// ==========================================================================
|
|
145
|
+
/**
|
|
146
|
+
* Build an INSERT query. When `options.upsert` is set, Firebird uses
|
|
147
|
+
* `UPDATE OR INSERT INTO ... MATCHING (...)` instead of PostgreSQL's
|
|
148
|
+
* `INSERT ... ON CONFLICT`. `MATCHING` names the key columns; when
|
|
149
|
+
* `conflictFields` is omitted Firebird matches on the primary key.
|
|
150
|
+
*/
|
|
151
|
+
buildInsertQuery(tableName, values, options) {
|
|
152
|
+
const columns = Object.keys(values);
|
|
153
|
+
const processedValues = [];
|
|
154
|
+
const placeholders = [];
|
|
155
|
+
let paramIndex = 1;
|
|
156
|
+
for (const value of Object.values(values)) {
|
|
157
|
+
if (value instanceof prorm_1.Literal) {
|
|
158
|
+
placeholders.push(value.val);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
placeholders.push(`$${paramIndex}`);
|
|
162
|
+
processedValues.push(value);
|
|
163
|
+
paramIndex++;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const cols = columns.map((c) => this.escapeId(c)).join(', ');
|
|
167
|
+
const vals = placeholders.join(', ');
|
|
168
|
+
let sql;
|
|
169
|
+
if (options?.upsert) {
|
|
170
|
+
sql = `UPDATE OR INSERT INTO ${this.escapeId(tableName)} (${cols}) VALUES (${vals})`;
|
|
171
|
+
if (options.conflictFields && options.conflictFields.length > 0) {
|
|
172
|
+
sql += ` MATCHING (${options.conflictFields.map((c) => this.escapeId(c)).join(', ')})`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
sql = `INSERT INTO ${this.escapeId(tableName)} (${cols}) VALUES (${vals})`;
|
|
177
|
+
}
|
|
178
|
+
sql += this.buildReturningClause(options?.returning);
|
|
179
|
+
return { sql, values: processedValues };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Build an UPSERT query for Firebird using
|
|
183
|
+
* `UPDATE OR INSERT INTO t (...) VALUES (...) MATCHING (...)`.
|
|
184
|
+
*
|
|
185
|
+
* Unlike PostgreSQL's `ON CONFLICT ... DO UPDATE SET <subset>`, Firebird's
|
|
186
|
+
* `UPDATE OR INSERT` always overwrites every listed column on a match, so a
|
|
187
|
+
* `updateOnDuplicate` subset has no Firebird equivalent and is ignored.
|
|
188
|
+
* `conflictFields`, when given, becomes the `MATCHING` key column list;
|
|
189
|
+
* otherwise Firebird matches on the table's primary key.
|
|
190
|
+
*/
|
|
191
|
+
buildUpsertQuery(tableName, values, options) {
|
|
192
|
+
const columns = Object.keys(values);
|
|
193
|
+
const processedValues = [];
|
|
194
|
+
const placeholders = [];
|
|
195
|
+
let paramIndex = 1;
|
|
196
|
+
for (const value of Object.values(values)) {
|
|
197
|
+
if (value instanceof prorm_1.Literal) {
|
|
198
|
+
placeholders.push(value.val);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
placeholders.push(`$${paramIndex}`);
|
|
202
|
+
processedValues.push(value);
|
|
203
|
+
paramIndex++;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const cols = columns.map((c) => this.escapeId(c)).join(', ');
|
|
207
|
+
let sql = `UPDATE OR INSERT INTO ${this.escapeId(tableName)} (${cols}) VALUES (${placeholders.join(', ')})`;
|
|
208
|
+
if (options?.conflictFields && options.conflictFields.length > 0) {
|
|
209
|
+
sql += ` MATCHING (${options.conflictFields.map((c) => this.escapeId(c)).join(', ')})`;
|
|
210
|
+
}
|
|
211
|
+
sql += this.buildReturningClause(options?.returning);
|
|
212
|
+
return { sql, values: processedValues };
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Build a ` RETURNING ...` suffix (or empty string). Firebird supports
|
|
216
|
+
* RETURNING on singleton INSERT/UPDATE/DELETE/UPDATE-OR-INSERT statements.
|
|
217
|
+
*/
|
|
218
|
+
buildReturningClause(returning) {
|
|
219
|
+
if (!returning) {
|
|
220
|
+
return '';
|
|
221
|
+
}
|
|
222
|
+
if (returning === true) {
|
|
223
|
+
return ' RETURNING *';
|
|
224
|
+
}
|
|
225
|
+
if (Array.isArray(returning)) {
|
|
226
|
+
return ` RETURNING ${returning.map((c) => this.escapeId(c)).join(', ')}`;
|
|
227
|
+
}
|
|
228
|
+
return '';
|
|
229
|
+
}
|
|
230
|
+
// ==========================================================================
|
|
231
|
+
// UPDATE / DELETE (ROWS instead of LIMIT)
|
|
232
|
+
// ==========================================================================
|
|
233
|
+
/**
|
|
234
|
+
* Build an UPDATE query. Firebird limits affected rows with `ROWS n`, not
|
|
235
|
+
* PostgreSQL's `LIMIT n`; we delegate to the base builder and rewrite the
|
|
236
|
+
* emitted `LIMIT n` fragment to `ROWS n` (positioned identically, before any
|
|
237
|
+
* RETURNING clause).
|
|
238
|
+
*/
|
|
239
|
+
buildUpdateQuery(tableName, values, where, options) {
|
|
240
|
+
const built = super.buildUpdateQuery(tableName, values, where, options);
|
|
241
|
+
if (options?.limit) {
|
|
242
|
+
built.sql = built.sql.replace(` LIMIT ${options.limit}`, ` ROWS ${options.limit}`);
|
|
243
|
+
}
|
|
244
|
+
return built;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Build a DELETE query. Firebird limits affected rows with `ROWS n`, not
|
|
248
|
+
* PostgreSQL's `LIMIT n`; rewrite the base builder's `LIMIT n` accordingly.
|
|
249
|
+
*/
|
|
250
|
+
buildDeleteQuery(tableName, where, options) {
|
|
251
|
+
const built = super.buildDeleteQuery(tableName, where, options);
|
|
252
|
+
if (options?.limit && !options.truncate) {
|
|
253
|
+
built.sql = built.sql.replace(` LIMIT ${options.limit}`, ` ROWS ${options.limit}`);
|
|
254
|
+
}
|
|
255
|
+
return built;
|
|
256
|
+
}
|
|
257
|
+
// ==========================================================================
|
|
258
|
+
// Type mapping
|
|
259
|
+
// ==========================================================================
|
|
260
|
+
/**
|
|
261
|
+
* Map an ORM data type to its Firebird SQL spelling. Overrides the mappings
|
|
262
|
+
* that differ from PostgreSQL and delegates everything else to the base.
|
|
263
|
+
*/
|
|
264
|
+
getDataTypeSql(dataType) {
|
|
265
|
+
if (!dataType || typeof dataType !== 'object') {
|
|
266
|
+
return super.getDataTypeSql(dataType);
|
|
267
|
+
}
|
|
268
|
+
const dt = dataType;
|
|
269
|
+
switch (dt.key) {
|
|
270
|
+
case 'STRING':
|
|
271
|
+
return `VARCHAR(${dt.length || 255})`;
|
|
272
|
+
case 'CHAR':
|
|
273
|
+
return `CHAR(${dt.length || 1})`;
|
|
274
|
+
case 'TEXT':
|
|
275
|
+
// Firebird has no `TEXT` type; long text is stored as a text BLOB.
|
|
276
|
+
return 'BLOB SUB_TYPE TEXT';
|
|
277
|
+
case 'INTEGER':
|
|
278
|
+
return dt.autoIncrement
|
|
279
|
+
? 'INTEGER GENERATED BY DEFAULT AS IDENTITY'
|
|
280
|
+
: 'INTEGER';
|
|
281
|
+
case 'BIGINT':
|
|
282
|
+
return dt.autoIncrement
|
|
283
|
+
? 'BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
284
|
+
: 'BIGINT';
|
|
285
|
+
case 'FLOAT':
|
|
286
|
+
return 'FLOAT';
|
|
287
|
+
case 'DOUBLE':
|
|
288
|
+
return 'DOUBLE PRECISION';
|
|
289
|
+
case 'DECIMAL':
|
|
290
|
+
return `DECIMAL(${dt.precision || 10},${dt.scale || 0})`;
|
|
291
|
+
case 'BOOLEAN':
|
|
292
|
+
return 'BOOLEAN';
|
|
293
|
+
case 'DATE':
|
|
294
|
+
// ORM DATE == timestamp; Firebird spells it TIMESTAMP.
|
|
295
|
+
return dt.precision ? `TIMESTAMP(${dt.precision})` : 'TIMESTAMP';
|
|
296
|
+
case 'DATEONLY':
|
|
297
|
+
return 'DATE';
|
|
298
|
+
case 'TIME':
|
|
299
|
+
return dt.precision ? `TIME(${dt.precision})` : 'TIME';
|
|
300
|
+
case 'BLOB':
|
|
301
|
+
return 'BLOB';
|
|
302
|
+
case 'JSON':
|
|
303
|
+
case 'JSONB':
|
|
304
|
+
// Firebird has no native JSON type; store as a text BLOB.
|
|
305
|
+
return 'BLOB SUB_TYPE TEXT';
|
|
306
|
+
default:
|
|
307
|
+
return super.getDataTypeSql(dataType);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// ==========================================================================
|
|
311
|
+
// DDL: CREATE TABLE / ALTER TABLE columns
|
|
312
|
+
// ==========================================================================
|
|
313
|
+
/**
|
|
314
|
+
* Build a Firebird `CREATE TABLE` statement. Unlike the PostgreSQL base,
|
|
315
|
+
* auto-increment columns use `GENERATED BY DEFAULT AS IDENTITY` (not
|
|
316
|
+
* `SERIAL`). Firebird does not support `CREATE TABLE IF NOT EXISTS`, so that
|
|
317
|
+
* option is ignored. Exposed separately from `createTable` so the generated
|
|
318
|
+
* SQL can be asserted without a live connection.
|
|
319
|
+
*/
|
|
320
|
+
buildCreateTableSQL(tableName, columns, options) {
|
|
321
|
+
const defs = [];
|
|
322
|
+
for (const [columnName, definition] of Object.entries(columns)) {
|
|
323
|
+
defs.push(this.getFirebirdColumnSql(columnName, definition));
|
|
324
|
+
}
|
|
325
|
+
if (options?.constraints) {
|
|
326
|
+
for (const constraint of options.constraints) {
|
|
327
|
+
const sql = this.buildFirebirdConstraintSql(constraint);
|
|
328
|
+
if (sql) {
|
|
329
|
+
defs.push(sql);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return `CREATE TABLE ${this.escapeId(tableName)} (${defs.join(', ')})`;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Create a table using Firebird DDL (identity columns, no SERIAL). After the
|
|
337
|
+
* table is created, unique keys, indexes and a table comment (if requested)
|
|
338
|
+
* are applied as separate statements, mirroring the base dialect's behaviour.
|
|
339
|
+
*/
|
|
340
|
+
async createTable(tableName, columns, options) {
|
|
341
|
+
await this.query(this.buildCreateTableSQL(tableName, columns, options));
|
|
342
|
+
// Unique keys as separate ALTER TABLE ... ADD CONSTRAINT statements.
|
|
343
|
+
if (options?.uniqueKeys && !Array.isArray(options.uniqueKeys)) {
|
|
344
|
+
for (const [keyName, fields] of Object.entries(options.uniqueKeys)) {
|
|
345
|
+
const constraintName = keyName || `${tableName}_${fields.join('_')}_key`;
|
|
346
|
+
await this.query(`ALTER TABLE ${this.escapeId(tableName)} ADD CONSTRAINT ${this.escapeId(constraintName)} UNIQUE (${fields
|
|
347
|
+
.map((f) => this.escapeId(f))
|
|
348
|
+
.join(', ')})`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (options?.indexes) {
|
|
352
|
+
for (const index of options.indexes) {
|
|
353
|
+
await this.addIndex(tableName, index.name || `idx_${tableName}_${index.fields.join('_')}`, index.fields, { unique: index.unique, using: index.using, where: index.where });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (options?.comment) {
|
|
357
|
+
await this.query(`COMMENT ON TABLE ${this.escapeId(tableName)} IS ${this.escape(options.comment)}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Build a single Firebird column definition (used by CREATE TABLE and
|
|
362
|
+
* ADD COLUMN). Auto-increment INTEGER/BIGINT columns become identity columns.
|
|
363
|
+
*/
|
|
364
|
+
getFirebirdColumnSql(columnName, definition) {
|
|
365
|
+
const dt = definition.type;
|
|
366
|
+
const isAutoInt = !!definition.autoIncrement && (!dt?.key || dt.key === 'INTEGER' || dt.key === 'BIGINT');
|
|
367
|
+
let typeSql;
|
|
368
|
+
if (isAutoInt) {
|
|
369
|
+
const baseType = dt?.key === 'BIGINT' ? 'BIGINT' : 'INTEGER';
|
|
370
|
+
typeSql = `${baseType} GENERATED BY DEFAULT AS IDENTITY`;
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
typeSql = this.getDataTypeSql(definition.type);
|
|
374
|
+
}
|
|
375
|
+
let sql = `${this.escapeId(columnName)} ${typeSql}`;
|
|
376
|
+
// Firebird requires DEFAULT before NOT NULL. Identity columns take no default.
|
|
377
|
+
if (!isAutoInt && definition.defaultValue !== undefined) {
|
|
378
|
+
sql += ` DEFAULT ${this.escape(definition.defaultValue)}`;
|
|
379
|
+
}
|
|
380
|
+
if (definition.allowNull === false) {
|
|
381
|
+
sql += ' NOT NULL';
|
|
382
|
+
}
|
|
383
|
+
if (definition.primaryKey) {
|
|
384
|
+
sql += ' PRIMARY KEY';
|
|
385
|
+
}
|
|
386
|
+
if (definition.unique) {
|
|
387
|
+
sql += ' UNIQUE';
|
|
388
|
+
}
|
|
389
|
+
if (definition.references) {
|
|
390
|
+
const refField = definition.references.field;
|
|
391
|
+
const refFieldSql = Array.isArray(refField)
|
|
392
|
+
? `(${refField.map((f) => this.escapeId(f)).join(', ')})`
|
|
393
|
+
: `(${this.escapeId(refField)})`;
|
|
394
|
+
sql += ` REFERENCES ${this.escapeId(definition.references.table)} ${refFieldSql}`;
|
|
395
|
+
if (definition.references.onDelete) {
|
|
396
|
+
sql += ` ON DELETE ${definition.references.onDelete}`;
|
|
397
|
+
}
|
|
398
|
+
if (definition.references.onUpdate) {
|
|
399
|
+
sql += ` ON UPDATE ${definition.references.onUpdate}`;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return sql;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Build an inline table constraint for Firebird CREATE TABLE.
|
|
406
|
+
*/
|
|
407
|
+
buildFirebirdConstraintSql(constraint) {
|
|
408
|
+
const name = constraint.name ? `CONSTRAINT ${this.escapeId(constraint.name)} ` : '';
|
|
409
|
+
const fields = (constraint.fields || []).map((f) => this.escapeId(f)).join(', ');
|
|
410
|
+
switch (constraint.type) {
|
|
411
|
+
case 'PRIMARY KEY':
|
|
412
|
+
return `${name}PRIMARY KEY (${fields})`;
|
|
413
|
+
case 'UNIQUE':
|
|
414
|
+
return `${name}UNIQUE (${fields})`;
|
|
415
|
+
case 'CHECK':
|
|
416
|
+
return constraint.check ? `${name}CHECK (${constraint.check})` : null;
|
|
417
|
+
case 'FOREIGN KEY': {
|
|
418
|
+
if (!constraint.references) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const refField = constraint.references.field;
|
|
422
|
+
const refFieldSql = Array.isArray(refField)
|
|
423
|
+
? refField.map((f) => this.escapeId(f)).join(', ')
|
|
424
|
+
: this.escapeId(refField);
|
|
425
|
+
let sql = `${name}FOREIGN KEY (${fields}) REFERENCES ${this.escapeId(constraint.references.table)} (${refFieldSql})`;
|
|
426
|
+
if (constraint.references.onDelete) {
|
|
427
|
+
sql += ` ON DELETE ${constraint.references.onDelete}`;
|
|
428
|
+
}
|
|
429
|
+
if (constraint.references.onUpdate) {
|
|
430
|
+
sql += ` ON UPDATE ${constraint.references.onUpdate}`;
|
|
431
|
+
}
|
|
432
|
+
return sql;
|
|
433
|
+
}
|
|
434
|
+
default:
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Add a column to a table. Firebird's `ALTER TABLE ... ADD` omits the
|
|
440
|
+
* `COLUMN` keyword that PostgreSQL uses.
|
|
441
|
+
*/
|
|
442
|
+
async addColumn(tableName, columnName, definition) {
|
|
443
|
+
const sql = `ALTER TABLE ${this.escapeId(tableName)} ADD ${this.getFirebirdColumnSql(columnName, definition)}`;
|
|
444
|
+
await this.query(sql);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Remove a column from a table. Firebird's `ALTER TABLE ... DROP` omits the
|
|
448
|
+
* `COLUMN` keyword that PostgreSQL uses.
|
|
449
|
+
*/
|
|
450
|
+
async removeColumn(tableName, columnName) {
|
|
451
|
+
const sql = `ALTER TABLE ${this.escapeId(tableName)} DROP ${this.escapeId(columnName)}`;
|
|
452
|
+
await this.query(sql);
|
|
453
|
+
}
|
|
454
|
+
// ==========================================================================
|
|
455
|
+
// Identity columns & generators
|
|
456
|
+
// ==========================================================================
|
|
457
|
+
/**
|
|
458
|
+
* Build a Firebird identity-column definition, e.g.
|
|
459
|
+
* `"id" INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY`.
|
|
460
|
+
*
|
|
461
|
+
* Firebird 3+ replaces PostgreSQL's `SERIAL` shorthand with the SQL-standard
|
|
462
|
+
* `GENERATED BY DEFAULT AS IDENTITY` clause.
|
|
463
|
+
*
|
|
464
|
+
* @param columnName - Name of the identity column
|
|
465
|
+
* @param options - `type` selects INTEGER (default) or BIGINT; `primaryKey`
|
|
466
|
+
* appends `PRIMARY KEY`
|
|
467
|
+
*/
|
|
468
|
+
getIdentityColumnSql(columnName, options) {
|
|
469
|
+
const baseType = options?.type === 'BIGINT' ? 'BIGINT' : 'INTEGER';
|
|
470
|
+
let sql = `${this.escapeId(columnName)} ${baseType} GENERATED BY DEFAULT AS IDENTITY`;
|
|
471
|
+
if (options?.primaryKey) {
|
|
472
|
+
sql += ' PRIMARY KEY';
|
|
473
|
+
}
|
|
474
|
+
return sql;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Build the SQL to create a Firebird generator (sequence). Firebird's
|
|
478
|
+
* sequence objects were historically called "generators"; modern Firebird
|
|
479
|
+
* accepts the SQL-standard `CREATE SEQUENCE` spelling, which is emitted here.
|
|
480
|
+
*
|
|
481
|
+
* @param name - Generator/sequence name
|
|
482
|
+
* @returns `CREATE SEQUENCE "name"`
|
|
483
|
+
*/
|
|
484
|
+
createGenerator(name) {
|
|
485
|
+
return `CREATE SEQUENCE ${this.escapeId(name)}`;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
exports.FirebirdDialect = FirebirdDialect;
|
|
489
|
+
/**
|
|
490
|
+
* Create a new Firebird dialect instance
|
|
491
|
+
*/
|
|
492
|
+
function createFirebirdDialect(options) {
|
|
493
|
+
return new FirebirdDialect(options || {});
|
|
494
|
+
}
|
|
495
|
+
exports.default = FirebirdDialect;
|