drizzle-databend 0.1.10 → 0.1.11

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/dist/index.mjs CHANGED
@@ -1,195 +1,12 @@
1
- // src/driver.ts
2
- import { Client } from "databend-driver";
3
- import { entityKind as entityKind3 } from "drizzle-orm/entity";
4
- import { DefaultLogger } from "drizzle-orm/logger";
5
- import { PgDatabase } from "drizzle-orm/pg-core/db";
6
- import {
7
- createTableRelationsHelpers,
8
- extractTablesRelationalConfig
9
- } from "drizzle-orm/relations";
10
-
11
- // src/session.ts
12
- import { entityKind } from "drizzle-orm/entity";
13
- import { NoopLogger } from "drizzle-orm/logger";
14
- import { PgTransaction } from "drizzle-orm/pg-core";
15
- import { PgPreparedQuery, PgSession } from "drizzle-orm/pg-core/session";
16
- import { fillPlaceholders, sql } from "drizzle-orm/sql/sql";
17
-
18
- // src/sql/result-mapper.ts
19
- import {
20
- Column,
21
- SQL,
22
- getTableName,
23
- is
24
- } from "drizzle-orm";
25
- import {
26
- PgCustomColumn,
27
- PgDate,
28
- PgDateString,
29
- PgTime,
30
- PgTimestamp,
31
- PgTimestampString
32
- } from "drizzle-orm/pg-core";
33
- function toDecoderInput(decoder, value) {
34
- return value;
35
- }
36
- function normalizeTimestampString(value, withTimezone) {
37
- if (value instanceof Date) {
38
- const iso = value.toISOString().replace("T", " ");
39
- return withTimezone ? iso.replace("Z", "+00") : iso.replace("Z", "");
40
- }
41
- if (typeof value === "string") {
42
- const normalized = value.replace("T", " ");
43
- if (withTimezone) {
44
- return normalized.includes("+") ? normalized : `${normalized}+00`;
45
- }
46
- return normalized.replace(/\+00$/, "");
47
- }
48
- return value;
49
- }
50
- function normalizeTimestamp(value, withTimezone) {
51
- if (value instanceof Date) {
52
- return value;
53
- }
54
- if (typeof value === "string") {
55
- const hasOffset = value.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(value.trim());
56
- const spaced = value.replace(" ", "T");
57
- const normalized = withTimezone || hasOffset ? spaced : `${spaced}+00`;
58
- return new Date(normalized);
59
- }
60
- return value;
61
- }
62
- function normalizeDateString(value) {
63
- if (value instanceof Date) {
64
- return value.toISOString().slice(0, 10);
65
- }
66
- if (typeof value === "string") {
67
- return value.slice(0, 10);
68
- }
69
- return value;
70
- }
71
- function normalizeDateValue(value) {
72
- if (value instanceof Date) {
73
- return value;
74
- }
75
- if (typeof value === "string") {
76
- return new Date(`${value.slice(0, 10)}T00:00:00Z`);
77
- }
78
- return value;
79
- }
80
- function normalizeTime(value) {
81
- if (typeof value === "bigint") {
82
- const totalMillis = Number(value) / 1000;
83
- const date = new Date(totalMillis);
84
- return date.toISOString().split("T")[1].replace("Z", "");
85
- }
86
- if (value instanceof Date) {
87
- return value.toISOString().split("T")[1].replace("Z", "");
88
- }
89
- return value;
90
- }
91
- function mapDriverValue(decoder, rawValue) {
92
- if (is(decoder, PgTimestampString)) {
93
- return decoder.mapFromDriverValue(toDecoderInput(decoder, normalizeTimestampString(rawValue, decoder.withTimezone)));
94
- }
95
- if (is(decoder, PgTimestamp)) {
96
- const normalized = normalizeTimestamp(rawValue, decoder.withTimezone);
97
- if (normalized instanceof Date) {
98
- return normalized;
99
- }
100
- return decoder.mapFromDriverValue(toDecoderInput(decoder, normalized));
101
- }
102
- if (is(decoder, PgDateString)) {
103
- return decoder.mapFromDriverValue(toDecoderInput(decoder, normalizeDateString(rawValue)));
104
- }
105
- if (is(decoder, PgDate)) {
106
- return decoder.mapFromDriverValue(toDecoderInput(decoder, normalizeDateValue(rawValue)));
107
- }
108
- if (is(decoder, PgTime)) {
109
- return decoder.mapFromDriverValue(toDecoderInput(decoder, normalizeTime(rawValue)));
110
- }
111
- return decoder.mapFromDriverValue(toDecoderInput(decoder, rawValue));
112
- }
113
- function mapResultRow(columns, row, joinsNotNullableMap) {
114
- const nullifyMap = {};
115
- const result = columns.reduce((acc, { path, field }, columnIndex) => {
116
- let decoder;
117
- if (is(field, Column)) {
118
- decoder = field;
119
- } else if (is(field, SQL)) {
120
- decoder = field.decoder;
121
- } else {
122
- const col = field.sql.queryChunks.find((chunk) => is(chunk, Column));
123
- if (is(col, PgCustomColumn)) {
124
- decoder = col;
125
- } else {
126
- decoder = field.sql.decoder;
127
- }
128
- }
129
- let node = acc;
130
- for (const [pathChunkIndex, pathChunk] of path.entries()) {
131
- if (pathChunkIndex < path.length - 1) {
132
- if (!(pathChunk in node)) {
133
- node[pathChunk] = {};
134
- }
135
- node = node[pathChunk];
136
- continue;
137
- }
138
- const rawValue = row[columnIndex];
139
- const value = node[pathChunk] = rawValue === null ? null : mapDriverValue(decoder, rawValue);
140
- if (joinsNotNullableMap && is(field, Column) && path.length === 2) {
141
- const objectName = path[0];
142
- if (!(objectName in nullifyMap)) {
143
- nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
144
- } else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
145
- nullifyMap[objectName] = false;
146
- }
147
- continue;
148
- }
149
- if (joinsNotNullableMap && is(field, SQL.Aliased) && path.length === 2) {
150
- const col = field.sql.queryChunks.find((chunk) => is(chunk, Column));
151
- const tableName = col?.table && getTableName(col?.table);
152
- if (!tableName) {
153
- continue;
154
- }
155
- const objectName = path[0];
156
- if (!(objectName in nullifyMap)) {
157
- nullifyMap[objectName] = value === null ? tableName : false;
158
- continue;
159
- }
160
- if (nullifyMap[objectName] && nullifyMap[objectName] !== tableName) {
161
- nullifyMap[objectName] = false;
162
- }
163
- continue;
164
- }
165
- }
166
- return acc;
167
- }, {});
168
- if (joinsNotNullableMap && Object.keys(nullifyMap).length > 0) {
169
- for (const [objectName, tableName] of Object.entries(nullifyMap)) {
170
- if (typeof tableName === "string" && !joinsNotNullableMap[tableName]) {
171
- result[objectName] = null;
172
- }
173
- }
174
- }
175
- return result;
176
- }
177
-
178
- // src/session.ts
179
- import { TransactionRollbackError } from "drizzle-orm/errors";
180
-
181
1
  // src/client.ts
