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.
Files changed (310) hide show
  1. package/CHANGELOG.md +1111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +573 -0
  4. package/dist/audit/history-query.js +180 -0
  5. package/dist/audit/index.js +23 -0
  6. package/dist/audit/logger.js +236 -0
  7. package/dist/cache/cache-manager.js +84 -0
  8. package/dist/cache/index.js +16 -0
  9. package/dist/cache/redis-cluster-cache.js +557 -0
  10. package/dist/cli.js +2200 -0
  11. package/dist/compliance/audit-trail.js +68 -0
  12. package/dist/compliance/backup-verification.js +685 -0
  13. package/dist/compliance/breach-detector.js +505 -0
  14. package/dist/compliance/consent-record.js +227 -0
  15. package/dist/compliance/consent-versioning.js +331 -0
  16. package/dist/compliance/cross-border-log.js +530 -0
  17. package/dist/compliance/data-classifier.js +258 -0
  18. package/dist/compliance/data-lineage.js +565 -0
  19. package/dist/compliance/data-masker.js +303 -0
  20. package/dist/compliance/data-portability.js +265 -0
  21. package/dist/compliance/data-retention.js +195 -0
  22. package/dist/compliance/dsar-workflow.js +342 -0
  23. package/dist/compliance/field-encryption.js +223 -0
  24. package/dist/compliance/immutable-record.js +148 -0
  25. package/dist/compliance/index.js +260 -0
  26. package/dist/compliance/privacy-impact-assessment.js +364 -0
  27. package/dist/compliance/pseudonymization.js +269 -0
  28. package/dist/compliance/query-firewall.js +1182 -0
  29. package/dist/compliance/rate-limiter.js +580 -0
  30. package/dist/compliance/right-to-erasure.js +117 -0
  31. package/dist/compliance/row-level-security.js +246 -0
  32. package/dist/compliance/security-decorator.js +574 -0
  33. package/dist/compliance/security-monitor.js +525 -0
  34. package/dist/compliance/sensitive-data-discovery.js +476 -0
  35. package/dist/compliance/session-isolation.js +472 -0
  36. package/dist/compliance/tls-enforcer.js +108 -0
  37. package/dist/compliance/worm-storage.js +712 -0
  38. package/dist/connection-manager.js +198 -0
  39. package/dist/connection-pool.js +519 -0
  40. package/dist/decorators/audit.js +136 -0
  41. package/dist/decorators/belongs-to-many.js +115 -0
  42. package/dist/decorators/belongs-to.js +115 -0
  43. package/dist/decorators/check.js +435 -0
  44. package/dist/decorators/collate.js +329 -0
  45. package/dist/decorators/comment.js +205 -0
  46. package/dist/decorators/database-settings.js +236 -0
  47. package/dist/decorators/default.js +244 -0
  48. package/dist/decorators/encryption.js +235 -0
  49. package/dist/decorators/engine.js +97 -0
  50. package/dist/decorators/fk-constraints.js +594 -0
  51. package/dist/decorators/foreign-table.js +136 -0
  52. package/dist/decorators/generated.js +274 -0
  53. package/dist/decorators/has-many.js +127 -0
  54. package/dist/decorators/has-one.js +116 -0
  55. package/dist/decorators/hstore.js +129 -0
  56. package/dist/decorators/index.js +355 -0
  57. package/dist/decorators/json-column.js +83 -0
  58. package/dist/decorators/jsonb.js +101 -0
  59. package/dist/decorators/orm-decorators.js +425 -0
  60. package/dist/decorators/permissions.js +294 -0
  61. package/dist/decorators/procedure.js +210 -0
  62. package/dist/decorators/query-options.js +556 -0
  63. package/dist/decorators/range.js +167 -0
  64. package/dist/decorators/set-column.js +83 -0
  65. package/dist/decorators/spatial.js +114 -0
  66. package/dist/decorators/storage.js +580 -0
  67. package/dist/decorators/timezone.js +512 -0
  68. package/dist/decorators/trigger.js +90 -0
  69. package/dist/decorators/uuid.js +135 -0
  70. package/dist/decorators/view.js +258 -0
  71. package/dist/diagrams/chen-diagram.js +354 -0
  72. package/dist/diagrams/class-diagram.js +384 -0
  73. package/dist/diagrams/dependency-diagram.js +432 -0
  74. package/dist/diagrams/er-diagram.js +605 -0
  75. package/dist/diagrams/flow-diagram.js +394 -0
  76. package/dist/diagrams/gantt-diagram.js +411 -0
  77. package/dist/diagrams/index-diagram.js +353 -0
  78. package/dist/diagrams/index.js +184 -0
  79. package/dist/diagrams/migration-diagram.js +316 -0
  80. package/dist/diagrams/model-diagram.js +616 -0
  81. package/dist/diagrams/package-diagram.js +376 -0
  82. package/dist/diagrams/palette.js +85 -0
  83. package/dist/diagrams/relational-diagram.js +455 -0
  84. package/dist/diagrams/schemadoc-diagram.js +309 -0
  85. package/dist/diagrams/sequence-diagram.js +307 -0
  86. package/dist/diagrams/state-diagram.js +344 -0
  87. package/dist/diagrams/svg-dom.js +111 -0
  88. package/dist/diagrams/tree-diagram.js +250 -0
  89. package/dist/dialects/clickhouse/index.js +1742 -0
  90. package/dist/dialects/cockroachdb/index.js +4677 -0
  91. package/dist/dialects/cratedb/index.js +441 -0
  92. package/dist/dialects/databricks/index.js +517 -0
  93. package/dist/dialects/db2/index.js +2225 -0
  94. package/dist/dialects/dialect.js +720 -0
  95. package/dist/dialects/duckdb/index.js +2014 -0
  96. package/dist/dialects/exasol/index.js +357 -0
  97. package/dist/dialects/firebird/index.js +495 -0
  98. package/dist/dialects/greenplum/index.js +457 -0
  99. package/dist/dialects/hana/index.js +1741 -0
  100. package/dist/dialects/mariadb/index.js +3590 -0
  101. package/dist/dialects/mssql/index.js +2296 -0
  102. package/dist/dialects/mysql/index.js +4058 -0
  103. package/dist/dialects/oracle/index.js +2999 -0
  104. package/dist/dialects/postgres/index.js +5319 -0
  105. package/dist/dialects/query-stream-helper.js +152 -0
  106. package/dist/dialects/questdb/index.js +433 -0
  107. package/dist/dialects/redshift/index.js +2277 -0
  108. package/dist/dialects/singlestore/index.js +354 -0
  109. package/dist/dialects/snowflake/index.js +2082 -0
  110. package/dist/dialects/spanner/index.js +1768 -0
  111. package/dist/dialects/sqlite/index.js +3382 -0
  112. package/dist/dialects/tidb/index.js +377 -0
  113. package/dist/dialects/timescaledb/index.js +164 -0
  114. package/dist/dialects/trino/index.js +420 -0
  115. package/dist/dialects/turso/index.js +227 -0
  116. package/dist/dialects/vertica/index.js +317 -0
  117. package/dist/dialects/yugabytedb/index.js +424 -0
  118. package/dist/errors/index.js +472 -0
  119. package/dist/errors/utils.js +340 -0
  120. package/dist/errors.js +21 -0
  121. package/dist/extensions/catalog/cloud-warehouse-features.js +207 -0
  122. package/dist/extensions/catalog/mssql-features.js +147 -0
  123. package/dist/extensions/catalog/mysql-mariadb-plugins.js +229 -0
  124. package/dist/extensions/catalog/oracle-db2-features.js +196 -0
  125. package/dist/extensions/catalog/postgres-extensions.js +516 -0
  126. package/dist/extensions/index.js +71 -0
  127. package/dist/extensions/types.js +13 -0
  128. package/dist/foreign-data.js +173 -0
  129. package/dist/hooks/hooks-manager.js +350 -0
  130. package/dist/hooks/index.js +37 -0
  131. package/dist/index.js +463 -0
  132. package/dist/logging.js +335 -0
  133. package/dist/migrations/index.js +40 -0
  134. package/dist/migrations/migration.js +196 -0
  135. package/dist/migrations/migrator.js +411 -0
  136. package/dist/migrations/prormmigration.js +275 -0
  137. package/dist/migrations/query-interface.js +435 -0
  138. package/dist/migrations/seeder.js +353 -0
  139. package/dist/models/associations.js +852 -0
  140. package/dist/models/constraints.js +288 -0
  141. package/dist/models/data-types.js +2518 -0
  142. package/dist/models/decorators.js +445 -0
  143. package/dist/models/index.js +33 -0
  144. package/dist/models/indexes.js +531 -0
  145. package/dist/models/methods.js +382 -0
  146. package/dist/models/model-manager.js +103 -0
  147. package/dist/models/model.js +5349 -0
  148. package/dist/models/operators.js +67 -0
  149. package/dist/models/scopes.js +189 -0
  150. package/dist/models/typescript-types.js +26 -0
  151. package/dist/nosql/aerospike/index.js +205 -0
  152. package/dist/nosql/allegrograph/index.js +169 -0
  153. package/dist/nosql/arangodb/index.js +364 -0
  154. package/dist/nosql/azure-blob/index.js +206 -0
  155. package/dist/nosql/beanstalkd/index.js +231 -0
  156. package/dist/nosql/beequeue/index.js +210 -0
  157. package/dist/nosql/bigchaindb/index.js +195 -0
  158. package/dist/nosql/bigtable/index.js +224 -0
  159. package/dist/nosql/blazegraph/index.js +173 -0
  160. package/dist/nosql/bullmq/index.js +191 -0
  161. package/dist/nosql/cassandra/index.js +174 -0
  162. package/dist/nosql/chroma/index.js +190 -0
  163. package/dist/nosql/cloudflare-kv/index.js +220 -0
  164. package/dist/nosql/coherence/index.js +200 -0
  165. package/dist/nosql/cosmosdb/index.js +157 -0
  166. package/dist/nosql/couchbase/index.js +213 -0
  167. package/dist/nosql/dax/index.js +212 -0
  168. package/dist/nosql/deno-kv/index.js +206 -0
  169. package/dist/nosql/dgraph/index.js +171 -0
  170. package/dist/nosql/doris/index.js +169 -0
  171. package/dist/nosql/druid/index.js +162 -0
  172. package/dist/nosql/dynamodb/index.js +937 -0
  173. package/dist/nosql/elasticsearch/index.js +377 -0
  174. package/dist/nosql/etcd/index.js +502 -0
  175. package/dist/nosql/eventhubs/index.js +213 -0
  176. package/dist/nosql/eventstore/index.js +254 -0
  177. package/dist/nosql/faunadb/index.js +188 -0
  178. package/dist/nosql/firestore/index.js +177 -0
  179. package/dist/nosql/fluree/index.js +148 -0
  180. package/dist/nosql/fuseki/index.js +170 -0
  181. package/dist/nosql/gcs/index.js +172 -0
  182. package/dist/nosql/gearman/index.js +160 -0
  183. package/dist/nosql/geode/index.js +196 -0
  184. package/dist/nosql/graphdb/index.js +169 -0
  185. package/dist/nosql/graylog/index.js +188 -0
  186. package/dist/nosql/gridgain/index.js +171 -0
  187. package/dist/nosql/hazelcast/index.js +162 -0
  188. package/dist/nosql/hbase/index.js +230 -0
  189. package/dist/nosql/ignite/index.js +173 -0
  190. package/dist/nosql/immudb/index.js +184 -0
  191. package/dist/nosql/index.js +232 -0
  192. package/dist/nosql/infinispan/index.js +200 -0
  193. package/dist/nosql/influxdb/index.js +0 -0
  194. package/dist/nosql/kafka/index.js +234 -0
  195. package/dist/nosql/keyspaces/index.js +189 -0
  196. package/dist/nosql/kinesis/index.js +253 -0
  197. package/dist/nosql/leveldb/index.js +153 -0
  198. package/dist/nosql/lmdb/index.js +160 -0
  199. package/dist/nosql/loki/index.js +201 -0
  200. package/dist/nosql/marklogic/index.js +204 -0
  201. package/dist/nosql/materialize/index.js +145 -0
  202. package/dist/nosql/meilisearch/index.js +154 -0
  203. package/dist/nosql/memcached/index.js +223 -0
  204. package/dist/nosql/milvus/index.js +410 -0
  205. package/dist/nosql/minio/index.js +265 -0
  206. package/dist/nosql/momento/index.js +179 -0
  207. package/dist/nosql/mongodb/index.js +461 -0
  208. package/dist/nosql/nats/index.js +247 -0
  209. package/dist/nosql/nedb/index.js +164 -0
  210. package/dist/nosql/neo4j/index.js +450 -0
  211. package/dist/nosql/neptune/index.js +470 -0
  212. package/dist/nosql/nsq/index.js +200 -0
  213. package/dist/nosql/opensearch/index.js +186 -0
  214. package/dist/nosql/orientdb/index.js +175 -0
  215. package/dist/nosql/papertrail/index.js +200 -0
  216. package/dist/nosql/pinecone/index.js +0 -0
  217. package/dist/nosql/pinot/index.js +133 -0
  218. package/dist/nosql/pouchdb/index.js +172 -0
  219. package/dist/nosql/prometheus/index.js +174 -0
  220. package/dist/nosql/provendb/index.js +147 -0
  221. package/dist/nosql/pubsub/index.js +187 -0
  222. package/dist/nosql/pulsar/index.js +232 -0
  223. package/dist/nosql/qdrant/index.js +295 -0
  224. package/dist/nosql/qldb/index.js +192 -0
  225. package/dist/nosql/r2/index.js +281 -0
  226. package/dist/nosql/rabbitmq/index.js +237 -0
  227. package/dist/nosql/ravendb/index.js +175 -0
  228. package/dist/nosql/redis/index.js +607 -0
  229. package/dist/nosql/redpanda/index.js +237 -0
  230. package/dist/nosql/resque/index.js +203 -0
  231. package/dist/nosql/rethinkdb/index.js +232 -0
  232. package/dist/nosql/rocksdb/index.js +152 -0
  233. package/dist/nosql/rockset/index.js +126 -0
  234. package/dist/nosql/s3/index.js +298 -0
  235. package/dist/nosql/scylladb/index.js +178 -0
  236. package/dist/nosql/signoz/index.js +227 -0
  237. package/dist/nosql/sns/index.js +201 -0
  238. package/dist/nosql/solr/index.js +231 -0
  239. package/dist/nosql/splunk/index.js +227 -0
  240. package/dist/nosql/sqs/index.js +246 -0
  241. package/dist/nosql/stardog/index.js +169 -0
  242. package/dist/nosql/starrocks/index.js +170 -0
  243. package/dist/nosql/store.js +2 -0
  244. package/dist/nosql/sumologic/index.js +213 -0
  245. package/dist/nosql/surrealdb/index.js +179 -0
  246. package/dist/nosql/terminusdb/index.js +151 -0
  247. package/dist/nosql/tigergraph/index.js +469 -0
  248. package/dist/nosql/typesense/index.js +148 -0
  249. package/dist/nosql/unqlite/index.js +157 -0
  250. package/dist/nosql/upstash/index.js +167 -0
  251. package/dist/nosql/vercel-kv/index.js +166 -0
  252. package/dist/nosql/victoriametrics/index.js +213 -0
  253. package/dist/nosql/virtuoso/index.js +169 -0
  254. package/dist/nosql/weaviate/index.js +276 -0
  255. package/dist/operators/index.js +108 -0
  256. package/dist/operators.js +2690 -0
  257. package/dist/prisma-migrate/index.js +38 -0
  258. package/dist/prisma-migrate/migration-generator.js +125 -0
  259. package/dist/prisma-migrate/model-generator.js +172 -0
  260. package/dist/prisma-migrate/relations.js +100 -0
  261. package/dist/prisma-migrate/schema-parser.js +167 -0
  262. package/dist/prisma-migrate/type-mapper.js +40 -0
  263. package/dist/prorm.js +6832 -0
  264. package/dist/query-builders/cte-builder.js +80 -0
  265. package/dist/query-builders/functions/aggregate.js +390 -0
  266. package/dist/query-builders/functions/conditional.js +503 -0
  267. package/dist/query-builders/functions/datetime.js +695 -0
  268. package/dist/query-builders/functions/fulltext.js +439 -0
  269. package/dist/query-builders/functions/index.js +93 -0
  270. package/dist/query-builders/functions/json.js +427 -0
  271. package/dist/query-builders/functions/math.js +399 -0
  272. package/dist/query-builders/functions/string.js +518 -0
  273. package/dist/query-builders/functions/window.js +328 -0
  274. package/dist/query-builders/include-builder.js +323 -0
  275. package/dist/query-builders/index-expression-builder.js +242 -0
  276. package/dist/query-builders/index.js +161 -0
  277. package/dist/query-builders/insert-builder.js +164 -0
  278. package/dist/query-builders/model-helpers.js +38 -0
  279. package/dist/query-builders/order-limit-builder.js +239 -0
  280. package/dist/query-builders/sql-compiler.js +2040 -0
  281. package/dist/query-builders/subquery-builder.js +152 -0
  282. package/dist/query-builders/update-builder.js +182 -0
  283. package/dist/query-builders/view-builder.js +218 -0
  284. package/dist/query-builders/where-builder.js +1532 -0
  285. package/dist/query-interface.js +622 -0
  286. package/dist/query-optimizers/batch-optimizer.js +426 -0
  287. package/dist/query-optimizers/explain-plans.js +415 -0
  288. package/dist/query-optimizers/index.js +51 -0
  289. package/dist/query-optimizers/prepared-statement-cache.js +423 -0
  290. package/dist/query-optimizers/query-hints.js +438 -0
  291. package/dist/query-optimizers/query-optimizer.js +278 -0
  292. package/dist/query-optimizers/slow-query-logger.js +271 -0
  293. package/dist/replica-manager.js +507 -0
  294. package/dist/schema/index.js +15 -0
  295. package/dist/schema/migration-generator.js +374 -0
  296. package/dist/schema/schema-differ.js +549 -0
  297. package/dist/schema/types.js +6 -0
  298. package/dist/sql-constants.js +300 -0
  299. package/dist/sqlite-advanced.js +1047 -0
  300. package/dist/streams/index.js +12 -0
  301. package/dist/streams/transforms.js +178 -0
  302. package/dist/transaction.js +456 -0
  303. package/dist/types/index.js +180 -0
  304. package/dist/user-management.js +127 -0
  305. package/dist/utils/date.js +300 -0
  306. package/dist/utils/index.js +1079 -0
  307. package/dist/utils/string.js +161 -0
  308. package/dist/validators/index.js +19 -0
  309. package/dist/validators/validator.js +911 -0
  310. package/package.json +190 -0
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+ /**
3
+ * Exasol dialect implementation for the TypeScript ORM.
4
+ *
5
+ * Exasol is an in-memory, column-oriented, massively-parallel (MPP) analytic
6
+ * database. Its SQL grammar and wire behavior are close enough to PostgreSQL
7
+ * that this dialect extends {@link PostgresDialect} and reuses the pg-style
8
+ * grammar (double-quoted identifiers, `$1` placeholders, `ON CONFLICT`-free
9
+ * INSERTs, etc.) as its base, overriding only the places where Exasol really
10
+ * differs. Notable differences from PostgreSQL captured here:
11
+ *
12
+ * - Default SQL port is 8563 (not 5432).
13
+ * - CREATE TABLE supports MPP distribution/partitioning clauses:
14
+ * `... DISTRIBUTE BY col1, col2` controls how rows are hash-distributed
15
+ * across cluster nodes, and `... PARTITION BY col` controls on-disk
16
+ * partitioning within a node. Both are surfaced via table options and
17
+ * emitted as trailing clauses.
18
+ * - No SERIAL / BIGSERIAL. Auto-increment columns use an `IDENTITY` column
19
+ * constraint on a numeric (DECIMAL) column instead.
20
+ * - Type mapping differs: TEXT maps to `VARCHAR(2000000)` (Exasol's max
21
+ * VARCHAR width), STRING to `VARCHAR(n)`, integers to `DECIMAL(18,0)`
22
+ * (Exasol has no native narrow integer types — everything numeric is a
23
+ * DECIMAL), and DECIMAL(p,s)/BOOLEAN/TIMESTAMP map straight through.
24
+ * - Bulk load/unload uses Exasol's `IMPORT` / `EXPORT` statements against a
25
+ * file/connection endpoint rather than PostgreSQL's `COPY`.
26
+ * - Exasol upper-cases unquoted identifiers (like Oracle). This dialect quotes
27
+ * identifiers with double quotes (inherited from PostgresDialect), so the
28
+ * ORM's mixed-case names are preserved exactly rather than being folded to
29
+ * upper case.
30
+ * - Exasol has **no `RETURNING` clause** on INSERT/UPDATE/DELETE and **no
31
+ * `ON CONFLICT`**. So the write builders inherited from PostgresDialect
32
+ * (`buildInsertQuery`, `buildUpdateQuery`, `buildDeleteQuery`,
33
+ * `buildUpsertQuery`) are overridden here to strip `RETURNING` and to express
34
+ * upserts as a `MERGE INTO ... USING (SELECT ...) ON (...) WHEN MATCHED /
35
+ * WHEN NOT MATCHED` statement instead.
36
+ * - Plain SELECT (WHERE, ORDER BY, GROUP BY / HAVING, JOIN, `LIMIT ... OFFSET`)
37
+ * and `buildLimitOffset` are inherited unchanged: Exasol's SELECT grammar
38
+ * matches the PostgreSQL forms the base emits, including `LIMIT n OFFSET m`.
39
+ *
40
+ * Placeholders: this dialect keeps the PostgreSQL `$n` positional style so it
41
+ * composes with the rest of the ORM's parameter handling. Exasol's own JDBC/
42
+ * WebSocket drivers use `?`; a live driver binding would translate accordingly.
43
+ */
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.ExasolDialect = void 0;
46
+ exports.createExasolDialect = createExasolDialect;
47
+ const postgres_1 = require("../postgres");
48
+ const prorm_1 = require("../../prorm");
49
+ /**
50
+ * Exasol dialect. Extends {@link PostgresDialect}; see the file header for the
51
+ * list of Exasol-specific behaviors.
52
+ */
53
+ class ExasolDialect extends postgres_1.PostgresDialect {
54
+ constructor(config) {
55
+ // Exasol's default SQL port is 8563 (not Postgres's 5432). Caller-supplied
56
+ // config still wins over this default.
57
+ super({ port: 8563, ...config });
58
+ this.name = 'exasol';
59
+ }
60
+ /**
61
+ * Map an ORM data type to its Exasol SQL type. Overrides the Postgres
62
+ * mapping for the types that differ on Exasol:
63
+ * - TEXT -> VARCHAR(2000000) (Exasol's max VARCHAR width; no TEXT type)
64
+ * - STRING -> VARCHAR(n)
65
+ * - INTEGER -> DECIMAL(18,0) (no SERIAL; IDENTITY is applied separately)
66
+ * - BIGINT -> DECIMAL(36,0)
67
+ * - DECIMAL -> DECIMAL(p,s)
68
+ * - BOOLEAN -> BOOLEAN
69
+ * - DATE -> TIMESTAMP
70
+ * Everything else delegates to the PostgreSQL mapping.
71
+ */
72
+ getDataTypeSql(dataType) {
73
+ if (typeof dataType === 'string') {
74
+ // Normalize the cross-dialect DATETIME pseudo-type to TIMESTAMP, matching
75
+ // the Postgres base behavior.
76
+ if (/^DATETIME(\(\d+\))?$/i.test(dataType)) {
77
+ return dataType.replace(/^DATETIME/i, 'TIMESTAMP');
78
+ }
79
+ return dataType;
80
+ }
81
+ if (!dataType || typeof dataType !== 'object') {
82
+ return super.getDataTypeSql(dataType);
83
+ }
84
+ const dt = dataType;
85
+ switch (dt.key) {
86
+ case 'TEXT':
87
+ // Exasol has no TEXT type; use its maximum-width VARCHAR.
88
+ return 'VARCHAR(2000000)';
89
+ case 'STRING':
90
+ return `VARCHAR(${dt.length || 255})`;
91
+ case 'CHAR':
92
+ return `CHAR(${dt.length || 1})`;
93
+ case 'INTEGER':
94
+ // No SERIAL on Exasol - auto-increment is handled via IDENTITY in the
95
+ // column definition, so the base type is a plain numeric DECIMAL.
96
+ return 'DECIMAL(18,0)';
97
+ case 'BIGINT':
98
+ return 'DECIMAL(36,0)';
99
+ case 'DECIMAL':
100
+ return `DECIMAL(${dt.precision || 18},${dt.scale || 0})`;
101
+ case 'BOOLEAN':
102
+ return 'BOOLEAN';
103
+ case 'DATE':
104
+ return dt.precision ? `TIMESTAMP(${dt.precision})` : 'TIMESTAMP';
105
+ case 'DATEONLY':
106
+ return 'DATE';
107
+ default:
108
+ return super.getDataTypeSql(dataType);
109
+ }
110
+ }
111
+ /**
112
+ * Format a single column's definition for CREATE TABLE. Emits `IDENTITY`
113
+ * (rather than SERIAL) for auto-increment columns.
114
+ */
115
+ buildColumnSql(columnName, definition) {
116
+ let sql = `${this.escapeId(columnName)} ${this.getDataTypeSql(definition.type)}`;
117
+ if (definition.autoIncrement) {
118
+ // Exasol auto-increment: numeric column with an IDENTITY constraint.
119
+ sql += ' IDENTITY';
120
+ }
121
+ if (definition.allowNull === false) {
122
+ sql += ' NOT NULL';
123
+ }
124
+ if (definition.defaultValue !== undefined && !definition.autoIncrement) {
125
+ sql += ` DEFAULT ${this.formatDefault(definition.defaultValue)}`;
126
+ }
127
+ if (definition.primaryKey) {
128
+ sql += ' PRIMARY KEY';
129
+ }
130
+ if (definition.unique) {
131
+ // Exasol accepts a column-level UNIQUE constraint (it is tracked but not
132
+ // enforced by default, like foreign keys).
133
+ sql += ' UNIQUE';
134
+ }
135
+ if (definition.references) {
136
+ const refField = definition.references.field;
137
+ const refFieldSql = Array.isArray(refField)
138
+ ? `(${refField.map((f) => this.escapeId(f)).join(', ')})`
139
+ : `(${this.escapeId(refField)})`;
140
+ sql += ` REFERENCES ${this.escapeId(definition.references.table)}${refFieldSql}`;
141
+ }
142
+ return sql;
143
+ }
144
+ /** Format a DEFAULT value literal for a column definition. */
145
+ formatDefault(value) {
146
+ if (value === null) {
147
+ return 'NULL';
148
+ }
149
+ if (typeof value === 'string') {
150
+ if (value.toUpperCase().includes('CURRENT_') || value.toUpperCase() === 'NULL') {
151
+ return value;
152
+ }
153
+ return `'${value.replace(/'/g, "''")}'`;
154
+ }
155
+ if (typeof value === 'number' || typeof value === 'boolean') {
156
+ return String(value);
157
+ }
158
+ return `'${String(value).replace(/'/g, "''")}'`;
159
+ }
160
+ /** Render a `DISTRIBUTE BY` / `PARTITION BY` column list. */
161
+ columnList(cols) {
162
+ const arr = Array.isArray(cols) ? cols : [cols];
163
+ return arr.map((c) => this.escapeId(c)).join(', ');
164
+ }
165
+ /**
166
+ * Build a `CREATE TABLE` statement, including Exasol's MPP `DISTRIBUTE BY`
167
+ * and `PARTITION BY` clauses. Exposed synchronously so the emitted SQL can be
168
+ * built (and tested) without a live connection.
169
+ */
170
+ buildCreateTableSQL(tableName, columns, options) {
171
+ const columnDefs = Object.entries(columns).map(([name, def]) => this.buildColumnSql(name, def));
172
+ let sql = 'CREATE TABLE';
173
+ if (options?.ifNotExists) {
174
+ sql += ' IF NOT EXISTS';
175
+ }
176
+ sql += ` ${this.escapeId(tableName)} (${columnDefs.join(', ')})`;
177
+ // MPP distribution across cluster nodes.
178
+ if (options?.distributeBy) {
179
+ sql += ` DISTRIBUTE BY ${this.columnList(options.distributeBy)}`;
180
+ }
181
+ // On-disk partitioning within a node.
182
+ if (options?.partitionBy) {
183
+ sql += ` PARTITION BY ${this.columnList(options.partitionBy)}`;
184
+ }
185
+ return sql;
186
+ }
187
+ /**
188
+ * Create a table. Overrides the Postgres implementation to emit Exasol's
189
+ * IDENTITY columns and `DISTRIBUTE BY` / `PARTITION BY` clauses.
190
+ */
191
+ async createTable(tableName, columns, options) {
192
+ await this.query(this.buildCreateTableSQL(tableName, columns, options));
193
+ }
194
+ /**
195
+ * Add a column. Overrides the Postgres implementation, which would emit a
196
+ * `SERIAL` for auto-increment columns; Exasol uses `IDENTITY` instead (see
197
+ * {@link buildColumnSql}). Exasol accepts the optional `COLUMN` keyword.
198
+ */
199
+ async addColumn(tableName, columnName, definition) {
200
+ const sql = `ALTER TABLE ${this.escapeId(tableName)} ADD COLUMN ${this.buildColumnSql(columnName, definition)}`;
201
+ await this.query(sql);
202
+ }
203
+ /**
204
+ * Change a column's type. Exasol uses `ALTER TABLE ... MODIFY COLUMN col type`
205
+ * rather than PostgreSQL's `ALTER COLUMN col TYPE type`.
206
+ */
207
+ async changeColumn(tableName, columnName, definition) {
208
+ let sql = `ALTER TABLE ${this.escapeId(tableName)} MODIFY COLUMN ${this.escapeId(columnName)} ${this.getDataTypeSql(definition.type)}`;
209
+ if (definition.allowNull === false) {
210
+ sql += ' NOT NULL';
211
+ }
212
+ if (definition.defaultValue !== undefined) {
213
+ sql += ` DEFAULT ${this.formatDefault(definition.defaultValue)}`;
214
+ }
215
+ await this.query(sql);
216
+ }
217
+ /**
218
+ * Build an INSERT. Same as the PostgreSQL base but Exasol has no `RETURNING`
219
+ * clause, and upserts are expressed as a `MERGE` (Exasol has no
220
+ * `ON CONFLICT`). When `options.upsert` is set this delegates to
221
+ * {@link buildMergeSQL}; the `returning` option is ignored.
222
+ */
223
+ buildInsertQuery(tableName, values, options) {
224
+ if (options?.upsert) {
225
+ return this.buildMergeSQL(tableName, values, {
226
+ conflictFields: options.conflictFields,
227
+ updateOnDuplicate: options.updateOnDuplicate,
228
+ });
229
+ }
230
+ const columns = Object.keys(values);
231
+ const processedValues = [];
232
+ const placeholders = [];
233
+ let paramIndex = 1;
234
+ for (const value of Object.values(values)) {
235
+ if (value instanceof prorm_1.Literal) {
236
+ placeholders.push(value.val);
237
+ }
238
+ else {
239
+ placeholders.push(`$${paramIndex}`);
240
+ processedValues.push(value);
241
+ paramIndex++;
242
+ }
243
+ }
244
+ // No RETURNING on Exasol - deliberately omitted even if requested.
245
+ const sql = `INSERT INTO ${this.escapeId(tableName)} (${columns
246
+ .map((c) => this.escapeId(c))
247
+ .join(', ')}) VALUES (${placeholders.join(', ')})`;
248
+ return { sql, values: processedValues };
249
+ }
250
+ /**
251
+ * Build an UPSERT as an Exasol `MERGE` statement. Exasol has no
252
+ * `INSERT ... ON CONFLICT`.
253
+ */
254
+ buildUpsertQuery(tableName, values, options) {
255
+ return this.buildMergeSQL(tableName, values, {
256
+ conflictFields: options?.conflictFields,
257
+ updateOnDuplicate: options?.updateOnDuplicate,
258
+ });
259
+ }
260
+ /**
261
+ * Build the Exasol `MERGE INTO ... USING (SELECT ...) ON (...)` statement that
262
+ * implements an upsert for a single row of `values`.
263
+ *
264
+ * The row is presented as a one-row derived source via a FROM-less
265
+ * `SELECT $1 AS "col", ...` (Exasol permits SELECT without FROM). Rows are
266
+ * matched on `conflictFields`; matched rows are updated (excluding the
267
+ * conflict columns, which Exasol forbids updating because they appear in the
268
+ * `ON` condition) and unmatched rows are inserted.
269
+ */
270
+ buildMergeSQL(tableName, values, options) {
271
+ const conflictFields = options?.conflictFields;
272
+ if (!conflictFields || conflictFields.length === 0) {
273
+ throw new Error('buildMergeSQL: options.conflictFields is required - Exasol MERGE needs the ' +
274
+ 'key column(s) to match existing rows on, so it cannot be inferred from the ' +
275
+ 'inserted columns.');
276
+ }
277
+ const columns = Object.keys(values);
278
+ const processedValues = [];
279
+ let paramIndex = 1;
280
+ // FROM-less source select: one aliased expression per column.
281
+ const sourceExprs = columns.map((col) => {
282
+ const value = values[col];
283
+ if (value instanceof prorm_1.Literal) {
284
+ return `${value.val} AS ${this.escapeId(col)}`;
285
+ }
286
+ const placeholder = `$${paramIndex++}`;
287
+ processedValues.push(value);
288
+ return `${placeholder} AS ${this.escapeId(col)}`;
289
+ });
290
+ const onCondition = conflictFields
291
+ .map((c) => `dst.${this.escapeId(c)} = src.${this.escapeId(c)}`)
292
+ .join(' AND ');
293
+ // Columns to update on match: explicit list if given, otherwise every
294
+ // non-conflict column. Exasol forbids updating the ON-condition columns.
295
+ const conflictSet = new Set(conflictFields);
296
+ const updateFields = (options?.updateOnDuplicate && options.updateOnDuplicate.length > 0
297
+ ? options.updateOnDuplicate
298
+ : columns).filter((c) => !conflictSet.has(c));
299
+ let sql = `MERGE INTO ${this.escapeId(tableName)} dst` +
300
+ ` USING (SELECT ${sourceExprs.join(', ')}) src` +
301
+ ` ON (${onCondition})`;
302
+ if (updateFields.length > 0) {
303
+ const updateClauses = updateFields
304
+ .map((c) => `dst.${this.escapeId(c)} = src.${this.escapeId(c)}`)
305
+ .join(', ');
306
+ sql += ` WHEN MATCHED THEN UPDATE SET ${updateClauses}`;
307
+ }
308
+ const insertCols = columns.map((c) => this.escapeId(c)).join(', ');
309
+ const insertVals = columns.map((c) => `src.${this.escapeId(c)}`).join(', ');
310
+ sql += ` WHEN NOT MATCHED THEN INSERT (${insertCols}) VALUES (${insertVals})`;
311
+ return { sql, values: processedValues };
312
+ }
313
+ /**
314
+ * Build an UPDATE. Same as the PostgreSQL base, but Exasol supports neither a
315
+ * `RETURNING` clause nor a `LIMIT` on UPDATE, so both are stripped from the
316
+ * options before delegating.
317
+ */
318
+ buildUpdateQuery(tableName, values, where, options) {
319
+ const { returning: _returning, limit: _limit, ...rest } = options || {};
320
+ return super.buildUpdateQuery(tableName, values, where, rest);
321
+ }
322
+ /**
323
+ * Build a DELETE. Exasol has no `RETURNING` and no `LIMIT` on DELETE, so both
324
+ * are stripped; `truncate` (which maps to `TRUNCATE TABLE`) is preserved.
325
+ */
326
+ buildDeleteQuery(tableName, where, options) {
327
+ const { returning: _returning, limit: _limit, ...rest } = options || {};
328
+ return super.buildDeleteQuery(tableName, where, rest);
329
+ }
330
+ /**
331
+ * Build an Exasol `IMPORT INTO <table> FROM <format> AT '<endpoint>' FILE '<path>'`
332
+ * statement for bulk-loading data. `schema` on the options, if any, is not
333
+ * used here; qualify the table name yourself if needed.
334
+ */
335
+ buildImportSQL(tableName, options) {
336
+ const format = options.format || 'CSV';
337
+ return (`IMPORT INTO ${this.escapeId(tableName)} FROM ${format}` +
338
+ ` AT '${options.at.replace(/'/g, "''")}' FILE '${options.file.replace(/'/g, "''")}'`);
339
+ }
340
+ /**
341
+ * Build an Exasol `EXPORT <table> INTO <format> AT '<endpoint>' FILE '<path>'`
342
+ * statement for bulk-unloading data.
343
+ */
344
+ buildExportSQL(tableName, options) {
345
+ const format = options.format || 'CSV';
346
+ return (`EXPORT ${this.escapeId(tableName)} INTO ${format}` +
347
+ ` AT '${options.at.replace(/'/g, "''")}' FILE '${options.file.replace(/'/g, "''")}'`);
348
+ }
349
+ }
350
+ exports.ExasolDialect = ExasolDialect;
351
+ /**
352
+ * Create a new Exasol dialect instance.
353
+ */
354
+ function createExasolDialect(options) {
355
+ return new ExasolDialect(options || {});
356
+ }
357
+ exports.default = ExasolDialect;