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,441 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CrateDB dialect implementation for the TypeScript ORM
|
|
4
|
+
*
|
|
5
|
+
* CrateDB is a distributed SQL database that speaks the PostgreSQL wire protocol
|
|
6
|
+
* (default port 5432) and is largely PG-compatible on the client side, so this
|
|
7
|
+
* dialect extends `PostgresDialect` and reuses the `pg` driver for connectivity
|
|
8
|
+
* and most query building. It overrides the schema-generation surface (CREATE
|
|
9
|
+
* TABLE + type mapping) to emit CrateDB-native SQL. Notable differences from the
|
|
10
|
+
* Postgres dialect:
|
|
11
|
+
*
|
|
12
|
+
* - Default port stays 5432 (PG-wire-compatible), so the constructor forwards
|
|
13
|
+
* `{ port: 5432, ...config }` to the Postgres base.
|
|
14
|
+
* - CREATE TABLE supports CrateDB's distribution/partitioning clauses, emitted in
|
|
15
|
+
* CrateDB's required order: `PARTITIONED BY (col)`, then
|
|
16
|
+
* `CLUSTERED [BY (col)] INTO n SHARDS`, then a `WITH ( ... )` settings block.
|
|
17
|
+
* Example:
|
|
18
|
+
* CREATE TABLE "t" (...) PARTITIONED BY ("day")
|
|
19
|
+
* CLUSTERED BY ("id") INTO 6 SHARDS
|
|
20
|
+
* WITH (number_of_replicas = '1', "refresh_interval" = 1000)
|
|
21
|
+
* - Type mapping is CrateDB-specific: TEXT, INTEGER, BIGINT, DOUBLE PRECISION,
|
|
22
|
+
* BOOLEAN, TIMESTAMP, OBJECT and GEO_POINT (rather than Postgres VARCHAR/SERIAL/
|
|
23
|
+
* JSONB/etc). Composite/semi-structured types use CrateDB syntax:
|
|
24
|
+
* * OBJECT columns emit `OBJECT(DYNAMIC) AS (col type, ...)` (or bare `OBJECT`
|
|
25
|
+
* when no sub-columns are declared). The column policy defaults to DYNAMIC.
|
|
26
|
+
* * ARRAY columns emit `ARRAY(type)` (CrateDB's array syntax) rather than
|
|
27
|
+
* Postgres's `type[]`.
|
|
28
|
+
* - PRIMARY KEY is preserved. NOTE: in CrateDB a PRIMARY KEY must include every
|
|
29
|
+
* routing/clustered/partitioned column (CrateDB requires routing columns to be
|
|
30
|
+
* part of the primary key). The dialect does not attempt to validate or rewrite
|
|
31
|
+
* the PRIMARY KEY to enforce this — it is the caller's responsibility.
|
|
32
|
+
* - FOREIGN KEYs are OMITTED. CrateDB has no foreign-key support, so both
|
|
33
|
+
* column-level `references` and any `FOREIGN KEY` table constraints are dropped
|
|
34
|
+
* from generated DDL rather than emitted.
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.CrateDBDialect = void 0;
|
|
38
|
+
exports.createCrateDBDialect = createCrateDBDialect;
|
|
39
|
+
const postgres_1 = require("../postgres");
|
|
40
|
+
/**
|
|
41
|
+
* CrateDB dialect class. Extends the PostgreSQL dialect (PG-wire compatible) and
|
|
42
|
+
* overrides CREATE TABLE generation and type mapping for CrateDB.
|
|
43
|
+
*/
|
|
44
|
+
class CrateDBDialect extends postgres_1.PostgresDialect {
|
|
45
|
+
constructor(config) {
|
|
46
|
+
// CrateDB is PG-wire-compatible and listens on 5432 by default.
|
|
47
|
+
super({ port: 5432, ...config });
|
|
48
|
+
this.name = 'cratedb';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Map an ORM data type to its CrateDB SQL type. Overrides the Postgres mapping
|
|
52
|
+
* to emit CrateDB-native types (TEXT, INTEGER, BIGINT, DOUBLE PRECISION,
|
|
53
|
+
* BOOLEAN, TIMESTAMP, OBJECT, GEO_POINT) and CrateDB's `OBJECT(...)`/`ARRAY(...)`
|
|
54
|
+
* syntax for semi-structured/collection types.
|
|
55
|
+
*/
|
|
56
|
+
getDataTypeSql(dataType) {
|
|
57
|
+
if (typeof dataType === 'string') {
|
|
58
|
+
const s = dataType.trim();
|
|
59
|
+
// The shared model-sync layer emits cross-dialect pseudo/PG types as
|
|
60
|
+
// strings; normalize the common ones to their CrateDB equivalents.
|
|
61
|
+
if (/^DATETIME(\(\d+\))?$/i.test(s))
|
|
62
|
+
return 'TIMESTAMP';
|
|
63
|
+
if (/^(VARCHAR|CHARACTER\s+VARYING|CHARACTER|CHAR|STRING|NVARCHAR|NCHAR|TEXT|CLOB)(\(.*\))?$/i.test(s)) {
|
|
64
|
+
return 'TEXT';
|
|
65
|
+
}
|
|
66
|
+
if (/^JSONB?$/i.test(s) || /^HSTORE$/i.test(s))
|
|
67
|
+
return 'OBJECT';
|
|
68
|
+
if (/^UUID$/i.test(s))
|
|
69
|
+
return 'TEXT';
|
|
70
|
+
if (/^(SERIAL|BIGSERIAL|SMALLSERIAL)$/i.test(s))
|
|
71
|
+
return 'BIGINT';
|
|
72
|
+
if (/^(REAL|FLOAT|NUMERIC|DECIMAL|DOUBLE(\s+PRECISION)?)(\(.*\))?$/i.test(s)) {
|
|
73
|
+
return 'DOUBLE PRECISION';
|
|
74
|
+
}
|
|
75
|
+
if (/^(TIMESTAMP|TIMESTAMPTZ|DATE|TIME)(\(\d+\))?$/i.test(s))
|
|
76
|
+
return 'TIMESTAMP';
|
|
77
|
+
return s;
|
|
78
|
+
}
|
|
79
|
+
if (!dataType || typeof dataType !== 'object') {
|
|
80
|
+
return 'TEXT';
|
|
81
|
+
}
|
|
82
|
+
const dt = dataType;
|
|
83
|
+
switch (dt.key) {
|
|
84
|
+
case 'STRING':
|
|
85
|
+
case 'CHAR':
|
|
86
|
+
case 'TEXT':
|
|
87
|
+
case 'ENUM':
|
|
88
|
+
case 'UUID':
|
|
89
|
+
case 'INET':
|
|
90
|
+
case 'CIDR':
|
|
91
|
+
case 'MACADDR':
|
|
92
|
+
return 'TEXT';
|
|
93
|
+
case 'INTEGER':
|
|
94
|
+
return 'INTEGER';
|
|
95
|
+
case 'BIGINT':
|
|
96
|
+
return 'BIGINT';
|
|
97
|
+
case 'FLOAT':
|
|
98
|
+
case 'DOUBLE':
|
|
99
|
+
case 'DECIMAL':
|
|
100
|
+
return 'DOUBLE PRECISION';
|
|
101
|
+
case 'BOOLEAN':
|
|
102
|
+
return 'BOOLEAN';
|
|
103
|
+
case 'DATE':
|
|
104
|
+
case 'DATEONLY':
|
|
105
|
+
case 'TIME':
|
|
106
|
+
return 'TIMESTAMP';
|
|
107
|
+
case 'JSON':
|
|
108
|
+
case 'JSONB':
|
|
109
|
+
case 'HSTORE':
|
|
110
|
+
case 'OBJECT':
|
|
111
|
+
return this.buildObjectTypeSql(dt);
|
|
112
|
+
case 'ARRAY': {
|
|
113
|
+
// CrateDB uses ARRAY(type), not Postgres's type[].
|
|
114
|
+
const arrayType = dt.type || dt.subtype;
|
|
115
|
+
const base = arrayType ? this.getDataTypeSql(arrayType) : 'TEXT';
|
|
116
|
+
return `ARRAY(${base})`;
|
|
117
|
+
}
|
|
118
|
+
case 'GEOMETRY':
|
|
119
|
+
case 'GEOGRAPHY':
|
|
120
|
+
case 'GEO_POINT':
|
|
121
|
+
return 'GEO_POINT';
|
|
122
|
+
case 'GEO_SHAPE':
|
|
123
|
+
return 'GEO_SHAPE';
|
|
124
|
+
case 'VIRTUAL':
|
|
125
|
+
return '';
|
|
126
|
+
default:
|
|
127
|
+
return 'TEXT';
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Build the CrateDB `OBJECT` type SQL. Emits `OBJECT(POLICY) AS (col type, ...)`
|
|
132
|
+
* when sub-columns are declared, otherwise a bare `OBJECT`. The column policy
|
|
133
|
+
* defaults to DYNAMIC (CrateDB's default).
|
|
134
|
+
*/
|
|
135
|
+
buildObjectTypeSql(dt) {
|
|
136
|
+
const policy = String(dt.columnPolicy || dt.policy || 'DYNAMIC').toUpperCase();
|
|
137
|
+
const fields = dt.fields || dt.columns || dt.properties;
|
|
138
|
+
if (fields && typeof fields === 'object') {
|
|
139
|
+
const inner = Object.entries(fields)
|
|
140
|
+
.map(([name, def]) => {
|
|
141
|
+
// A field value is either a DataType directly (has `.key`, e.g. an
|
|
142
|
+
// ARRAY type which itself carries a `.type` subtype) or a
|
|
143
|
+
// ColumnDefinition wrapper (`{ type: DataType }`). Only unwrap `.type`
|
|
144
|
+
// when there's no `.key`, so an ARRAY DataType isn't misread as a wrapper.
|
|
145
|
+
const d = def;
|
|
146
|
+
const type = d && d.key === undefined && d.type !== undefined
|
|
147
|
+
? def.type
|
|
148
|
+
: def;
|
|
149
|
+
return `${this.escapeId(name)} ${this.getDataTypeSql(type)}`;
|
|
150
|
+
})
|
|
151
|
+
.join(', ');
|
|
152
|
+
return `OBJECT(${policy}) AS (${inner})`;
|
|
153
|
+
}
|
|
154
|
+
return 'OBJECT';
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Format a value for a `WITH ( key = value )` table setting: strings are
|
|
158
|
+
* single-quoted (with embedded quotes escaped), numbers/booleans are bare.
|
|
159
|
+
*/
|
|
160
|
+
formatSettingValue(value) {
|
|
161
|
+
if (typeof value === 'string') {
|
|
162
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
163
|
+
}
|
|
164
|
+
return String(value);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Format a CrateDB column DEFAULT value.
|
|
168
|
+
*/
|
|
169
|
+
formatDefaultValue(value) {
|
|
170
|
+
if (value === null)
|
|
171
|
+
return 'NULL';
|
|
172
|
+
if (typeof value === 'string') {
|
|
173
|
+
if (value.toUpperCase().includes('CURRENT_') || value.toUpperCase() === 'NULL') {
|
|
174
|
+
return value;
|
|
175
|
+
}
|
|
176
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
177
|
+
}
|
|
178
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
179
|
+
return String(value);
|
|
180
|
+
}
|
|
181
|
+
if (value instanceof Date) {
|
|
182
|
+
return `'${value.toISOString()}'`;
|
|
183
|
+
}
|
|
184
|
+
if (typeof value === 'object' &&
|
|
185
|
+
value !== null &&
|
|
186
|
+
typeof value.toDefaultValue === 'function') {
|
|
187
|
+
return value.toDefaultValue();
|
|
188
|
+
}
|
|
189
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Build a single CrateDB column definition. FOREIGN KEY references are omitted
|
|
193
|
+
* (CrateDB has no FK support).
|
|
194
|
+
*/
|
|
195
|
+
getCrateColumnDefinitionSql(columnName, definition) {
|
|
196
|
+
const typeSql = this.getDataTypeSql(definition.type);
|
|
197
|
+
// VIRTUAL columns map to an empty type and produce no column.
|
|
198
|
+
if (!typeSql)
|
|
199
|
+
return '';
|
|
200
|
+
let sql = `${this.escapeId(columnName)} ${typeSql}`;
|
|
201
|
+
if (definition.allowNull === false) {
|
|
202
|
+
sql += ' NOT NULL';
|
|
203
|
+
}
|
|
204
|
+
if (definition.defaultValue !== undefined) {
|
|
205
|
+
sql += ` DEFAULT ${this.formatDefaultValue(definition.defaultValue)}`;
|
|
206
|
+
}
|
|
207
|
+
if (definition.primaryKey) {
|
|
208
|
+
sql += ' PRIMARY KEY';
|
|
209
|
+
}
|
|
210
|
+
// definition.references is intentionally ignored: CrateDB has no FOREIGN KEYs.
|
|
211
|
+
return sql;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Build a CrateDB table constraint. FOREIGN KEY constraints are omitted
|
|
215
|
+
* (CrateDB has no FK support); PRIMARY KEY / UNIQUE / CHECK are passed through.
|
|
216
|
+
*/
|
|
217
|
+
buildCrateConstraintSql(constraint) {
|
|
218
|
+
if (constraint.type === 'FOREIGN KEY') {
|
|
219
|
+
// CrateDB does not support foreign keys — drop the constraint entirely.
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
const name = constraint.name ? `${this.escapeId(constraint.name)} ` : '';
|
|
223
|
+
const fields = constraint.fields?.map((f) => this.escapeId(f)).join(', ') || '';
|
|
224
|
+
switch (constraint.type) {
|
|
225
|
+
case 'PRIMARY KEY':
|
|
226
|
+
return `${name}PRIMARY KEY (${fields})`;
|
|
227
|
+
case 'UNIQUE':
|
|
228
|
+
return `${name}UNIQUE (${fields})`;
|
|
229
|
+
case 'CHECK':
|
|
230
|
+
if (!constraint.check)
|
|
231
|
+
return null;
|
|
232
|
+
return `${name}CHECK (${constraint.check})`;
|
|
233
|
+
default:
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Build the CrateDB `CREATE TABLE` statement (synchronous, no execution).
|
|
239
|
+
*
|
|
240
|
+
* Emits clauses in CrateDB's required order after the column list:
|
|
241
|
+
* 1. `PARTITIONED BY (col, ...)`
|
|
242
|
+
* 2. `CLUSTERED [BY (col)] INTO n SHARDS`
|
|
243
|
+
* 3. `WITH ( key = value, ... )`
|
|
244
|
+
*
|
|
245
|
+
* FOREIGN KEY references/constraints are omitted (unsupported by CrateDB).
|
|
246
|
+
*/
|
|
247
|
+
buildCreateTableSQL(tableName, columns, options) {
|
|
248
|
+
const columnDefs = [];
|
|
249
|
+
for (const [columnName, definition] of Object.entries(columns)) {
|
|
250
|
+
const columnSql = this.getCrateColumnDefinitionSql(columnName, definition);
|
|
251
|
+
if (columnSql) {
|
|
252
|
+
columnDefs.push(columnSql);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (options?.constraints) {
|
|
256
|
+
for (const constraint of options.constraints) {
|
|
257
|
+
const constraintSql = this.buildCrateConstraintSql(constraint);
|
|
258
|
+
if (constraintSql) {
|
|
259
|
+
columnDefs.push(constraintSql);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// Fulltext INDEX columns (CrateDB's only user-defined index kind) are
|
|
264
|
+
// declared inline in the column list, e.g.
|
|
265
|
+
// INDEX "ft_body" USING FULLTEXT ("title", "body") WITH (analyzer = 'english')
|
|
266
|
+
if (options?.fulltextIndexes) {
|
|
267
|
+
for (const ft of options.fulltextIndexes) {
|
|
268
|
+
const cols = ft.fields.map((f) => this.escapeId(f)).join(', ');
|
|
269
|
+
let ftSql = `INDEX ${this.escapeId(ft.name)} USING FULLTEXT (${cols})`;
|
|
270
|
+
if (ft.analyzer) {
|
|
271
|
+
ftSql += ` WITH (analyzer = ${this.formatSettingValue(ft.analyzer)})`;
|
|
272
|
+
}
|
|
273
|
+
columnDefs.push(ftSql);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
let sql = 'CREATE TABLE';
|
|
277
|
+
if (options?.ifNotExists) {
|
|
278
|
+
sql += ' IF NOT EXISTS';
|
|
279
|
+
}
|
|
280
|
+
sql += ` ${this.escapeId(tableName)} (${columnDefs.join(', ')})`;
|
|
281
|
+
// 1. PARTITIONED BY
|
|
282
|
+
if (options?.partitionedBy) {
|
|
283
|
+
const cols = Array.isArray(options.partitionedBy)
|
|
284
|
+
? options.partitionedBy
|
|
285
|
+
: [options.partitionedBy];
|
|
286
|
+
sql += ` PARTITIONED BY (${cols.map((c) => this.escapeId(c)).join(', ')})`;
|
|
287
|
+
}
|
|
288
|
+
// 2. CLUSTERED [BY (col)] INTO n SHARDS
|
|
289
|
+
const clusteredBy = options?.clusteredBy;
|
|
290
|
+
const shards = options?.clusteredInto ?? options?.shards;
|
|
291
|
+
if (clusteredBy || shards !== undefined) {
|
|
292
|
+
let clustered = 'CLUSTERED';
|
|
293
|
+
if (clusteredBy) {
|
|
294
|
+
clustered += ` BY (${this.escapeId(clusteredBy)})`;
|
|
295
|
+
}
|
|
296
|
+
if (shards !== undefined) {
|
|
297
|
+
clustered += ` INTO ${shards} SHARDS`;
|
|
298
|
+
}
|
|
299
|
+
sql += ` ${clustered}`;
|
|
300
|
+
}
|
|
301
|
+
// 3. WITH ( key = value, ... )
|
|
302
|
+
const withOpts = options?.with;
|
|
303
|
+
if (withOpts && Object.keys(withOpts).length > 0) {
|
|
304
|
+
const pairs = Object.entries(withOpts).map(([key, value]) => `${key} = ${this.formatSettingValue(value)}`);
|
|
305
|
+
sql += ` WITH (${pairs.join(', ')})`;
|
|
306
|
+
}
|
|
307
|
+
return sql;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Create a new table in CrateDB.
|
|
311
|
+
*
|
|
312
|
+
* Overrides the Postgres implementation to emit CrateDB's CREATE TABLE syntax
|
|
313
|
+
* (CLUSTERED / PARTITIONED BY / WITH, CrateDB type mapping, no foreign keys).
|
|
314
|
+
*/
|
|
315
|
+
async createTable(tableName, columns, options) {
|
|
316
|
+
const sql = this.buildCreateTableSQL(tableName, columns, options);
|
|
317
|
+
await this.query(sql);
|
|
318
|
+
// CrateDB has no standalone CREATE INDEX statement: every column is
|
|
319
|
+
// automatically indexed (a plain index), and the only user-defined indexes
|
|
320
|
+
// are fulltext indexes, which are declared inline at CREATE TABLE via the
|
|
321
|
+
// `fulltextIndexes` option (handled in buildCreateTableSQL). Generic
|
|
322
|
+
// `options.indexes` therefore cannot be honored — warn rather than emit
|
|
323
|
+
// invalid `CREATE INDEX` SQL.
|
|
324
|
+
if (options?.indexes && options.indexes.length > 0) {
|
|
325
|
+
console.warn(`CrateDB: ${options.indexes.length} secondary index(es) on "${tableName}" ignored — ` +
|
|
326
|
+
'CrateDB auto-indexes all columns; use the fulltextIndexes option for fulltext search.');
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
async addIndex(_tableName, _indexName, _fields, _options) {
|
|
330
|
+
throw new Error(CrateDBDialect.NO_CREATE_INDEX);
|
|
331
|
+
}
|
|
332
|
+
async createIndex(_tableName, _indexDef) {
|
|
333
|
+
throw new Error(CrateDBDialect.NO_CREATE_INDEX);
|
|
334
|
+
}
|
|
335
|
+
async createFulltextIndex(_tableName, _indexName, _fields, _options) {
|
|
336
|
+
throw new Error('CrateDB fulltext indexes cannot be added after table creation — declare them at ' +
|
|
337
|
+
'CREATE TABLE via the fulltextIndexes option (INDEX ... USING FULLTEXT (...)).');
|
|
338
|
+
}
|
|
339
|
+
async createSpatialIndex(_tableName, _indexName, _fields, _options) {
|
|
340
|
+
throw new Error('CrateDB has no spatial index statement: GEO_SHAPE columns take an inline INDEX ' +
|
|
341
|
+
'definition at CREATE TABLE time, not a separate CREATE INDEX.');
|
|
342
|
+
}
|
|
343
|
+
async removeIndex(_tableName, _indexName) {
|
|
344
|
+
throw new Error(CrateDBDialect.NO_CREATE_INDEX);
|
|
345
|
+
}
|
|
346
|
+
async dropIndex(_tableName, _indexName, _options) {
|
|
347
|
+
throw new Error(CrateDBDialect.NO_CREATE_INDEX);
|
|
348
|
+
}
|
|
349
|
+
// ---------------------------------------------------------------------------
|
|
350
|
+
// CrateDB has no FOREIGN KEY support. The inherited Postgres methods would
|
|
351
|
+
// emit FK DDL that CrateDB rejects, so reject FK operations explicitly.
|
|
352
|
+
// ---------------------------------------------------------------------------
|
|
353
|
+
async addForeignKey(_tableName, _columnName, _referencedTableName, _referencedColumnName, _options) {
|
|
354
|
+
throw new Error('CrateDB does not support foreign keys.');
|
|
355
|
+
}
|
|
356
|
+
async addConstraint(tableName, options) {
|
|
357
|
+
if (options.type === 'FOREIGN KEY') {
|
|
358
|
+
throw new Error('CrateDB does not support foreign keys.');
|
|
359
|
+
}
|
|
360
|
+
return super.addConstraint(tableName, options);
|
|
361
|
+
}
|
|
362
|
+
async createConstraint(tableName, constraintDef) {
|
|
363
|
+
if (constraintDef.type === 'FOREIGN KEY') {
|
|
364
|
+
throw new Error('CrateDB does not support foreign keys.');
|
|
365
|
+
}
|
|
366
|
+
return super.createConstraint(tableName, constraintDef);
|
|
367
|
+
}
|
|
368
|
+
// ---------------------------------------------------------------------------
|
|
369
|
+
// ALTER TABLE differences.
|
|
370
|
+
// ---------------------------------------------------------------------------
|
|
371
|
+
/**
|
|
372
|
+
* Add a column via `ALTER TABLE t ADD COLUMN ...`. Overrides the Postgres
|
|
373
|
+
* implementation so the column uses CrateDB's type mapping and drops any FK
|
|
374
|
+
* reference (CrateDB supports ADD COLUMN but not SERIAL/REFERENCES).
|
|
375
|
+
*/
|
|
376
|
+
async addColumn(tableName, columnName, definition) {
|
|
377
|
+
const columnSql = this.getCrateColumnDefinitionSql(columnName, definition);
|
|
378
|
+
if (!columnSql)
|
|
379
|
+
return;
|
|
380
|
+
await this.query(`ALTER TABLE ${this.escapeId(tableName)} ADD COLUMN ${columnSql}`);
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* CrateDB cannot rename columns via ALTER TABLE (no `RENAME COLUMN`).
|
|
384
|
+
*/
|
|
385
|
+
async renameColumn(_tableName, _oldColumnName, _newColumnName) {
|
|
386
|
+
throw new Error('CrateDB does not support renaming columns.');
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* CrateDB cannot rename tables via ALTER TABLE (no `RENAME TO`).
|
|
390
|
+
*/
|
|
391
|
+
async renameTable(_oldName, _newName) {
|
|
392
|
+
throw new Error('CrateDB does not support renaming tables.');
|
|
393
|
+
}
|
|
394
|
+
// ---------------------------------------------------------------------------
|
|
395
|
+
// INSERT / UPSERT. CrateDB supports `ON CONFLICT (pk) DO UPDATE SET ...`
|
|
396
|
+
// (identical to Postgres — buildUpsertQuery / buildInsertQuery upsert output
|
|
397
|
+
// is reused unchanged) and additionally `ON CONFLICT [(pk)] DO NOTHING`.
|
|
398
|
+
// ---------------------------------------------------------------------------
|
|
399
|
+
buildInsertQuery(tableName, values, options) {
|
|
400
|
+
if (options?.onConflictDoNothing) {
|
|
401
|
+
// Build a plain INSERT (no upsert/RETURNING), then append DO NOTHING and
|
|
402
|
+
// RETURNING in the correct order. CrateDB allows DO NOTHING without a
|
|
403
|
+
// conflict target, so conflictFields is optional here.
|
|
404
|
+
const base = super.buildInsertQuery(tableName, values, {
|
|
405
|
+
...options,
|
|
406
|
+
upsert: false,
|
|
407
|
+
returning: undefined,
|
|
408
|
+
});
|
|
409
|
+
let sql = base.sql + ' ON CONFLICT';
|
|
410
|
+
if (options.conflictFields && options.conflictFields.length > 0) {
|
|
411
|
+
sql += ` (${options.conflictFields.map((c) => this.escapeId(c)).join(', ')})`;
|
|
412
|
+
}
|
|
413
|
+
sql += ' DO NOTHING';
|
|
414
|
+
if (options.returning === true) {
|
|
415
|
+
sql += ' RETURNING *';
|
|
416
|
+
}
|
|
417
|
+
else if (Array.isArray(options.returning)) {
|
|
418
|
+
sql += ` RETURNING ${options.returning.map((c) => this.escapeId(c)).join(', ')}`;
|
|
419
|
+
}
|
|
420
|
+
return { sql, values: base.values };
|
|
421
|
+
}
|
|
422
|
+
return super.buildInsertQuery(tableName, values, options);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
exports.CrateDBDialect = CrateDBDialect;
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
// CrateDB has no CREATE INDEX / DROP INDEX. Every column is auto-indexed, and
|
|
428
|
+
// fulltext indexes must be declared at CREATE TABLE (see fulltextIndexes /
|
|
429
|
+
// buildCreateTableSQL). The inherited Postgres index methods would emit SQL
|
|
430
|
+
// CrateDB rejects, so they're overridden to throw with actionable guidance.
|
|
431
|
+
// ---------------------------------------------------------------------------
|
|
432
|
+
CrateDBDialect.NO_CREATE_INDEX = 'CrateDB has no CREATE INDEX statement: all columns are automatically indexed. ' +
|
|
433
|
+
'For fulltext search, declare a fulltext index at CREATE TABLE via the ' +
|
|
434
|
+
'fulltextIndexes option (INDEX ... USING FULLTEXT (...)).';
|
|
435
|
+
/**
|
|
436
|
+
* Create a new CrateDB dialect instance
|
|
437
|
+
*/
|
|
438
|
+
function createCrateDBDialect(options) {
|
|
439
|
+
return new CrateDBDialect(options || {});
|
|
440
|
+
}
|
|
441
|
+
exports.default = CrateDBDialect;
|