182
2
  function isPool(client) {
183
3
  return typeof client.acquire === "function";
184
4
  }
185
5
  function prepareParams(params, typings) {
186
6
  return params.map((param, i) => {
187
- if (param === undefined)
188
- return null;
189
- if (param instanceof Date)
190
- return param.toISOString().replace(/'/g, "''");
191
- if (typeof param === "bigint")
192
- return param.toString();
7
+ if (param === void 0) return null;
8
+ if (param instanceof Date) return param.toISOString().replace(/'/g, "''");
9
+ if (typeof param === "bigint") return param.toString();
193
10
  if (typeof param === "string") {
194
11
  const typing = typings?.[i];
195
12
  if (typing === "decimal" && /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(param)) {
@@ -204,27 +21,25 @@ function prepareParams(params, typings) {
204
21
  });
205
22
  }
206
23
  function isTransientError(error) {
207
- if (!(error instanceof Error))
208
- return false;
24
+ if (!(error instanceof Error)) return false;
209
25
  const msg = error.message?.toLowerCase() ?? "";
210
26
  return msg.includes("connection closed") || msg.includes("econnreset") || msg.includes("epipe") || msg.includes("socket hang up") || msg.includes("connection refused");
211
27
  }
212
28
  async function withRetry(fn, maxRetries = 2) {
213
29
  let lastError;
214
- for (let attempt = 0;attempt <= maxRetries; attempt++) {
30
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
215
31
  try {
216
32
  return await fn();
217
33
  } catch (error) {
218
34
  lastError = error;
219
- if (!isTransientError(error) || attempt === maxRetries)
220
- throw error;
221
- await new Promise((r) => setTimeout(r, 100 * Math.pow(2, attempt)));
35
+ if (!isTransientError(error) || attempt === maxRetries) throw error;
36
+ await new Promise((r) => setTimeout(r, 100 * 2 ** attempt));
222
37
  }
223
38
  }
224
39
  throw lastError;
225
40
  }
226
41
  function deduplicateColumns(columns) {
227
- const counts = new Map;
42
+ const counts = /* @__PURE__ */ new Map();
228
43
  let hasDuplicates = false;
229
44
  for (const column of columns) {
230
45
  const next = (counts.get(column) ?? 0) + 1;
@@ -256,7 +71,7 @@ async function executeOnClient(client, query, params, typings) {
256
71
  });
257
72
  }
258
73
  const prepared = prepareParams(params, typings);
259
- const paramValue = prepared.length > 0 ? prepared : undefined;
74
+ const paramValue = prepared.length > 0 ? prepared : void 0;
260
75
  const rows = await client.queryAll(query, paramValue);
261
76
  if (!rows || rows.length === 0) {
262
77
  return [];
@@ -275,7 +90,7 @@ async function executeArraysOnClient(client, query, params, typings) {
275
90
  });
276
91
  }
277
92
  const prepared = prepareParams(params, typings);
278
- const paramValue = prepared.length > 0 ? prepared : undefined;
93
+ const paramValue = prepared.length > 0 ? prepared : void 0;
279
94
  const iter = await client.queryIter(query, paramValue);
280
95
  const schema = iter.schema();
281
96
  const fields = schema.fields();
@@ -283,10 +98,8 @@ async function executeArraysOnClient(client, query, params, typings) {
283
98
  const rows = [];
284
99
  while (true) {
285
100
  const row = await iter.next();
286
- if (row === null)
287
- break;
288
- if (row instanceof Error)
289
- throw row;
101
+ if (row === null) break;
102
+ if (row instanceof Error) throw row;
290
103
  rows.push(row.values());
291
104
  }
292
105
  return { columns, rows };
@@ -303,7 +116,7 @@ async function execOnClient(client, query, params, typings) {
303
116
  });
304
117
  }
305
118
  const prepared = prepareParams(params, typings);
306
- const paramValue = prepared.length > 0 ? prepared : undefined;
119
+ const paramValue = prepared.length > 0 ? prepared : void 0;
307
120
  return await client.exec(query, paramValue);
308
121
  }
309
122
  async function closeClientConnection(connection) {
@@ -312,179 +125,155 @@ async function closeClientConnection(connection) {
312
125
  }
313
126
  }
314
127
 
315
- // src/session.ts
316
- class DatabendPreparedQuery extends PgPreparedQuery {
317
- client;
318
- queryString;
319
- params;
320
- logger;
321
- fields;
322
- _isResponseInArrayMode;
323
- customResultMapper;
324
- typings;
325
- static [entityKind] = "DatabendPreparedQuery";
326
- constructor(client, queryString, params, logger, fields, _isResponseInArrayMode, customResultMapper, typings) {
327
- super({ sql: queryString, params });
328
- this.client = client;
329
- this.queryString = queryString;
330
- this.params = params;
331
- this.logger = logger;
332
- this.fields = fields;
333
- this._isResponseInArrayMode = _isResponseInArrayMode;
334
- this.customResultMapper = customResultMapper;
335
- this.typings = typings;
128
+ // src/columns.ts
129
+ import { customType } from "drizzle-orm/pg-core";
130
+ var databendVariant = (name) => customType({
131
+ dataType() {
132
+ return "VARIANT";
133
+ },
134
+ toDriver(value) {
135
+ if (typeof value === "string") {
136
+ return value;
137
+ }
138
+ return JSON.stringify(value);
139
+ },
140
+ fromDriver(value) {
141
+ if (typeof value === "string") {
142
+ try {
143
+ return JSON.parse(value);
144
+ } catch {
145
+ return value;
146
+ }
147
+ }
148
+ return value;
336
149
  }
337
- async execute(placeholderValues = {}) {
338
- const params = fillPlaceholders(this.params, placeholderValues);
339
- this.logger.logQuery(this.queryString, params);
340
- const { fields, joinsNotNullableMap, customResultMapper, typings } = this;
341
- if (fields) {
342
- const { rows: rows2 } = await executeArraysOnClient(this.client, this.queryString, params, typings);
343
- if (rows2.length === 0) {
150
+ })(name);
151
+ var databendArray = (name, elementType) => customType({
152
+ dataType() {
153
+ return `ARRAY(${elementType})`;
154
+ },
155
+ toDriver(value) {
156
+ return value;
157
+ },
158
+ fromDriver(value) {
159
+ if (typeof value === "string") {
160
+ try {
161
+ return JSON.parse(value);
162
+ } catch {
344
163
  return [];
345
164
  }
346
- return customResultMapper ? customResultMapper(rows2) : rows2.map((row) => mapResultRow(fields, row, joinsNotNullableMap));
347
165
  }
348
- const rows = await executeOnClient(this.client, this.queryString, params, typings);
349
- return rows;
350
- }
351
- all(placeholderValues = {}) {
352
- return this.execute(placeholderValues);
353
- }
354
- isResponseInArrayMode() {
355
- return this._isResponseInArrayMode;
356
- }
357
- }
358
-
359
- class DatabendSession extends PgSession {
360
- client;
361
- schema;
362
- options;
363
- static [entityKind] = "DatabendSession";
364
- dialect;
365
- logger;
366
- rollbackOnly = false;
367
- constructor(client, dialect, schema, options = {}) {
368
- super(dialect);
369
- this.client = client;
370
- this.schema = schema;
371
- this.options = options;
372
- this.dialect = dialect;
373
- this.logger = options.logger ?? new NoopLogger;
374
- }
375
- prepareQuery(query, fields, name, isResponseInArrayMode, customResultMapper) {
376
- return new DatabendPreparedQuery(this.client, query.sql, query.params, this.logger, fields, isResponseInArrayMode, customResultMapper, query.typings);
166
+ return value;
377
167
  }
378
- async transaction(transaction, config) {
379
- let pinnedConnection;
380
- let pool;
381
- let clientForTx = this.client;
382
- if (isPool(this.client)) {
383
- pool = this.client;
384
- pinnedConnection = await pool.acquire();
385
- clientForTx = pinnedConnection;
386
- }
387
- const session = new DatabendSession(clientForTx, this.dialect, this.schema, this.options);
388
- const tx = new DatabendTransaction(this.dialect, session, this.schema);
389
- try {
390
- await tx.execute(sql`BEGIN`);
391
- if (config) {
392
- await tx.setTransaction(config);
393
- }
168
+ })(name);
169
+ var databendTuple = (name, types) => customType({
170
+ dataType() {
171
+ return `TUPLE(${types.join(", ")})`;
172
+ },
173
+ toDriver(value) {
174
+ return value;
175
+ },
176
+ fromDriver(value) {
177
+ if (typeof value === "string") {
394
178
  try {
395
- const result = await transaction(tx);
396
- if (session.isRollbackOnly()) {
397
- await tx.execute(sql`ROLLBACK`);
398
- throw new TransactionRollbackError;
399
- }
400
- await tx.execute(sql`COMMIT`);
401
- return result;
402
- } catch (error) {
403
- await tx.execute(sql`ROLLBACK`);
404
- throw error;
405
- }
406
- } finally {
407
- if (pinnedConnection && pool) {
408
- await pool.release(pinnedConnection);
179
+ return JSON.parse(value);
180
+ } catch {
181
+ return value;
409
182
  }
410
183
  }
184
+ return value;
411
185
  }
412
- markRollbackOnly() {
413
- this.rollbackOnly = true;
414
- }
415
- isRollbackOnly() {
416
- return this.rollbackOnly;
417
- }
418
- }
419
- var VALID_TRANSACTION_ISOLATION_LEVELS = new Set([
420
- "read uncommitted",
421
- "read committed",
422
- "repeatable read",
423
- "serializable"
424
- ]);
425
- var VALID_TRANSACTION_ACCESS_MODES = new Set([
426
- "read only",
427
- "read write"
428
- ]);
429
-
430
- class DatabendTransaction extends PgTransaction {
431
- static [entityKind] = "DatabendTransaction";
432
- rollback() {
433
- throw new TransactionRollbackError;
186
+ })(name);
187
+ var databendMap = (name, keyType, valueType) => customType({
188
+ dataType() {
189
+ return `MAP(${keyType}, ${valueType})`;
190
+ },
191
+ toDriver(value) {
192
+ return value;
193
+ },
194
+ fromDriver(value) {
195
+ if (typeof value === "string") {
196
+ try {
197
+ return JSON.parse(value);
198
+ } catch {
199
+ return value;
200
+ }
201
+ }
202
+ return value;
434
203
  }
435
- getTransactionConfigSQL(config) {
436
- if (config.isolationLevel && !VALID_TRANSACTION_ISOLATION_LEVELS.has(config.isolationLevel)) {
437
- throw new Error(`Invalid transaction isolation level "${config.isolationLevel}". Expected one of: ${Array.from(VALID_TRANSACTION_ISOLATION_LEVELS).join(", ")}.`);
204
+ })(name);
205
+ var databendTimestamp = (name) => customType({
206
+ dataType() {
207
+ return "TIMESTAMP";
208
+ },
209
+ toDriver(value) {
210
+ if (value instanceof Date) {
211
+ return value.toISOString();
438
212
  }
439
- if (config.accessMode && !VALID_TRANSACTION_ACCESS_MODES.has(config.accessMode)) {
440
- throw new Error(`Invalid transaction access mode "${config.accessMode}". Expected one of: ${Array.from(VALID_TRANSACTION_ACCESS_MODES).join(", ")}.`);
213
+ return value;
214
+ },
215
+ fromDriver(value) {
216
+ if (value instanceof Date) {
217
+ return value;
441
218
  }
442
- const chunks = [];
443
- if (config.isolationLevel) {
444
- chunks.push(`isolation level ${config.isolationLevel}`);
219
+ const str = String(value);
220
+ const hasOffset = str.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(str);
221
+ const normalized = hasOffset ? str.replace(" ", "T") : `${str.replace(" ", "T")}Z`;
222
+ return new Date(normalized);
223
+ }
224
+ })(name);
225
+ var databendDate = (name) => customType({
226
+ dataType() {
227
+ return "DATE";
228
+ },
229
+ toDriver(value) {
230
+ if (value instanceof Date) {
231
+ return value.toISOString().slice(0, 10);
445
232
  }
446
- if (config.accessMode) {
447
- chunks.push(config.accessMode);
233
+ return value;
234
+ },
235
+ fromDriver(value) {
236
+ if (value instanceof Date) {
237
+ return value.toISOString().slice(0, 10);
448
238
  }
449
- return sql.raw(chunks.join(" "));
450
- }
451
- setTransaction(config) {
452
- return this.session.execute(sql`SET TRANSACTION ${this.getTransactionConfigSQL(config)}`);
453
- }
454
- async transaction(transaction) {
455
- const internals = this;
456
- const nestedTx = new DatabendTransaction(internals.dialect, internals.session, this.schema, this.nestedIndex + 1);
457
- return transaction(nestedTx).catch((error) => {
458
- internals.session.markRollbackOnly();
459
- throw error;
460
- });
239
+ return value.slice(0, 10);
461
240
  }
462
- }
241
+ })(name);
242
+
243
+ // src/driver.ts
244
+ import { Client } from "databend-driver";
245
+ import { entityKind as entityKind3 } from "drizzle-orm/entity";
246
+ import { DefaultLogger } from "drizzle-orm/logger";
247
+ import { PgDatabase } from "drizzle-orm/pg-core/db";
248
+ import {
249
+ createTableRelationsHelpers,
250
+ extractTablesRelationalConfig
251
+ } from "drizzle-orm/relations";
463
252
 
464
253
  // src/dialect.ts
465
- import { entityKind as entityKind2, is as is2 } from "drizzle-orm/entity";
254
+ import {
255
+ sql
256
+ } from "drizzle-orm";
257
+ import { entityKind, is } from "drizzle-orm/entity";
466
258
  import {
467
259
  PgBigInt53,
468
260
  PgBigInt64,
469
- PgDate as PgDate2,
470
- PgDateString as PgDateString2,
261
+ PgDate,
262
+ PgDateString,
471
263
  PgDialect,
472
264
  PgDoublePrecision,
473
265
  PgInteger,
474
266
  PgNumeric,
475
267
  PgReal,
476
268
  PgSmallInt,
477
- PgTime as PgTime2,
478
- PgTimestamp as PgTimestamp2,
479
- PgTimestampString as PgTimestampString2,
269
+ PgTime,
270
+ PgTimestamp,
271
+ PgTimestampString,
480
272
  PgUUID
481
273
  } from "drizzle-orm/pg-core";
482
- import {
483
- sql as sql2
484
- } from "drizzle-orm";
485
-
486
- class DatabendDialect extends PgDialect {
487
- static [entityKind2] = "DatabendPgDialect";
274
+ var DatabendDialect = class extends PgDialect {
275
+ static [entityKind] = "DatabendPgDialect";
276
+ // Databend does not support savepoints
488
277
  areSavepointsUnsupported() {
489
278
  return true;
490
279
  }
@@ -492,67 +281,79 @@ class DatabendDialect extends PgDialect {
492
281
  const migrationConfig = typeof config === "string" ? { migrationsFolder: config } : config;
493
282
  const migrationsSchema = migrationConfig.migrationsSchema ?? "default";
494
283
  const migrationsTable = migrationConfig.migrationsTable ?? "__drizzle_migrations";
495
- const migrationTableCreate = sql2`
496
- CREATE TABLE IF NOT EXISTS ${sql2.identifier(migrationsSchema)}.${sql2.identifier(migrationsTable)} (
284
+ const migrationTableCreate = sql`
285
+ CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsSchema)}.${sql.identifier(
286
+ migrationsTable
287
+ )} (
497
288
  id INT NOT NULL,
498
289
  hash VARCHAR NOT NULL,
499
290
  created_at BIGINT
500
291
  )
501
292
  `;
502
293
  await session.execute(migrationTableCreate);
503
- const dbMigrations = await session.all(sql2`SELECT id, hash, created_at FROM ${sql2.identifier(migrationsSchema)}.${sql2.identifier(migrationsTable)} ORDER BY created_at DESC LIMIT 1`);
294
+ const dbMigrations = await session.all(
295
+ sql`SELECT id, hash, created_at FROM ${sql.identifier(
296
+ migrationsSchema
297
+ )}.${sql.identifier(migrationsTable)} ORDER BY created_at DESC LIMIT 1`
298
+ );
504
299
  const lastDbMigration = dbMigrations[0];
505
300
  await session.transaction(async (tx) => {
506
301
  for await (const migration of migrations) {
507
302
  if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
508
303
  for (const stmt of migration.sql) {
509
- await tx.execute(sql2.raw(stmt));
304
+ await tx.execute(sql.raw(stmt));
510
305
  }
511
- await tx.execute(sql2`INSERT INTO ${sql2.identifier(migrationsSchema)}.${sql2.identifier(migrationsTable)} (id, hash, created_at)
306
+ await tx.execute(
307
+ sql`INSERT INTO ${sql.identifier(
308
+ migrationsSchema
309
+ )}.${sql.identifier(migrationsTable)} (id, hash, created_at)
512
310
  VALUES (
513
- (SELECT COALESCE(MAX(id), 0) + 1 FROM ${sql2.identifier(migrationsSchema)}.${sql2.identifier(migrationsTable)}),
311
+ (SELECT COALESCE(MAX(id), 0) + 1 FROM ${sql.identifier(
312
+ migrationsSchema
313
+ )}.${sql.identifier(migrationsTable)}),
514
314
  ${migration.hash},
515
315
  ${migration.folderMillis}
516
- )`);
316
+ )`
317
+ );
517
318
  }
518
319
  }
519
320
  });
520
321
  }
521
322
  prepareTyping(encoder) {
522
- if (is2(encoder, PgNumeric) || is2(encoder, PgInteger) || is2(encoder, PgSmallInt) || is2(encoder, PgReal) || is2(encoder, PgDoublePrecision) || is2(encoder, PgBigInt53) || is2(encoder, PgBigInt64)) {
323
+ if (is(encoder, PgNumeric) || is(encoder, PgInteger) || is(encoder, PgSmallInt) || is(encoder, PgReal) || is(encoder, PgDoublePrecision) || is(encoder, PgBigInt53) || is(encoder, PgBigInt64)) {
523
324
  return "decimal";
524
- } else if (is2(encoder, PgTime2)) {
325
+ } else if (is(encoder, PgTime)) {
525
326
  return "time";
526
- } else if (is2(encoder, PgTimestamp2) || is2(encoder, PgTimestampString2)) {
327
+ } else if (is(encoder, PgTimestamp) || is(encoder, PgTimestampString)) {
527
328
  return "timestamp";
528
- } else if (is2(encoder, PgDate2) || is2(encoder, PgDateString2)) {
329
+ } else if (is(encoder, PgDate) || is(encoder, PgDateString)) {
529
330
  return "date";
530
- } else if (is2(encoder, PgUUID)) {
331
+ } else if (is(encoder, PgUUID)) {
531
332
  return "uuid";
532
333
  } else {
533
334
  return "none";
534
335
  }
535
336
  }
536
- }
337
+ };
537
338
 
538
339
  // src/pool.ts
539
340
  function createDatabendConnectionPool(client, options = {}) {
540
341
  const size = options.size && options.size > 0 ? options.size : 4;
541
- const acquireTimeout = options.acquireTimeout ?? 30000;
342
+ const acquireTimeout = options.acquireTimeout ?? 3e4;
542
343
  const maxWaitingRequests = options.maxWaitingRequests ?? 100;
543
344
  const maxLifetimeMs = options.maxLifetimeMs;
544
345
  const idleTimeoutMs = options.idleTimeoutMs;
545
- const metadata = new WeakMap;
346
+ const metadata = /* @__PURE__ */ new WeakMap();
546
347
  const idle = [];
547
348
  const waiting = [];
548
349
  let total = 0;
549
350
  let closed = false;
550
351
  let pendingAcquires = 0;
551
352
  const shouldRecycle = (conn, now) => {
552
- if (maxLifetimeMs !== undefined && now - conn.createdAt >= maxLifetimeMs) {
353
+ if (maxLifetimeMs !== void 0 && now - conn.createdAt >= maxLifetimeMs) {
553
354
  return true;
554
355
  }
555
- if (idleTimeoutMs !== undefined && now - conn.lastUsedAt >= idleTimeoutMs) {
356
+ if (idleTimeoutMs !== void 0 && now - conn.lastUsedAt >= idleTimeoutMs) {
556
357
  return true;
557
358
  }
558
359
  return false;
@@ -598,7 +399,9 @@ function createDatabendConnectionPool(client, options = {}) {
598
399
  }
599
400
  }
600
401
  if (waiting.length >= maxWaitingRequests) {
601
- throw new Error(`Databend connection pool queue is full (max ${maxWaitingRequests} waiting requests)`);
402
+ throw new Error(
403
+ `Databend connection pool queue is full (max ${maxWaitingRequests} waiting requests)`
404
+ );
602
405
  }
603
406
  return await new Promise((resolve, reject) => {
604
407
  const timeoutId = setTimeout(() => {
@@ -606,7 +409,11 @@ function createDatabendConnectionPool(client, options = {}) {
606
409
  if (idx !== -1) {
607
410
  waiting.splice(idx, 1);
608
411
  }
609
- reject(new Error(`Databend connection pool acquire timeout after ${acquireTimeout}ms`));
412
+ reject(
413
+ new Error(
414
+ `Databend connection pool acquire timeout after ${acquireTimeout}ms`
415
+ )
416
+ );
610
417
  }, acquireTimeout);
611
418
  waiting.push({ resolve, reject, timeoutId });
612
419
  });
@@ -617,7 +424,7 @@ function createDatabendConnectionPool(client, options = {}) {
617
424
  clearTimeout(waiter.timeoutId);
618
425
  const now2 = Date.now();
619
426
  const meta = metadata.get(connection) ?? { createdAt: now2, lastUsedAt: now2 };
620
- const expired = maxLifetimeMs !== undefined && now2 - meta.createdAt >= maxLifetimeMs;
427
+ const expired = maxLifetimeMs !== void 0 && now2 - meta.createdAt >= maxLifetimeMs;
621
428
  if (closed) {
622
429
  await closeClientConnection(connection);
623
430
  total = Math.max(0, total - 1);
@@ -652,7 +459,7 @@ function createDatabendConnectionPool(client, options = {}) {
652
459
  const existingMeta = metadata.get(connection) ?? { createdAt: now, lastUsedAt: now };
653
460
  existingMeta.lastUsedAt = now;
654
461
  metadata.set(connection, existingMeta);
655
- if (maxLifetimeMs !== undefined && now - existingMeta.createdAt >= maxLifetimeMs) {
462
+ if (maxLifetimeMs !== void 0 && now - existingMeta.createdAt >= maxLifetimeMs) {
656
463
  await closeClientConnection(connection);
657
464
  total -= 1;
658
465
  metadata.delete(connection);
@@ -672,10 +479,14 @@ function createDatabendConnectionPool(client, options = {}) {
672
479
  waiter.reject(new Error("Databend connection pool is closed"));
673
480
  }
674
481
  const toClose = idle.splice(0, idle.length);
675
- await Promise.allSettled(toClose.map((item) => closeClientConnection(item.connection)));
482
+ await Promise.allSettled(
483
+ toClose.map((item) => closeClientConnection(item.connection))
484
+ );
676
485
  total = Math.max(0, total - toClose.length);
677
- toClose.forEach((item) => metadata.delete(item.connection));
678
- const maxWait = 5000;
486
+ for (const item of toClose) {
487
+ metadata.delete(item.connection);
488
+ }
489
+ const maxWait = 5e3;
679
490
  const start = Date.now();
680
491
  while (pendingAcquires > 0 && Date.now() - start < maxWait) {
681
492
  await new Promise((r) => setTimeout(r, 10));
@@ -689,36 +500,393 @@ function createDatabendConnectionPool(client, options = {}) {
689
500
  };
690
501
  }
691
502
 
692
- // src/driver.ts
693
- class DatabendDriver {
694
- client;
503
+ // src/session.ts
504
+ import { entityKind as entityKind2 } from "drizzle-orm/entity";
505
+ import { TransactionRollbackError } from "drizzle-orm/errors";
506
+ import { NoopLogger } from "drizzle-orm/logger";
507
+ import { PgTransaction } from "drizzle-orm/pg-core";
508
+ import { PgPreparedQuery, PgSession } from "drizzle-orm/pg-core/session";
509
+ import { fillPlaceholders, sql as sql2 } from "drizzle-orm/sql/sql";
510
+
511
+ // src/sql/result-mapper.ts
512
+ import {
513
+ Column,
514
+ getTableName,
515
+ is as is2,
516
+ SQL
517
+ } from "drizzle-orm";
518
+ import {
519
+ PgCustomColumn,
520
+ PgDate as PgDate2,
521
+ PgDateString as PgDateString2,
522
+ PgTime as PgTime2,
523
+ PgTimestamp as PgTimestamp2,
524
+ PgTimestampString as PgTimestampString2
525
+ } from "drizzle-orm/pg-core";
526
+ function toDecoderInput(decoder, value) {
527
+ void decoder;
528
+ return value;
529
+ }
530
+ function normalizeTimestampString(value, withTimezone) {
531
+ if (value instanceof Date) {
532
+ const iso = value.toISOString().replace("T", " ");
533
+ return withTimezone ? iso.replace("Z", "+00") : iso.replace("Z", "");
534
+ }
535
+ if (typeof value === "string") {
536
+ const normalized = value.replace("T", " ");
537
+ if (withTimezone) {
538
+ return normalized.includes("+") ? normalized : `${normalized}+00`;
539
+ }
540
+ return normalized.replace(/\+00$/, "");
541
+ }
542
+ return value;
543
+ }
544
+ function normalizeTimestamp(value, withTimezone) {
545
+ if (value instanceof Date) {
546
+ return value;
547
+ }
548
+ if (typeof value === "string") {
549
+ const hasOffset = value.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(value.trim());
550
+ const spaced = value.replace(" ", "T");
551
+ const normalized = withTimezone || hasOffset ? spaced : `${spaced}+00`;
552
+ return new Date(normalized);
553
+ }
554
+ return value;
555
+ }
556
+ function normalizeDateString(value) {
557
+ if (value instanceof Date) {
558
+ return value.toISOString().slice(0, 10);
559
+ }
560
+ if (typeof value === "string") {
561
+ return value.slice(0, 10);
562
+ }
563
+ return value;
564
+ }
565
+ function normalizeDateValue(value) {
566
+ if (value instanceof Date) {
567
+ return value;
568
+ }
569
+ if (typeof value === "string") {
570
+ return /* @__PURE__ */ new Date(`${value.slice(0, 10)}T00:00:00Z`);
571
+ }
572
+ return value;
573
+ }
574
+ function normalizeTime(value) {
575
+ if (typeof value === "bigint") {
576
+ const totalMillis = Number(value) / 1e3;
577
+ const date = new Date(totalMillis);
578
+ return date.toISOString().split("T")[1].replace("Z", "");
579
+ }
580
+ if (value instanceof Date) {
581
+ return value.toISOString().split("T")[1].replace("Z", "");
582
+ }
583
+ return value;
584
+ }
585
+ function mapDriverValue(decoder, rawValue) {
586
+ if (is2(decoder, PgTimestampString2)) {
587
+ return decoder.mapFromDriverValue(
588
+ toDecoderInput(
589
+ decoder,
590
+ normalizeTimestampString(rawValue, decoder.withTimezone)
591
+ )
592
+ );
593
+ }
594
+ if (is2(decoder, PgTimestamp2)) {
595
+ const normalized = normalizeTimestamp(rawValue, decoder.withTimezone);
596
+ if (normalized instanceof Date) {
597
+ return normalized;
598
+ }
599
+ return decoder.mapFromDriverValue(toDecoderInput(decoder, normalized));
600
+ }
601
+ if (is2(decoder, PgDateString2)) {
602
+ return decoder.mapFromDriverValue(
603
+ toDecoderInput(decoder, normalizeDateString(rawValue))
604
+ );
605
+ }
606
+ if (is2(decoder, PgDate2)) {
607
+ return decoder.mapFromDriverValue(
608
+ toDecoderInput(decoder, normalizeDateValue(rawValue))
609
+ );
610
+ }
611
+ if (is2(decoder, PgTime2)) {
612
+ return decoder.mapFromDriverValue(
613
+ toDecoderInput(decoder, normalizeTime(rawValue))
614
+ );
615
+ }
616
+ return decoder.mapFromDriverValue(toDecoderInput(decoder, rawValue));
617
+ }
618
+ function mapResultRow(columns, row, joinsNotNullableMap) {
619
+ const nullifyMap = {};
620
+ const result = columns.reduce(
621
+ (acc, { path, field }, columnIndex) => {
622
+ let decoder;
623
+ if (is2(field, Column)) {
624
+ decoder = field;
625
+ } else if (is2(field, SQL)) {
626
+ decoder = field.decoder;
627
+ } else {
628
+ const col = field.sql.queryChunks.find((chunk) => is2(chunk, Column));
629
+ if (is2(col, PgCustomColumn)) {
630
+ decoder = col;
631
+ } else {
632
+ decoder = field.sql.decoder;
633
+ }
634
+ }
635
+ let node = acc;
636
+ for (const [pathChunkIndex, pathChunk] of path.entries()) {
637
+ if (pathChunkIndex < path.length - 1) {
638
+ if (!(pathChunk in node)) {
639
+ node[pathChunk] = {};
640
+ }
641
+ node = node[pathChunk];
642
+ continue;
643
+ }
644
+ const rawValue = row[columnIndex];
645
+ const value = node[pathChunk] = rawValue === null ? null : mapDriverValue(decoder, rawValue);
646
+ if (joinsNotNullableMap && is2(field, Column) && path.length === 2) {
647
+ const objectName = path[0];
648
+ if (!(objectName in nullifyMap)) {
649
+ nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
650
+ } else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
651
+ nullifyMap[objectName] = false;
652
+ }
653
+ continue;
654
+ }
655
+ if (joinsNotNullableMap && is2(field, SQL.Aliased) && path.length === 2) {
656
+ const col = field.sql.queryChunks.find((chunk) => is2(chunk, Column));
657
+ const tableName = col?.table && getTableName(col?.table);
658
+ if (!tableName) {
659
+ continue;
660
+ }
661
+ const objectName = path[0];
662
+ if (!(objectName in nullifyMap)) {
663
+ nullifyMap[objectName] = value === null ? tableName : false;
664
+ continue;
665
+ }
666
+ if (nullifyMap[objectName] && nullifyMap[objectName] !== tableName) {
667
+ nullifyMap[objectName] = false;
668
+ }
669
+ }
670
+ }
671
+ return acc;
672
+ },
673
+ {}
674
+ );
675
+ if (joinsNotNullableMap && Object.keys(nullifyMap).length > 0) {
676
+ for (const [objectName, tableName] of Object.entries(nullifyMap)) {
677
+ if (typeof tableName === "string" && !joinsNotNullableMap[tableName]) {
678
+ result[objectName] = null;
679
+ }
680
+ }
681
+ }
682
+ return result;
683
+ }
684
+
685
+ // src/session.ts
686
+ var DatabendPreparedQuery = class extends PgPreparedQuery {
687
+ constructor(client, queryString, params, logger, fields, _isResponseInArrayMode, customResultMapper, typings) {
688
+ super({ sql: queryString, params });
689
+ this.client = client;
690
+ this.queryString = queryString;
691
+ this.params = params;
692
+ this.logger = logger;
693
+ this.fields = fields;
694
+ this._isResponseInArrayMode = _isResponseInArrayMode;
695
+ this.customResultMapper = customResultMapper;
696
+ this.typings = typings;
697
+ }
698
+ static [entityKind2] = "DatabendPreparedQuery";
699
+ async execute(placeholderValues = {}) {
700
+ const params = fillPlaceholders(this.params, placeholderValues);
701
+ this.logger.logQuery(this.queryString, params);
702
+ const { fields, joinsNotNullableMap, customResultMapper, typings } = this;
703
+ if (fields) {
704
+ const { rows: rows2 } = await executeArraysOnClient(
705
+ this.client,
706
+ this.queryString,
707
+ params,
708
+ typings
709
+ );
710
+ if (rows2.length === 0) {
711
+ return [];
712
+ }
713
+ return customResultMapper ? customResultMapper(rows2) : rows2.map(
714
+ (row) => mapResultRow(fields, row, joinsNotNullableMap)
715
+ );
716
+ }
717
+ const rows = await executeOnClient(this.client, this.queryString, params, typings);
718
+ return rows;
719
+ }
720
+ all(placeholderValues = {}) {
721
+ return this.execute(placeholderValues);
722
+ }
723
+ isResponseInArrayMode() {
724
+ return this._isResponseInArrayMode;
725
+ }
726
+ };
727
+ var DatabendSession = class _DatabendSession extends PgSession {
728
+ constructor(client, dialect, schema, options = {}) {
729
+ super(dialect);
730
+ this.client = client;
731
+ this.schema = schema;
732
+ this.options = options;
733
+ this.dialect = dialect;
734
+ this.logger = options.logger ?? new NoopLogger();
735
+ }
736
+ static [entityKind2] = "DatabendSession";
695
737
  dialect;
696
- options;
697
- static [entityKind3] = "DatabendDriver";
738
+ logger;
739
+ rollbackOnly = false;
740
+ prepareQuery(query, fields, name, isResponseInArrayMode, customResultMapper) {
741
+ void name;
742
+ return new DatabendPreparedQuery(
743
+ this.client,
744
+ query.sql,
745
+ query.params,
746
+ this.logger,
747
+ fields,
748
+ isResponseInArrayMode,
749
+ customResultMapper,
750
+ query.typings
751
+ );
752
+ }
753
+ async transaction(transaction, config) {
754
+ let pinnedConnection;
755
+ let pool;
756
+ let clientForTx = this.client;
757
+ if (isPool(this.client)) {
758
+ pool = this.client;
759
+ pinnedConnection = await pool.acquire();
760
+ clientForTx = pinnedConnection;
761
+ }
762
+ const session = new _DatabendSession(
763
+ clientForTx,
764
+ this.dialect,
765
+ this.schema,
766
+ this.options
767
+ );
768
+ const tx = new DatabendTransaction(
769
+ this.dialect,
770
+ session,
771
+ this.schema
772
+ );
773
+ try {
774
+ await tx.execute(sql2`BEGIN`);
775
+ if (config) {
776
+ await tx.setTransaction(config);
777
+ }
778
+ try {
779
+ const result = await transaction(tx);
780
+ if (session.isRollbackOnly()) {
781
+ await tx.execute(sql2`ROLLBACK`);
782
+ throw new TransactionRollbackError();
783
+ }
784
+ await tx.execute(sql2`COMMIT`);
785
+ return result;
786
+ } catch (error) {
787
+ await tx.execute(sql2`ROLLBACK`);
788
+ throw error;
789
+ }
790
+ } finally {
791
+ if (pinnedConnection && pool) {
792
+ await pool.release(pinnedConnection);
793
+ }
794
+ }
795
+ }
796
+ markRollbackOnly() {
797
+ this.rollbackOnly = true;
798
+ }
799
+ isRollbackOnly() {
800
+ return this.rollbackOnly;
801
+ }
802
+ };
803
+ var VALID_TRANSACTION_ISOLATION_LEVELS = /* @__PURE__ */ new Set([
804
+ "read uncommitted",
805
+ "read committed",
806
+ "repeatable read",
807
+ "serializable"
808
+ ]);
809
+ var VALID_TRANSACTION_ACCESS_MODES = /* @__PURE__ */ new Set([
810
+ "read only",
811
+ "read write"
812
+ ]);
813
+ var DatabendTransaction = class _DatabendTransaction extends PgTransaction {
814
+ static [entityKind2] = "DatabendTransaction";
815
+ rollback() {
816
+ throw new TransactionRollbackError();
817
+ }
818
+ getTransactionConfigSQL(config) {
819
+ if (config.isolationLevel && !VALID_TRANSACTION_ISOLATION_LEVELS.has(config.isolationLevel)) {
820
+ throw new Error(
821
+ `Invalid transaction isolation level "${config.isolationLevel}". Expected one of: ${Array.from(
822
+ VALID_TRANSACTION_ISOLATION_LEVELS
823
+ ).join(", ")}.`
824
+ );
825
+ }
826
+ if (config.accessMode && !VALID_TRANSACTION_ACCESS_MODES.has(config.accessMode)) {
827
+ throw new Error(
828
+ `Invalid transaction access mode "${config.accessMode}". Expected one of: ${Array.from(
829
+ VALID_TRANSACTION_ACCESS_MODES
830
+ ).join(", ")}.`
831
+ );
832
+ }
833
+ const chunks = [];
834
+ if (config.isolationLevel) {
835
+ chunks.push(`isolation level ${config.isolationLevel}`);
836
+ }
837
+ if (config.accessMode) {
838
+ chunks.push(config.accessMode);
839
+ }
840
+ return sql2.raw(chunks.join(" "));
841
+ }
842
+ setTransaction(config) {
843
+ return this.session.execute(
844
+ sql2`SET TRANSACTION ${this.getTransactionConfigSQL(config)}`
845
+ );
846
+ }
847
+ async transaction(transaction) {
848
+ const internals = this;
849
+ const nestedTx = new _DatabendTransaction(
850
+ internals.dialect,
851
+ internals.session,
852
+ this.schema,
853
+ this.nestedIndex + 1
854
+ );
855
+ return transaction(nestedTx).catch((error) => {
856
+ internals.session.markRollbackOnly();
857
+ throw error;
858
+ });
859
+ }
860
+ };
861
+
862
+ // src/driver.ts
863
+ var DatabendDriver = class {
698
864
  constructor(client, dialect, options = {}) {
699
865
  this.client = client;
700
866
  this.dialect = dialect;
701
867
  this.options = options;
702
868
  }
869
+ static [entityKind3] = "DatabendDriver";
703
870
  createSession(schema) {
704
871
  return new DatabendSession(this.client, this.dialect, schema, {
705
872
  logger: this.options.logger
706
873
  });
707
874
  }
708
- }
875
+ };
709
876
  function isConfigObject(data) {
710
- if (typeof data !== "object" || data === null)
711
- return false;
712
- if (data.constructor?.name !== "Object")
713
- return false;
877
+ if (typeof data !== "object" || data === null) return false;
878
+ if (data.constructor?.name !== "Object") return false;
714
879
  return "connection" in data || "client" in data || "pool" in data || "schema" in data || "logger" in data;
715
880
  }
716
881
  function createFromClient(client, config = {}, databendClient) {
717
- const dialect = new DatabendDialect;
718
- const logger = config.logger === true ? new DefaultLogger : config.logger || undefined;
882
+ const dialect = new DatabendDialect();
883
+ const logger = config.logger === true ? new DefaultLogger() : config.logger || void 0;
719
884
  let schema;
720
885
  if (config.schema) {
721
- const tablesConfig = extractTablesRelationalConfig(config.schema, createTableRelationsHelpers);
886
+ const tablesConfig = extractTablesRelationalConfig(
887
+ config.schema,
888
+ createTableRelationsHelpers
889
+ );
722
890
  schema = {
723
891
  fullSchema: config.schema,
724
892
  schema: tablesConfig.tables,
@@ -727,7 +895,13 @@ function createFromClient(client, config = {}, databendClient) {
727
895
  }
728
896
  const driver = new DatabendDriver(client, dialect, { logger });
729
897
  const session = driver.createSession(schema);
730
- const db = new DatabendDatabase(dialect, session, schema, client, databendClient);
898
+ const db = new DatabendDatabase(
899
+ dialect,
900
+ session,
901
+ schema,
902
+ client,
903
+ databendClient
904
+ );
731
905
  return db;
732
906
  }
733
907
  async function createFromDsn(dsn, config = {}) {
@@ -749,24 +923,26 @@ function drizzle(clientOrConfigOrDsn, config) {
749
923
  if ("connection" in configObj) {
750
924
  const connConfig = configObj;
751
925
  const { connection, ...restConfig } = connConfig;
752
- return createFromDsn(connection, restConfig);
926
+ return createFromDsn(
927
+ connection,
928
+ restConfig
929
+ );
753
930
  }
754
931
  if ("client" in configObj) {
755
932
  const clientConfig = configObj;
756
933
  const { client: clientValue, ...restConfig } = clientConfig;
757
- return createFromClient(clientValue, restConfig);
934
+ return createFromClient(
935
+ clientValue,
936
+ restConfig
937
+ );
758
938
  }
759
- throw new Error("Invalid drizzle config: either connection or client must be provided");
939
+ throw new Error(
940
+ "Invalid drizzle config: either connection or client must be provided"
941
+ );
760
942
  }
761
943
  return createFromClient(clientOrConfigOrDsn, config);
762
944
  }
763
-
764
- class DatabendDatabase extends PgDatabase {
765
- dialect;
766
- session;
767
- static [entityKind3] = "DatabendDatabase";
768
- $client;
769
- $databendClient;
945
+ var DatabendDatabase = class extends PgDatabase {
770
946
  constructor(dialect, session, schema, client, databendClient) {
771
947
  super(dialect, session, schema);
772
948
  this.dialect = dialect;
@@ -774,6 +950,11 @@ class DatabendDatabase extends PgDatabase {
774
950
  this.$client = client;
775
951
  this.$databendClient = databendClient;
776
952
  }
953
+ static [entityKind3] = "DatabendDatabase";
954
+ /** The underlying connection or pool */
955
+ $client;
956
+ /** The Databend Client instance (when created from DSN) */
957
+ $databendClient;
777
958
  async close() {
778
959
  if (isPool(this.$client) && this.$client.close) {
779
960
  await this.$client.close();
@@ -785,147 +966,38 @@ class DatabendDatabase extends PgDatabase {
785
966
  async transaction(transaction) {
786
967
  return await this.session.transaction(transaction);
787
968
  }
788
- }
789
- // src/columns.ts
790
- import { customType } from "drizzle-orm/pg-core";
791
- var databendVariant = (name) => customType({
792
- dataType() {
793
- return "VARIANT";
794
- },
795
- toDriver(value) {
796
- if (typeof value === "string") {
797
- return value;
798
- }
799
- return JSON.stringify(value);
800
- },
801
- fromDriver(value) {
802
- if (typeof value === "string") {
803
- try {
804
- return JSON.parse(value);
805
- } catch {
806
- return value;
807
- }
808
- }
809
- return value;
810
- }
811
- })(name);
812
- var databendArray = (name, elementType) => customType({
813
- dataType() {
814
- return `ARRAY(${elementType})`;
815
- },
816
- toDriver(value) {
817
- return value;
818
- },
819
- fromDriver(value) {
820
- if (typeof value === "string") {
821
- try {
822
- return JSON.parse(value);
823
- } catch {
824
- return [];
825
- }
826
- }
827
- return value;
828
- }
829
- })(name);
830
- var databendTuple = (name, types) => customType({
831
- dataType() {
832
- return `TUPLE(${types.join(", ")})`;
833
- },
834
- toDriver(value) {
835
- return value;
836
- },
837
- fromDriver(value) {
838
- if (typeof value === "string") {
839
- try {
840
- return JSON.parse(value);
841
- } catch {
842
- return value;
843
- }
844
- }
845
- return value;
846
- }
847
- })(name);
848
- var databendMap = (name, keyType, valueType) => customType({
849
- dataType() {
850
- return `MAP(${keyType}, ${valueType})`;
851
- },
852
- toDriver(value) {
853
- return value;
854
- },
855
- fromDriver(value) {
856
- if (typeof value === "string") {
857
- try {
858
- return JSON.parse(value);
859
- } catch {
860
- return value;
861
- }
862
- }
863
- return value;
864
- }
865
- })(name);
866
- var databendTimestamp = (name) => customType({
867
- dataType() {
868
- return "TIMESTAMP";
869
- },
870
- toDriver(value) {
871
- if (value instanceof Date) {
872
- return value.toISOString();
873
- }
874
- return value;
875
- },
876
- fromDriver(value) {
877
- if (value instanceof Date) {
878
- return value;
879
- }
880
- const str = String(value);
881
- const hasOffset = str.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(str);
882
- const normalized = hasOffset ? str.replace(" ", "T") : `${str.replace(" ", "T")}Z`;
883
- return new Date(normalized);
884
- }
885
- })(name);
886
- var databendDate = (name) => customType({
887
- dataType() {
888
- return "DATE";
889
- },
890
- toDriver(value) {
891
- if (value instanceof Date) {
892
- return value.toISOString().slice(0, 10);
893
- }
894
- return value;
895
- },
896
- fromDriver(value) {
897
- if (value instanceof Date) {
898
- return value.toISOString().slice(0, 10);
899
- }
900
- return value.slice(0, 10);
901
- }
902
- })(name);
969
+ };
970
+
903
971
  // src/migrator.ts
904
972
  import { readMigrationFiles } from "drizzle-orm/migrator";
905
973
  async function migrate(db, config) {
906
974
  const migrationConfig = typeof config === "string" ? { migrationsFolder: config } : config;
907
975
  const migrations = readMigrationFiles(migrationConfig);
908
- await db.dialect.migrate(migrations, db.session, migrationConfig);
976
+ await db.dialect.migrate(
977
+ migrations,
978
+ db.session,
979
+ migrationConfig
980
+ );
909
981
  }
910
982
  export {
911
- prepareParams,
912
- migrate,
913
- isPool,
914
- executeOnClient,
915
- executeArraysOnClient,
916
- execOnClient,
917
- drizzle,
918
- databendVariant,
919
- databendTuple,
920
- databendTimestamp,
921
- databendMap,
922
- databendDate,
923
- databendArray,
924
- createDatabendConnectionPool,
925
- closeClientConnection,
926
- DatabendTransaction,
927
- DatabendSession,
928
- DatabendPreparedQuery,
983
+ DatabendDatabase,
929
984
  DatabendDriver,
930
- DatabendDatabase
985
+ DatabendPreparedQuery,
986
+ DatabendSession,
987
+ DatabendTransaction,
988
+ closeClientConnection,
989
+ createDatabendConnectionPool,
990
+ databendArray,
991
+ databendDate,
992
+ databendMap,
993
+ databendTimestamp,
994
+ databendTuple,
995
+ databendVariant,
996
+ drizzle,
997
+ execOnClient,
998
+ executeArraysOnClient,
999
+ executeOnClient,
1000
+ isPool,
1001
+ migrate,
1002
+ prepareParams
931
1003
  };