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,169 @@
1
+ "use strict";
2
+ /**
3
+ * Apache Doris store.
4
+ *
5
+ * Apache Doris is a real-time MPP analytical (OLAP) database. Like StarRocks
6
+ * (with which it shares ancestry), it speaks the **MySQL wire protocol**, so
7
+ * it is queried with the `mysql2` driver over a normal MySQL connection/pool.
8
+ * Doris is a columnar analytics engine rather than an OLTP store, which does
9
+ * not fit this ORM's SQL `Dialect` abstraction cleanly, so it is modelled as
10
+ * a `NoSqlStore` (`src/nosql/store.ts`) exposing a direct `query`/`ingest`
11
+ * surface.
12
+ *
13
+ * ## Driver: `mysql2` (MySQL-wire)
14
+ *
15
+ * The `mysql2` package is an optional peer dependency, lazily `require`d
16
+ * inside `connect()` so importing this module never forces it to be
17
+ * installed. Tests inject a pre-built mock connection via
18
+ * `DorisStoreOptions.client`, which skips the `require` entirely.
19
+ *
20
+ * ## Ingestion
21
+ *
22
+ * `ingest()` performs a batched `INSERT` over the MySQL wire. For
23
+ * high-throughput loading Doris also offers **Stream Load** (an HTTP
24
+ * `PUT /api/{db}/{table}/_stream_load` endpoint). Stream Load is a separate
25
+ * (optional) HTTP transport and is intentionally not wired here; use the
26
+ * `mysql2`-based `ingest()` for wire-level inserts, or POST to the Stream Load
27
+ * endpoint yourself for bulk pipelines.
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.DorisStore = void 0;
31
+ const errors_1 = require("../../errors");
32
+ /**
33
+ * `DorisStore` wraps a `mysql2` connection to a Doris frontend and exposes
34
+ * `query(sql, params)` for reads/DDL and `ingest(table, rows)` for batched
35
+ * wire-level inserts.
36
+ */
37
+ class DorisStore {
38
+ constructor(options = {}) {
39
+ this.name = 'doris';
40
+ this.library = 'mysql2';
41
+ this.client = null;
42
+ this.connected = false;
43
+ this.options = options;
44
+ }
45
+ // ---------------------------------------------------------------------
46
+ // NoSqlStore lifecycle
47
+ // ---------------------------------------------------------------------
48
+ async connect() {
49
+ if (this.connected && this.client) {
50
+ return;
51
+ }
52
+ try {
53
+ let client = this.options.client;
54
+ if (!client) {
55
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
56
+ const mysql = require('mysql2/promise');
57
+ client = (await mysql.createConnection({
58
+ host: this.options.host,
59
+ port: this.options.port,
60
+ user: this.options.user,
61
+ password: this.options.password,
62
+ database: this.options.database,
63
+ ...this.options.connectionOptions,
64
+ }));
65
+ }
66
+ this.client = client;
67
+ this.connected = true;
68
+ }
69
+ catch (err) {
70
+ this.client = null;
71
+ this.connected = false;
72
+ const parent = err instanceof Error ? err : new Error(String(err));
73
+ throw new errors_1.ConnectionError(`Unable to connect to Doris: ${parent.message}`, {
74
+ parent,
75
+ database: 'doris',
76
+ host: this.options.host,
77
+ });
78
+ }
79
+ }
80
+ async disconnect() {
81
+ if (this.client) {
82
+ try {
83
+ await this.client.end?.();
84
+ }
85
+ finally {
86
+ this.client = null;
87
+ this.connected = false;
88
+ }
89
+ }
90
+ else {
91
+ this.connected = false;
92
+ }
93
+ }
94
+ isConnected() {
95
+ return this.connected && this.client !== null;
96
+ }
97
+ /** Returns the underlying `mysql2` connection for anything not wrapped here. */
98
+ getClient() {
99
+ return this.requireClient();
100
+ }
101
+ requireClient() {
102
+ if (!this.client || !this.connected) {
103
+ throw new errors_1.ConnectionError('Doris client is not connected. Call connect() first.', {
104
+ database: 'doris',
105
+ });
106
+ }
107
+ return this.client;
108
+ }
109
+ // ---------------------------------------------------------------------
110
+ // Query + ingest
111
+ // ---------------------------------------------------------------------
112
+ /**
113
+ * Execute a SQL statement over the MySQL wire with optional positional
114
+ * `params` and return the result rows (the first element of `mysql2`'s
115
+ * `[rows, fields]` tuple).
116
+ */
117
+ async query(sql, params) {
118
+ const client = this.requireClient();
119
+ try {
120
+ const [rows] = await client.query(sql, params);
121
+ return (rows ?? []);
122
+ }
123
+ catch (err) {
124
+ const parent = err instanceof Error ? err : new Error(String(err));
125
+ throw errors_1.DatabaseError.from(parent, {
126
+ message: `Doris query failed: ${parent.message}`,
127
+ sql,
128
+ });
129
+ }
130
+ }
131
+ /**
132
+ * Batch-insert `rows` into `table` via a single parameterized
133
+ * `INSERT INTO table (cols) VALUES (...)` over the MySQL wire. Columns are
134
+ * taken from the first row. Returns the driver result (`OkPacket`).
135
+ *
136
+ * For high-throughput bulk loading, use Doris Stream Load (HTTP) instead —
137
+ * see the module header.
138
+ */
139
+ async ingest(table, rows) {
140
+ if (rows.length === 0) {
141
+ throw new errors_1.DatabaseError('ingest() requires at least one row', {
142
+ original: 'empty rows array',
143
+ });
144
+ }
145
+ const columns = Object.keys(rows[0]);
146
+ if (columns.length === 0) {
147
+ throw new errors_1.DatabaseError('ingest() requires at least one column', {
148
+ original: 'empty row object',
149
+ });
150
+ }
151
+ const values = rows.map((r) => columns.map((c) => r[c]));
152
+ const client = this.requireClient();
153
+ // mysql2 expands a single `?` bound to a nested array into a bulk VALUES list.
154
+ const sql = `INSERT INTO ${table} (${columns.join(', ')}) VALUES ?`;
155
+ try {
156
+ const [result] = await client.query(sql, [values]);
157
+ return result;
158
+ }
159
+ catch (err) {
160
+ const parent = err instanceof Error ? err : new Error(String(err));
161
+ throw errors_1.DatabaseError.from(parent, {
162
+ message: `Doris ingest failed: ${parent.message}`,
163
+ sql,
164
+ });
165
+ }
166
+ }
167
+ }
168
+ exports.DorisStore = DorisStore;
169
+ exports.default = DorisStore;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ /**
3
+ * Apache Druid store.
4
+ *
5
+ * Druid is a real-time OLAP / analytics datastore designed for sub-second
6
+ * queries over large event streams. It is not a relational database: it has
7
+ * no cross-datasource joins in the classic sense, no row-level UPDATE/DELETE,
8
+ * and ingestion happens by submitting *tasks* to an indexing service rather
9
+ * than by running `INSERT`. That model does not fit the SQL-shaped `Dialect`
10
+ * interface (`src/dialects/dialect.ts`), so this class implements the minimal
11
+ * `NoSqlStore` marker interface (`src/nosql/store.ts`) and talks to Druid's
12
+ * HTTP JSON API directly.
13
+ *
14
+ * ## No canonical driver - HTTP over `fetch`
15
+ *
16
+ * Druid has no single canonical npm client; it is just an HTTP/JSON API.
17
+ * Rather than depend on any package this store uses the global `fetch`. Tests
18
+ * (and callers wanting their own transport) can inject an alternative client
19
+ * via `DruidStoreOptions.client`; when omitted a tiny `fetch`-based client is
20
+ * built against `endpoint` at `connect()` time.
21
+ *
22
+ * ## Endpoints wrapped
23
+ *
24
+ * - `query(sql, params?)` -> `POST /druid/v2/sql` (Druid SQL, returns rows)
25
+ * - `nativeQuery(spec)` -> `POST /druid/v2` (native JSON query)
26
+ * - `ingest(target, rows)` -> `POST /druid/indexer/v1/task` (inline index task)
27
+ * - `submitTask(spec)` -> `POST /druid/indexer/v1/task` (arbitrary task spec)
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.DruidStore = exports.DEFAULT_DRUID_ENDPOINT = void 0;
31
+ exports.createFetchClient = createFetchClient;
32
+ const errors_1 = require("../../errors");
33
+ /** Default Druid router/broker HTTP endpoint. */
34
+ exports.DEFAULT_DRUID_ENDPOINT = 'http://localhost:8888';
35
+ /** Build a `fetch`-backed client for the given endpoint. */
36
+ function createFetchClient(endpoint, headers) {
37
+ const base = endpoint.endsWith('/') ? endpoint.slice(0, -1) : endpoint;
38
+ return {
39
+ async post(path, body) {
40
+ const res = await fetch(`${base}${path}`, {
41
+ method: 'POST',
42
+ headers: { 'Content-Type': 'application/json', ...(headers ?? {}) },
43
+ body: JSON.stringify(body),
44
+ });
45
+ if (!res.ok) {
46
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
47
+ }
48
+ const text = await res.text();
49
+ return text ? JSON.parse(text) : undefined;
50
+ },
51
+ };
52
+ }
53
+ /**
54
+ * `DruidStore` wraps Druid's HTTP query + indexing API behind the
55
+ * `NoSqlStore` lifecycle: SQL and native queries for reads, task submission
56
+ * for ingestion.
57
+ */
58
+ class DruidStore {
59
+ constructor(options = {}) {
60
+ this.name = 'druid';
61
+ this.library = 'fetch';
62
+ this.client = null;
63
+ this.connected = false;
64
+ this.endpoint = options.endpoint ?? exports.DEFAULT_DRUID_ENDPOINT;
65
+ this.injectedClient = options.client;
66
+ this.headers = options.headers;
67
+ }
68
+ // ---------------------------------------------------------------------
69
+ // Connection lifecycle
70
+ // ---------------------------------------------------------------------
71
+ async connect() {
72
+ if (this.connected && this.client) {
73
+ return;
74
+ }
75
+ this.client = this.injectedClient ?? createFetchClient(this.endpoint, this.headers);
76
+ this.connected = true;
77
+ }
78
+ async disconnect() {
79
+ this.client = null;
80
+ this.connected = false;
81
+ }
82
+ isConnected() {
83
+ return this.connected && this.client !== null;
84
+ }
85
+ /** Returns the underlying (internal or injected) HTTP client. */
86
+ getClient() {
87
+ return this.requireClient();
88
+ }
89
+ requireClient() {
90
+ if (!this.client || !this.connected) {
91
+ throw new errors_1.ConnectionError('Not connected to Druid. Call connect() first.', {
92
+ database: 'druid',
93
+ host: this.endpoint,
94
+ });
95
+ }
96
+ return this.client;
97
+ }
98
+ async post(path, body, action) {
99
+ const client = this.requireClient();
100
+ try {
101
+ return await client.post(path, body);
102
+ }
103
+ catch (err) {
104
+ const parent = err instanceof Error ? err : new Error(String(err));
105
+ throw errors_1.DatabaseError.from(parent, { message: `Druid ${action} failed: ${parent.message}` });
106
+ }
107
+ }
108
+ // ---------------------------------------------------------------------
109
+ // Query API
110
+ // ---------------------------------------------------------------------
111
+ /**
112
+ * Run a Druid SQL query via `POST /druid/v2/sql`. Optional positional
113
+ * `params` are sent as Druid SQL parameters (`{ value }` objects). Druid
114
+ * returns an array of row objects, which is returned as-is.
115
+ */
116
+ async query(sql, params) {
117
+ const body = { query: sql };
118
+ if (params && params.length > 0) {
119
+ body.parameters = params.map((value) => ({ value }));
120
+ }
121
+ const rows = await this.post('/druid/v2/sql', body, 'query');
122
+ return (rows ?? []);
123
+ }
124
+ /**
125
+ * Run a native (JSON) Druid query via `POST /druid/v2`. Returns the parsed
126
+ * response body (shape depends on the native query type).
127
+ */
128
+ async nativeQuery(spec) {
129
+ return (await this.post('/druid/v2', spec, 'nativeQuery'));
130
+ }
131
+ // ---------------------------------------------------------------------
132
+ // Ingestion (indexing tasks)
133
+ // ---------------------------------------------------------------------
134
+ /**
135
+ * Ingest `rows` into datasource `target` by submitting an inline
136
+ * `index_parallel` task to `POST /druid/indexer/v1/task`. Returns the task
137
+ * submission response (typically `{ task: '<id>' }`).
138
+ */
139
+ async ingest(target, rows) {
140
+ const spec = {
141
+ type: 'index_parallel',
142
+ spec: {
143
+ dataSchema: { dataSource: target },
144
+ ioConfig: {
145
+ type: 'index_parallel',
146
+ inputSource: {
147
+ type: 'inline',
148
+ data: rows.map((r) => JSON.stringify(r)).join('\n'),
149
+ },
150
+ inputFormat: { type: 'json' },
151
+ },
152
+ },
153
+ };
154
+ return this.submitTask(spec);
155
+ }
156
+ /** Submit an arbitrary task spec to `POST /druid/indexer/v1/task`. */
157
+ async submitTask(spec) {
158
+ return this.post('/druid/indexer/v1/task', spec, 'submitTask');
159
+ }
160
+ }
161
+ exports.DruidStore = DruidStore;
162
+ exports.default = DruidStore;