drizzle-databend 0.1.10 → 0.1.12
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/columns.d.ts +25 -37
- package/dist/databend-core/alias.d.ts +1 -0
- package/dist/databend-core/columns/all.d.ts +35 -0
- package/dist/databend-core/columns/array.d.ts +16 -0
- package/dist/databend-core/columns/bigint.d.ts +24 -0
- package/dist/databend-core/columns/binary.d.ts +13 -0
- package/dist/databend-core/columns/bitmap.d.ts +13 -0
- package/dist/databend-core/columns/boolean.d.ts +13 -0
- package/dist/databend-core/columns/common.d.ts +45 -0
- package/dist/databend-core/columns/custom.d.ts +33 -0
- package/dist/databend-core/columns/date.d.ts +16 -0
- package/dist/databend-core/columns/decimal.d.ts +19 -0
- package/dist/databend-core/columns/double.d.ts +14 -0
- package/dist/databend-core/columns/float.d.ts +14 -0
- package/dist/databend-core/columns/index.d.ts +21 -0
- package/dist/databend-core/columns/integer.d.ts +13 -0
- package/dist/databend-core/columns/map.d.ts +17 -0
- package/dist/databend-core/columns/smallint.d.ts +13 -0
- package/dist/databend-core/columns/text.d.ts +13 -0
- package/dist/databend-core/columns/timestamp.d.ts +16 -0
- package/dist/databend-core/columns/tinyint.d.ts +13 -0
- package/dist/databend-core/columns/tuple.d.ts +16 -0
- package/dist/databend-core/columns/varchar.d.ts +17 -0
- package/dist/databend-core/columns/variant.d.ts +15 -0
- package/dist/databend-core/db.d.ts +31 -0
- package/dist/databend-core/dialect.d.ts +29 -0
- package/dist/databend-core/index.d.ts +18 -0
- package/dist/databend-core/indexes.d.ts +24 -0
- package/dist/databend-core/primary-keys.d.ts +20 -0
- package/dist/databend-core/query-builders/count.d.ts +18 -0
- package/dist/databend-core/query-builders/delete.d.ts +18 -0
- package/dist/databend-core/query-builders/index.d.ts +5 -0
- package/dist/databend-core/query-builders/insert.d.ts +27 -0
- package/dist/databend-core/query-builders/query-builder.d.ts +19 -0
- package/dist/databend-core/query-builders/query.d.ts +37 -0
- package/dist/databend-core/query-builders/raw.d.ts +17 -0
- package/dist/databend-core/query-builders/select.d.ts +65 -0
- package/dist/databend-core/query-builders/update.d.ts +27 -0
- package/dist/databend-core/schema.d.ts +12 -0
- package/dist/databend-core/session.d.ts +28 -0
- package/dist/databend-core/subquery.d.ts +1 -0
- package/dist/databend-core/table.d.ts +12 -0
- package/dist/databend-core/utils.d.ts +7 -0
- package/dist/databend-core/view-base.d.ts +5 -0
- package/dist/databend-core/view-common.d.ts +1 -0
- package/dist/databend-core/view.d.ts +30 -0
- package/dist/dialect.d.ts +1 -10
- package/dist/driver.d.ts +6 -6
- package/dist/index.d.ts +13 -3
- package/dist/index.mjs +3135 -684
- package/dist/session.d.ts +23 -20
- package/dist/sql/result-mapper.d.ts +2 -3
- package/dist/sql/selection.d.ts +2 -1
- package/package.json +11 -8
- package/src/client.ts +1 -1
- package/src/columns.ts +8 -7
- package/src/databend-core/alias.ts +5 -0
- package/src/databend-core/columns/all.ts +38 -0
- package/src/databend-core/columns/array.ts +46 -0
- package/src/databend-core/columns/bigint.ts +52 -0
- package/src/databend-core/columns/binary.ts +27 -0
- package/src/databend-core/columns/bitmap.ts +27 -0
- package/src/databend-core/columns/boolean.ts +27 -0
- package/src/databend-core/columns/common.ts +97 -0
- package/src/databend-core/columns/custom.ts +86 -0
- package/src/databend-core/columns/date.ts +49 -0
- package/src/databend-core/columns/decimal.ts +44 -0
- package/src/databend-core/columns/double.ts +34 -0
- package/src/databend-core/columns/float.ts +31 -0
- package/src/databend-core/columns/index.ts +21 -0
- package/src/databend-core/columns/integer.ts +27 -0
- package/src/databend-core/columns/map.ts +49 -0
- package/src/databend-core/columns/smallint.ts +27 -0
- package/src/databend-core/columns/text.ts +27 -0
- package/src/databend-core/columns/timestamp.ts +51 -0
- package/src/databend-core/columns/tinyint.ts +27 -0
- package/src/databend-core/columns/tuple.ts +46 -0
- package/src/databend-core/columns/varchar.ts +35 -0
- package/src/databend-core/columns/variant.ts +45 -0
- package/src/databend-core/db.ts +153 -0
- package/src/databend-core/dialect.ts +724 -0
- package/src/databend-core/index.ts +18 -0
- package/src/databend-core/indexes.ts +67 -0
- package/src/databend-core/primary-keys.ts +48 -0
- package/src/databend-core/query-builders/count.ts +47 -0
- package/src/databend-core/query-builders/delete.ts +56 -0
- package/src/databend-core/query-builders/index.ts +5 -0
- package/src/databend-core/query-builders/insert.ts +105 -0
- package/src/databend-core/query-builders/query-builder.ts +77 -0
- package/src/databend-core/query-builders/query.ts +124 -0
- package/src/databend-core/query-builders/raw.ts +37 -0
- package/src/databend-core/query-builders/select.ts +377 -0
- package/src/databend-core/query-builders/update.ts +82 -0
- package/src/databend-core/schema.ts +29 -0
- package/src/databend-core/session.ts +85 -0
- package/src/databend-core/subquery.ts +1 -0
- package/src/databend-core/table.ts +67 -0
- package/src/databend-core/utils.ts +34 -0
- package/src/databend-core/view-base.ts +6 -0
- package/src/databend-core/view-common.ts +1 -0
- package/src/databend-core/view.ts +127 -0
- package/src/dialect.ts +3 -119
- package/src/driver.ts +14 -15
- package/src/index.ts +30 -3
- package/src/migrator.ts +1 -2
- package/src/pool.ts +3 -1
- package/src/session.ts +46 -61
- package/src/sql/result-mapper.ts +15 -58
- package/src/sql/selection.ts +3 -2
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 ===
|
|
188
|
-
|
|
189
|
-
if (param
|
|
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
|
-
|
|
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 :
|
|
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 :
|
|
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
|
-
|
|
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 :
|
|
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,482 +125,140 @@ async function closeClientConnection(connection) {
|
|
|
312
125
|
}
|
|
313
126
|
}
|
|
314
127
|
|
|
315
|
-
// src/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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;
|
|
336
|
-
}
|
|
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) {
|
|
344
|
-
return [];
|
|
345
|
-
}
|
|
346
|
-
return customResultMapper ? customResultMapper(rows2) : rows2.map((row) => mapResultRow(fields, row, joinsNotNullableMap));
|
|
347
|
-
}
|
|
348
|
-
const rows = await executeOnClient(this.client, this.queryString, params, typings);
|
|
349
|
-
return rows;
|
|
128
|
+
// src/databend-core/columns/custom.ts
|
|
129
|
+
import { entityKind as entityKind2 } from "drizzle-orm/entity";
|
|
130
|
+
|
|
131
|
+
// src/databend-core/columns/common.ts
|
|
132
|
+
import { Column } from "drizzle-orm/column";
|
|
133
|
+
import { ColumnBuilder } from "drizzle-orm/column-builder";
|
|
134
|
+
import { entityKind } from "drizzle-orm/entity";
|
|
135
|
+
var DatabendColumnBuilder = class extends ColumnBuilder {
|
|
136
|
+
static [entityKind] = "DatabendColumnBuilder";
|
|
137
|
+
generatedAlwaysAs(as, _config) {
|
|
138
|
+
this.config.generated = { as, type: "always", mode: "stored" };
|
|
139
|
+
return this;
|
|
350
140
|
}
|
|
351
|
-
|
|
352
|
-
|
|
141
|
+
unique(name, config) {
|
|
142
|
+
this.config.isUnique = true;
|
|
143
|
+
this.config.uniqueName = name;
|
|
144
|
+
this.config.uniqueType = config?.nulls;
|
|
145
|
+
return this;
|
|
353
146
|
}
|
|
354
|
-
|
|
355
|
-
|
|
147
|
+
/** @internal */
|
|
148
|
+
buildForeignKeys(_column, _table) {
|
|
149
|
+
return [];
|
|
356
150
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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;
|
|
151
|
+
/** @internal */
|
|
152
|
+
buildExtraConfigColumn(table) {
|
|
153
|
+
return new DatabendExtraConfigColumn(table, this.config);
|
|
374
154
|
}
|
|
375
|
-
|
|
376
|
-
|
|
155
|
+
};
|
|
156
|
+
var DatabendColumn = class extends Column {
|
|
157
|
+
static [entityKind] = "DatabendColumn";
|
|
158
|
+
constructor(table, config) {
|
|
159
|
+
super(table, config);
|
|
377
160
|
}
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
}
|
|
394
|
-
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);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
161
|
+
getSQLType() {
|
|
162
|
+
return "";
|
|
411
163
|
}
|
|
412
|
-
|
|
413
|
-
|
|
164
|
+
};
|
|
165
|
+
var DatabendExtraConfigColumn = class extends DatabendColumn {
|
|
166
|
+
static [entityKind] = "DatabendExtraConfigColumn";
|
|
167
|
+
getSQLType() {
|
|
168
|
+
return this.getSQLType();
|
|
414
169
|
}
|
|
415
|
-
|
|
416
|
-
|
|
170
|
+
indexConfig = {
|
|
171
|
+
order: this.config.order ?? "asc",
|
|
172
|
+
nulls: this.config.nulls ?? "last",
|
|
173
|
+
opClass: this.config.opClass
|
|
174
|
+
};
|
|
175
|
+
defaultConfig = {
|
|
176
|
+
order: "asc",
|
|
177
|
+
nulls: "last",
|
|
178
|
+
opClass: void 0
|
|
179
|
+
};
|
|
180
|
+
asc() {
|
|
181
|
+
this.indexConfig.order = "asc";
|
|
182
|
+
return this;
|
|
417
183
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
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;
|
|
184
|
+
desc() {
|
|
185
|
+
this.indexConfig.order = "desc";
|
|
186
|
+
return this;
|
|
434
187
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
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(", ")}.`);
|
|
441
|
-
}
|
|
442
|
-
const chunks = [];
|
|
443
|
-
if (config.isolationLevel) {
|
|
444
|
-
chunks.push(`isolation level ${config.isolationLevel}`);
|
|
445
|
-
}
|
|
446
|
-
if (config.accessMode) {
|
|
447
|
-
chunks.push(config.accessMode);
|
|
448
|
-
}
|
|
449
|
-
return sql.raw(chunks.join(" "));
|
|
188
|
+
nullsFirst() {
|
|
189
|
+
this.indexConfig.nulls = "first";
|
|
190
|
+
return this;
|
|
450
191
|
}
|
|
451
|
-
|
|
452
|
-
|
|
192
|
+
nullsLast() {
|
|
193
|
+
this.indexConfig.nulls = "last";
|
|
194
|
+
return this;
|
|
453
195
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
196
|
+
};
|
|
197
|
+
var IndexedColumn = class {
|
|
198
|
+
static [entityKind] = "IndexedColumn";
|
|
199
|
+
name;
|
|
200
|
+
keyAsName;
|
|
201
|
+
type;
|
|
202
|
+
indexConfig;
|
|
203
|
+
constructor(name, keyAsName, type, indexConfig) {
|
|
204
|
+
this.name = name;
|
|
205
|
+
this.keyAsName = keyAsName;
|
|
206
|
+
this.type = type;
|
|
207
|
+
this.indexConfig = indexConfig;
|
|
461
208
|
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// src/dialect.ts
|
|
465
|
-
import { entityKind as entityKind2, is as is2 } from "drizzle-orm/entity";
|
|
466
|
-
import {
|
|
467
|
-
PgBigInt53,
|
|
468
|
-
PgBigInt64,
|
|
469
|
-
PgDate as PgDate2,
|
|
470
|
-
PgDateString as PgDateString2,
|
|
471
|
-
PgDialect,
|
|
472
|
-
PgDoublePrecision,
|
|
473
|
-
PgInteger,
|
|
474
|
-
PgNumeric,
|
|
475
|
-
PgReal,
|
|
476
|
-
PgSmallInt,
|
|
477
|
-
PgTime as PgTime2,
|
|
478
|
-
PgTimestamp as PgTimestamp2,
|
|
479
|
-
PgTimestampString as PgTimestampString2,
|
|
480
|
-
PgUUID
|
|
481
|
-
} from "drizzle-orm/pg-core";
|
|
482
|
-
import {
|
|
483
|
-
sql as sql2
|
|
484
|
-
} from "drizzle-orm";
|
|
209
|
+
};
|
|
485
210
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
211
|
+
// src/databend-core/columns/custom.ts
|
|
212
|
+
var DatabendCustomColumnBuilder = class extends DatabendColumnBuilder {
|
|
213
|
+
static [entityKind2] = "DatabendCustomColumnBuilder";
|
|
214
|
+
sqlDataType;
|
|
215
|
+
mapTo;
|
|
216
|
+
mapFrom;
|
|
217
|
+
constructor(name, fieldConfig, customTypeParams) {
|
|
218
|
+
super(name, "custom", "DatabendCustomColumn");
|
|
219
|
+
this.sqlDataType = customTypeParams.dataType(fieldConfig);
|
|
220
|
+
this.mapTo = customTypeParams.toDriver;
|
|
221
|
+
this.mapFrom = customTypeParams.fromDriver;
|
|
490
222
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
)
|
|
501
|
-
`;
|
|
502
|
-
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`);
|
|
504
|
-
const lastDbMigration = dbMigrations[0];
|
|
505
|
-
await session.transaction(async (tx) => {
|
|
506
|
-
for await (const migration of migrations) {
|
|
507
|
-
if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
|
|
508
|
-
for (const stmt of migration.sql) {
|
|
509
|
-
await tx.execute(sql2.raw(stmt));
|
|
510
|
-
}
|
|
511
|
-
await tx.execute(sql2`INSERT INTO ${sql2.identifier(migrationsSchema)}.${sql2.identifier(migrationsTable)} (id, hash, created_at)
|
|
512
|
-
VALUES (
|
|
513
|
-
(SELECT COALESCE(MAX(id), 0) + 1 FROM ${sql2.identifier(migrationsSchema)}.${sql2.identifier(migrationsTable)}),
|
|
514
|
-
${migration.hash},
|
|
515
|
-
${migration.folderMillis}
|
|
516
|
-
)`);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
});
|
|
223
|
+
/** @internal */
|
|
224
|
+
build(table) {
|
|
225
|
+
return new DatabendCustomColumn(
|
|
226
|
+
table,
|
|
227
|
+
this.config,
|
|
228
|
+
this.sqlDataType,
|
|
229
|
+
this.mapTo,
|
|
230
|
+
this.mapFrom
|
|
231
|
+
);
|
|
520
232
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
233
|
+
};
|
|
234
|
+
var DatabendCustomColumn = class extends DatabendColumn {
|
|
235
|
+
static [entityKind2] = "DatabendCustomColumn";
|
|
236
|
+
sqlDataType;
|
|
237
|
+
mapTo;
|
|
238
|
+
mapFrom;
|
|
239
|
+
constructor(table, config, sqlDataType, mapTo, mapFrom) {
|
|
240
|
+
super(table, config);
|
|
241
|
+
this.sqlDataType = sqlDataType;
|
|
242
|
+
this.mapTo = mapTo;
|
|
243
|
+
this.mapFrom = mapFrom;
|
|
244
|
+
}
|
|
245
|
+
getSQLType() {
|
|
246
|
+
return this.sqlDataType;
|
|
247
|
+
}
|
|
248
|
+
mapFromDriverValue(value) {
|
|
249
|
+
return this.mapFrom ? this.mapFrom(value) : value;
|
|
535
250
|
}
|
|
251
|
+
mapToDriverValue(value) {
|
|
252
|
+
return this.mapTo ? this.mapTo(value) : value;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
function customType(customTypeParams) {
|
|
256
|
+
return (dbName, fieldConfig) => {
|
|
257
|
+
return new DatabendCustomColumnBuilder(dbName, fieldConfig, customTypeParams);
|
|
258
|
+
};
|
|
536
259
|
}
|
|
537
260
|
|
|
538
|
-
// src/pool.ts
|
|
539
|
-
function createDatabendConnectionPool(client, options = {}) {
|
|
540
|
-
const size = options.size && options.size > 0 ? options.size : 4;
|
|
541
|
-
const acquireTimeout = options.acquireTimeout ?? 30000;
|
|
542
|
-
const maxWaitingRequests = options.maxWaitingRequests ?? 100;
|
|
543
|
-
const maxLifetimeMs = options.maxLifetimeMs;
|
|
544
|
-
const idleTimeoutMs = options.idleTimeoutMs;
|
|
545
|
-
const metadata = new WeakMap;
|
|
546
|
-
const idle = [];
|
|
547
|
-
const waiting = [];
|
|
548
|
-
let total = 0;
|
|
549
|
-
let closed = false;
|
|
550
|
-
let pendingAcquires = 0;
|
|
551
|
-
const shouldRecycle = (conn, now) => {
|
|
552
|
-
if (maxLifetimeMs !== undefined && now - conn.createdAt >= maxLifetimeMs) {
|
|
553
|
-
return true;
|
|
554
|
-
}
|
|
555
|
-
if (idleTimeoutMs !== undefined && now - conn.lastUsedAt >= idleTimeoutMs) {
|
|
556
|
-
return true;
|
|
557
|
-
}
|
|
558
|
-
return false;
|
|
559
|
-
};
|
|
560
|
-
const acquire = async () => {
|
|
561
|
-
if (closed) {
|
|
562
|
-
throw new Error("Databend connection pool is closed");
|
|
563
|
-
}
|
|
564
|
-
while (idle.length > 0) {
|
|
565
|
-
const pooled = idle.pop();
|
|
566
|
-
const now = Date.now();
|
|
567
|
-
if (shouldRecycle(pooled, now)) {
|
|
568
|
-
await closeClientConnection(pooled.connection);
|
|
569
|
-
total = Math.max(0, total - 1);
|
|
570
|
-
metadata.delete(pooled.connection);
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
pooled.lastUsedAt = now;
|
|
574
|
-
metadata.set(pooled.connection, {
|
|
575
|
-
createdAt: pooled.createdAt,
|
|
576
|
-
lastUsedAt: pooled.lastUsedAt
|
|
577
|
-
});
|
|
578
|
-
return pooled.connection;
|
|
579
|
-
}
|
|
580
|
-
if (total < size) {
|
|
581
|
-
pendingAcquires += 1;
|
|
582
|
-
total += 1;
|
|
583
|
-
try {
|
|
584
|
-
const connection = await client.getConn();
|
|
585
|
-
if (closed) {
|
|
586
|
-
await closeClientConnection(connection);
|
|
587
|
-
total -= 1;
|
|
588
|
-
throw new Error("Databend connection pool is closed");
|
|
589
|
-
}
|
|
590
|
-
const now = Date.now();
|
|
591
|
-
metadata.set(connection, { createdAt: now, lastUsedAt: now });
|
|
592
|
-
return connection;
|
|
593
|
-
} catch (error) {
|
|
594
|
-
total -= 1;
|
|
595
|
-
throw error;
|
|
596
|
-
} finally {
|
|
597
|
-
pendingAcquires -= 1;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
if (waiting.length >= maxWaitingRequests) {
|
|
601
|
-
throw new Error(`Databend connection pool queue is full (max ${maxWaitingRequests} waiting requests)`);
|
|
602
|
-
}
|
|
603
|
-
return await new Promise((resolve, reject) => {
|
|
604
|
-
const timeoutId = setTimeout(() => {
|
|
605
|
-
const idx = waiting.findIndex((w) => w.timeoutId === timeoutId);
|
|
606
|
-
if (idx !== -1) {
|
|
607
|
-
waiting.splice(idx, 1);
|
|
608
|
-
}
|
|
609
|
-
reject(new Error(`Databend connection pool acquire timeout after ${acquireTimeout}ms`));
|
|
610
|
-
}, acquireTimeout);
|
|
611
|
-
waiting.push({ resolve, reject, timeoutId });
|
|
612
|
-
});
|
|
613
|
-
};
|
|
614
|
-
const release = async (connection) => {
|
|
615
|
-
const waiter = waiting.shift();
|
|
616
|
-
if (waiter) {
|
|
617
|
-
clearTimeout(waiter.timeoutId);
|
|
618
|
-
const now2 = Date.now();
|
|
619
|
-
const meta = metadata.get(connection) ?? { createdAt: now2, lastUsedAt: now2 };
|
|
620
|
-
const expired = maxLifetimeMs !== undefined && now2 - meta.createdAt >= maxLifetimeMs;
|
|
621
|
-
if (closed) {
|
|
622
|
-
await closeClientConnection(connection);
|
|
623
|
-
total = Math.max(0, total - 1);
|
|
624
|
-
metadata.delete(connection);
|
|
625
|
-
waiter.reject(new Error("Databend connection pool is closed"));
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
if (expired) {
|
|
629
|
-
await closeClientConnection(connection);
|
|
630
|
-
total = Math.max(0, total - 1);
|
|
631
|
-
metadata.delete(connection);
|
|
632
|
-
try {
|
|
633
|
-
const replacement = await acquire();
|
|
634
|
-
waiter.resolve(replacement);
|
|
635
|
-
} catch (error) {
|
|
636
|
-
waiter.reject(error);
|
|
637
|
-
}
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
meta.lastUsedAt = now2;
|
|
641
|
-
metadata.set(connection, meta);
|
|
642
|
-
waiter.resolve(connection);
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
if (closed) {
|
|
646
|
-
await closeClientConnection(connection);
|
|
647
|
-
metadata.delete(connection);
|
|
648
|
-
total = Math.max(0, total - 1);
|
|
649
|
-
return;
|
|
650
|
-
}
|
|
651
|
-
const now = Date.now();
|
|
652
|
-
const existingMeta = metadata.get(connection) ?? { createdAt: now, lastUsedAt: now };
|
|
653
|
-
existingMeta.lastUsedAt = now;
|
|
654
|
-
metadata.set(connection, existingMeta);
|
|
655
|
-
if (maxLifetimeMs !== undefined && now - existingMeta.createdAt >= maxLifetimeMs) {
|
|
656
|
-
await closeClientConnection(connection);
|
|
657
|
-
total -= 1;
|
|
658
|
-
metadata.delete(connection);
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
|
-
idle.push({
|
|
662
|
-
connection,
|
|
663
|
-
createdAt: existingMeta.createdAt,
|
|
664
|
-
lastUsedAt: existingMeta.lastUsedAt
|
|
665
|
-
});
|
|
666
|
-
};
|
|
667
|
-
const close = async () => {
|
|
668
|
-
closed = true;
|
|
669
|
-
const waiters = waiting.splice(0, waiting.length);
|
|
670
|
-
for (const waiter of waiters) {
|
|
671
|
-
clearTimeout(waiter.timeoutId);
|
|
672
|
-
waiter.reject(new Error("Databend connection pool is closed"));
|
|
673
|
-
}
|
|
674
|
-
const toClose = idle.splice(0, idle.length);
|
|
675
|
-
await Promise.allSettled(toClose.map((item) => closeClientConnection(item.connection)));
|
|
676
|
-
total = Math.max(0, total - toClose.length);
|
|
677
|
-
toClose.forEach((item) => metadata.delete(item.connection));
|
|
678
|
-
const maxWait = 5000;
|
|
679
|
-
const start = Date.now();
|
|
680
|
-
while (pendingAcquires > 0 && Date.now() - start < maxWait) {
|
|
681
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
682
|
-
}
|
|
683
|
-
};
|
|
684
|
-
return {
|
|
685
|
-
acquire,
|
|
686
|
-
release,
|
|
687
|
-
close,
|
|
688
|
-
size
|
|
689
|
-
};
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// src/driver.ts
|
|
693
|
-
class DatabendDriver {
|
|
694
|
-
client;
|
|
695
|
-
dialect;
|
|
696
|
-
options;
|
|
697
|
-
static [entityKind3] = "DatabendDriver";
|
|
698
|
-
constructor(client, dialect, options = {}) {
|
|
699
|
-
this.client = client;
|
|
700
|
-
this.dialect = dialect;
|
|
701
|
-
this.options = options;
|
|
702
|
-
}
|
|
703
|
-
createSession(schema) {
|
|
704
|
-
return new DatabendSession(this.client, this.dialect, schema, {
|
|
705
|
-
logger: this.options.logger
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
function isConfigObject(data) {
|
|
710
|
-
if (typeof data !== "object" || data === null)
|
|
711
|
-
return false;
|
|
712
|
-
if (data.constructor?.name !== "Object")
|
|
713
|
-
return false;
|
|
714
|
-
return "connection" in data || "client" in data || "pool" in data || "schema" in data || "logger" in data;
|
|
715
|
-
}
|
|
716
|
-
function createFromClient(client, config = {}, databendClient) {
|
|
717
|
-
const dialect = new DatabendDialect;
|
|
718
|
-
const logger = config.logger === true ? new DefaultLogger : config.logger || undefined;
|
|
719
|
-
let schema;
|
|
720
|
-
if (config.schema) {
|
|
721
|
-
const tablesConfig = extractTablesRelationalConfig(config.schema, createTableRelationsHelpers);
|
|
722
|
-
schema = {
|
|
723
|
-
fullSchema: config.schema,
|
|
724
|
-
schema: tablesConfig.tables,
|
|
725
|
-
tableNamesMap: tablesConfig.tableNamesMap
|
|
726
|
-
};
|
|
727
|
-
}
|
|
728
|
-
const driver = new DatabendDriver(client, dialect, { logger });
|
|
729
|
-
const session = driver.createSession(schema);
|
|
730
|
-
const db = new DatabendDatabase(dialect, session, schema, client, databendClient);
|
|
731
|
-
return db;
|
|
732
|
-
}
|
|
733
|
-
async function createFromDsn(dsn, config = {}) {
|
|
734
|
-
const databendClient = new Client(dsn);
|
|
735
|
-
if (config.pool === false) {
|
|
736
|
-
const connection = await databendClient.getConn();
|
|
737
|
-
return createFromClient(connection, config, databendClient);
|
|
738
|
-
}
|
|
739
|
-
const poolSize = config.pool?.size ?? 4;
|
|
740
|
-
const pool = createDatabendConnectionPool(databendClient, { size: poolSize });
|
|
741
|
-
return createFromClient(pool, config, databendClient);
|
|
742
|
-
}
|
|
743
|
-
function drizzle(clientOrConfigOrDsn, config) {
|
|
744
|
-
if (typeof clientOrConfigOrDsn === "string") {
|
|
745
|
-
return createFromDsn(clientOrConfigOrDsn, config);
|
|
746
|
-
}
|
|
747
|
-
if (isConfigObject(clientOrConfigOrDsn)) {
|
|
748
|
-
const configObj = clientOrConfigOrDsn;
|
|
749
|
-
if ("connection" in configObj) {
|
|
750
|
-
const connConfig = configObj;
|
|
751
|
-
const { connection, ...restConfig } = connConfig;
|
|
752
|
-
return createFromDsn(connection, restConfig);
|
|
753
|
-
}
|
|
754
|
-
if ("client" in configObj) {
|
|
755
|
-
const clientConfig = configObj;
|
|
756
|
-
const { client: clientValue, ...restConfig } = clientConfig;
|
|
757
|
-
return createFromClient(clientValue, restConfig);
|
|
758
|
-
}
|
|
759
|
-
throw new Error("Invalid drizzle config: either connection or client must be provided");
|
|
760
|
-
}
|
|
761
|
-
return createFromClient(clientOrConfigOrDsn, config);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
class DatabendDatabase extends PgDatabase {
|
|
765
|
-
dialect;
|
|
766
|
-
session;
|
|
767
|
-
static [entityKind3] = "DatabendDatabase";
|
|
768
|
-
$client;
|
|
769
|
-
$databendClient;
|
|
770
|
-
constructor(dialect, session, schema, client, databendClient) {
|
|
771
|
-
super(dialect, session, schema);
|
|
772
|
-
this.dialect = dialect;
|
|
773
|
-
this.session = session;
|
|
774
|
-
this.$client = client;
|
|
775
|
-
this.$databendClient = databendClient;
|
|
776
|
-
}
|
|
777
|
-
async close() {
|
|
778
|
-
if (isPool(this.$client) && this.$client.close) {
|
|
779
|
-
await this.$client.close();
|
|
780
|
-
}
|
|
781
|
-
if (!isPool(this.$client)) {
|
|
782
|
-
await closeClientConnection(this.$client);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
async transaction(transaction) {
|
|
786
|
-
return await this.session.transaction(transaction);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
261
|
// src/columns.ts
|
|
790
|
-
import { customType } from "drizzle-orm/pg-core";
|
|
791
262
|
var databendVariant = (name) => customType({
|
|
792
263
|
dataType() {
|
|
793
264
|
return "VARIANT";
|
|
@@ -900,32 +371,3012 @@ var databendDate = (name) => customType({
|
|
|
900
371
|
return value.slice(0, 10);
|
|
901
372
|
}
|
|
902
373
|
})(name);
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
await db.dialect.migrate(migrations, db.session, migrationConfig);
|
|
374
|
+
|
|
375
|
+
// src/databend-core/alias.ts
|
|
376
|
+
import { TableAliasProxyHandler } from "drizzle-orm/alias";
|
|
377
|
+
function alias(table, alias2) {
|
|
378
|
+
return new Proxy(table, new TableAliasProxyHandler(alias2, false));
|
|
909
379
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
380
|
+
|
|
381
|
+
// src/databend-core/columns/bigint.ts
|
|
382
|
+
import { entityKind as entityKind3 } from "drizzle-orm/entity";
|
|
383
|
+
var DatabendBigInt53Builder = class extends DatabendColumnBuilder {
|
|
384
|
+
static [entityKind3] = "DatabendBigInt53Builder";
|
|
385
|
+
constructor(name) {
|
|
386
|
+
super(name, "number", "DatabendBigInt53");
|
|
387
|
+
}
|
|
388
|
+
/** @internal */
|
|
389
|
+
build(table) {
|
|
390
|
+
return new DatabendBigInt53(table, this.config);
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
var DatabendBigInt53 = class extends DatabendColumn {
|
|
394
|
+
static [entityKind3] = "DatabendBigInt53";
|
|
395
|
+
getSQLType() {
|
|
396
|
+
return "bigint";
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
var DatabendBigInt64Builder = class extends DatabendColumnBuilder {
|
|
400
|
+
static [entityKind3] = "DatabendBigInt64Builder";
|
|
401
|
+
constructor(name) {
|
|
402
|
+
super(name, "bigint", "DatabendBigInt64");
|
|
403
|
+
}
|
|
404
|
+
/** @internal */
|
|
405
|
+
build(table) {
|
|
406
|
+
return new DatabendBigInt64(table, this.config);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var DatabendBigInt64 = class extends DatabendColumn {
|
|
410
|
+
static [entityKind3] = "DatabendBigInt64";
|
|
411
|
+
getSQLType() {
|
|
412
|
+
return "bigint";
|
|
413
|
+
}
|
|
414
|
+
mapFromDriverValue(value) {
|
|
415
|
+
return BigInt(value);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
function bigint(name) {
|
|
419
|
+
return new DatabendBigInt53Builder(name ?? "");
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// src/databend-core/columns/binary.ts
|
|
423
|
+
import { entityKind as entityKind4 } from "drizzle-orm/entity";
|
|
424
|
+
var DatabendBinaryBuilder = class extends DatabendColumnBuilder {
|
|
425
|
+
static [entityKind4] = "DatabendBinaryBuilder";
|
|
426
|
+
constructor(name) {
|
|
427
|
+
super(name, "string", "DatabendBinary");
|
|
428
|
+
}
|
|
429
|
+
/** @internal */
|
|
430
|
+
build(table) {
|
|
431
|
+
return new DatabendBinary(table, this.config);
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
var DatabendBinary = class extends DatabendColumn {
|
|
435
|
+
static [entityKind4] = "DatabendBinary";
|
|
436
|
+
getSQLType() {
|
|
437
|
+
return "binary";
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
function binary(name) {
|
|
441
|
+
return new DatabendBinaryBuilder(name ?? "");
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// src/databend-core/columns/bitmap.ts
|
|
445
|
+
import { entityKind as entityKind5 } from "drizzle-orm/entity";
|
|
446
|
+
var DatabendBitmapBuilder = class extends DatabendColumnBuilder {
|
|
447
|
+
static [entityKind5] = "DatabendBitmapBuilder";
|
|
448
|
+
constructor(name) {
|
|
449
|
+
super(name, "string", "DatabendBitmap");
|
|
450
|
+
}
|
|
451
|
+
/** @internal */
|
|
452
|
+
build(table) {
|
|
453
|
+
return new DatabendBitmap(table, this.config);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
var DatabendBitmap = class extends DatabendColumn {
|
|
457
|
+
static [entityKind5] = "DatabendBitmap";
|
|
458
|
+
getSQLType() {
|
|
459
|
+
return "bitmap";
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
function bitmap(name) {
|
|
463
|
+
return new DatabendBitmapBuilder(name ?? "");
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// src/databend-core/columns/boolean.ts
|
|
467
|
+
import { entityKind as entityKind6 } from "drizzle-orm/entity";
|
|
468
|
+
var DatabendBooleanBuilder = class extends DatabendColumnBuilder {
|
|
469
|
+
static [entityKind6] = "DatabendBooleanBuilder";
|
|
470
|
+
constructor(name) {
|
|
471
|
+
super(name, "boolean", "DatabendBoolean");
|
|
472
|
+
}
|
|
473
|
+
/** @internal */
|
|
474
|
+
build(table) {
|
|
475
|
+
return new DatabendBoolean(table, this.config);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
var DatabendBoolean = class extends DatabendColumn {
|
|
479
|
+
static [entityKind6] = "DatabendBoolean";
|
|
480
|
+
getSQLType() {
|
|
481
|
+
return "boolean";
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
function boolean(name) {
|
|
485
|
+
return new DatabendBooleanBuilder(name ?? "");
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// src/databend-core/columns/date.ts
|
|
489
|
+
import { entityKind as entityKind7 } from "drizzle-orm/entity";
|
|
490
|
+
import { sql } from "drizzle-orm/sql/sql";
|
|
491
|
+
var DatabendDateBuilder = class extends DatabendColumnBuilder {
|
|
492
|
+
static [entityKind7] = "DatabendDateBuilder";
|
|
493
|
+
constructor(name) {
|
|
494
|
+
super(name, "string", "DatabendDate");
|
|
495
|
+
}
|
|
496
|
+
defaultNow() {
|
|
497
|
+
return this.default(sql`now()`);
|
|
498
|
+
}
|
|
499
|
+
/** @internal */
|
|
500
|
+
build(table) {
|
|
501
|
+
return new DatabendDate(table, this.config);
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
var DatabendDate = class extends DatabendColumn {
|
|
505
|
+
static [entityKind7] = "DatabendDate";
|
|
506
|
+
getSQLType() {
|
|
507
|
+
return "date";
|
|
508
|
+
}
|
|
509
|
+
mapFromDriverValue(value) {
|
|
510
|
+
if (value instanceof Date) {
|
|
511
|
+
return value.toISOString().slice(0, 10);
|
|
512
|
+
}
|
|
513
|
+
if (typeof value === "string") {
|
|
514
|
+
return value.slice(0, 10);
|
|
515
|
+
}
|
|
516
|
+
return value;
|
|
517
|
+
}
|
|
518
|
+
mapToDriverValue(value) {
|
|
519
|
+
if (value instanceof Date) {
|
|
520
|
+
return value.toISOString().slice(0, 10);
|
|
521
|
+
}
|
|
522
|
+
return value;
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
function date(name) {
|
|
526
|
+
return new DatabendDateBuilder(name ?? "");
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// src/databend-core/columns/decimal.ts
|
|
530
|
+
import { entityKind as entityKind8 } from "drizzle-orm/entity";
|
|
531
|
+
var DatabendDecimalBuilder = class extends DatabendColumnBuilder {
|
|
532
|
+
static [entityKind8] = "DatabendDecimalBuilder";
|
|
533
|
+
constructor(name, precision, scale) {
|
|
534
|
+
super(name, "string", "DatabendDecimal");
|
|
535
|
+
this.config.precision = precision;
|
|
536
|
+
this.config.scale = scale;
|
|
537
|
+
}
|
|
538
|
+
/** @internal */
|
|
539
|
+
build(table) {
|
|
540
|
+
return new DatabendDecimal(table, this.config);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
var DatabendDecimal = class extends DatabendColumn {
|
|
544
|
+
static [entityKind8] = "DatabendDecimal";
|
|
545
|
+
precision;
|
|
546
|
+
scale;
|
|
547
|
+
constructor(table, config) {
|
|
548
|
+
super(table, config);
|
|
549
|
+
this.precision = config.precision;
|
|
550
|
+
this.scale = config.scale;
|
|
551
|
+
}
|
|
552
|
+
getSQLType() {
|
|
553
|
+
if (this.precision !== void 0 && this.scale !== void 0) {
|
|
554
|
+
return `decimal(${this.precision}, ${this.scale})`;
|
|
555
|
+
}
|
|
556
|
+
if (this.precision !== void 0) {
|
|
557
|
+
return `decimal(${this.precision})`;
|
|
558
|
+
}
|
|
559
|
+
return "decimal";
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
function decimal(name, config) {
|
|
563
|
+
return new DatabendDecimalBuilder(name ?? "", config?.precision, config?.scale);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/databend-core/columns/double.ts
|
|
567
|
+
import { entityKind as entityKind9 } from "drizzle-orm/entity";
|
|
568
|
+
var DatabendDoublePrecisionBuilder = class extends DatabendColumnBuilder {
|
|
569
|
+
static [entityKind9] = "DatabendDoublePrecisionBuilder";
|
|
570
|
+
constructor(name) {
|
|
571
|
+
super(name, "number", "DatabendDoublePrecision");
|
|
572
|
+
}
|
|
573
|
+
/** @internal */
|
|
574
|
+
build(table) {
|
|
575
|
+
return new DatabendDoublePrecision(table, this.config);
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
var DatabendDoublePrecision = class extends DatabendColumn {
|
|
579
|
+
static [entityKind9] = "DatabendDoublePrecision";
|
|
580
|
+
getSQLType() {
|
|
581
|
+
return "double";
|
|
582
|
+
}
|
|
583
|
+
mapFromDriverValue(value) {
|
|
584
|
+
if (typeof value === "string") {
|
|
585
|
+
return Number.parseFloat(value);
|
|
586
|
+
}
|
|
587
|
+
return value;
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
function doublePrecision(name) {
|
|
591
|
+
return new DatabendDoublePrecisionBuilder(name ?? "");
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// src/databend-core/columns/float.ts
|
|
595
|
+
import { entityKind as entityKind10 } from "drizzle-orm/entity";
|
|
596
|
+
var DatabendRealBuilder = class extends DatabendColumnBuilder {
|
|
597
|
+
static [entityKind10] = "DatabendRealBuilder";
|
|
598
|
+
constructor(name) {
|
|
599
|
+
super(name, "number", "DatabendReal");
|
|
600
|
+
}
|
|
601
|
+
/** @internal */
|
|
602
|
+
build(table) {
|
|
603
|
+
return new DatabendReal(table, this.config);
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
var DatabendReal = class extends DatabendColumn {
|
|
607
|
+
static [entityKind10] = "DatabendReal";
|
|
608
|
+
getSQLType() {
|
|
609
|
+
return "real";
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
function real(name) {
|
|
613
|
+
return new DatabendRealBuilder(name ?? "");
|
|
614
|
+
}
|
|
615
|
+
function float(name) {
|
|
616
|
+
return new DatabendRealBuilder(name ?? "");
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// src/databend-core/columns/integer.ts
|
|
620
|
+
import { entityKind as entityKind11 } from "drizzle-orm/entity";
|
|
621
|
+
var DatabendIntegerBuilder = class extends DatabendColumnBuilder {
|
|
622
|
+
static [entityKind11] = "DatabendIntegerBuilder";
|
|
623
|
+
constructor(name) {
|
|
624
|
+
super(name, "number", "DatabendInteger");
|
|
625
|
+
}
|
|
626
|
+
/** @internal */
|
|
627
|
+
build(table) {
|
|
628
|
+
return new DatabendInteger(table, this.config);
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
var DatabendInteger = class extends DatabendColumn {
|
|
632
|
+
static [entityKind11] = "DatabendInteger";
|
|
633
|
+
getSQLType() {
|
|
634
|
+
return "integer";
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
function integer(name) {
|
|
638
|
+
return new DatabendIntegerBuilder(name ?? "");
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// src/databend-core/columns/smallint.ts
|
|
642
|
+
import { entityKind as entityKind12 } from "drizzle-orm/entity";
|
|
643
|
+
var DatabendSmallIntBuilder = class extends DatabendColumnBuilder {
|
|
644
|
+
static [entityKind12] = "DatabendSmallIntBuilder";
|
|
645
|
+
constructor(name) {
|
|
646
|
+
super(name, "number", "DatabendSmallInt");
|
|
647
|
+
}
|
|
648
|
+
/** @internal */
|
|
649
|
+
build(table) {
|
|
650
|
+
return new DatabendSmallInt(table, this.config);
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
var DatabendSmallInt = class extends DatabendColumn {
|
|
654
|
+
static [entityKind12] = "DatabendSmallInt";
|
|
655
|
+
getSQLType() {
|
|
656
|
+
return "smallint";
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
function smallint(name) {
|
|
660
|
+
return new DatabendSmallIntBuilder(name ?? "");
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/databend-core/columns/text.ts
|
|
664
|
+
import { entityKind as entityKind13 } from "drizzle-orm/entity";
|
|
665
|
+
var DatabendTextBuilder = class extends DatabendColumnBuilder {
|
|
666
|
+
static [entityKind13] = "DatabendTextBuilder";
|
|
667
|
+
constructor(name) {
|
|
668
|
+
super(name, "string", "DatabendText");
|
|
669
|
+
}
|
|
670
|
+
/** @internal */
|
|
671
|
+
build(table) {
|
|
672
|
+
return new DatabendText(table, this.config);
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
var DatabendText = class extends DatabendColumn {
|
|
676
|
+
static [entityKind13] = "DatabendText";
|
|
677
|
+
getSQLType() {
|
|
678
|
+
return "text";
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
function text(name) {
|
|
682
|
+
return new DatabendTextBuilder(name ?? "");
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// src/databend-core/columns/timestamp.ts
|
|
686
|
+
import { entityKind as entityKind14 } from "drizzle-orm/entity";
|
|
687
|
+
import { sql as sql2 } from "drizzle-orm/sql/sql";
|
|
688
|
+
var DatabendTimestampBuilder = class extends DatabendColumnBuilder {
|
|
689
|
+
static [entityKind14] = "DatabendTimestampBuilder";
|
|
690
|
+
constructor(name) {
|
|
691
|
+
super(name, "date", "DatabendTimestamp");
|
|
692
|
+
}
|
|
693
|
+
defaultNow() {
|
|
694
|
+
return this.default(sql2`now()`);
|
|
695
|
+
}
|
|
696
|
+
/** @internal */
|
|
697
|
+
build(table) {
|
|
698
|
+
return new DatabendTimestamp(table, this.config);
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
var DatabendTimestamp = class extends DatabendColumn {
|
|
702
|
+
static [entityKind14] = "DatabendTimestamp";
|
|
703
|
+
getSQLType() {
|
|
704
|
+
return "timestamp";
|
|
705
|
+
}
|
|
706
|
+
mapFromDriverValue(value) {
|
|
707
|
+
if (value instanceof Date) {
|
|
708
|
+
return value;
|
|
709
|
+
}
|
|
710
|
+
const str = String(value);
|
|
711
|
+
const hasOffset = str.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(str);
|
|
712
|
+
const normalized = hasOffset ? str.replace(" ", "T") : `${str.replace(" ", "T")}Z`;
|
|
713
|
+
return new Date(normalized);
|
|
714
|
+
}
|
|
715
|
+
mapToDriverValue(value) {
|
|
716
|
+
if (value instanceof Date) {
|
|
717
|
+
return value.toISOString();
|
|
718
|
+
}
|
|
719
|
+
return value;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
function timestamp(name) {
|
|
723
|
+
return new DatabendTimestampBuilder(name ?? "");
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// src/databend-core/columns/tinyint.ts
|
|
727
|
+
import { entityKind as entityKind15 } from "drizzle-orm/entity";
|
|
728
|
+
var DatabendTinyIntBuilder = class extends DatabendColumnBuilder {
|
|
729
|
+
static [entityKind15] = "DatabendTinyIntBuilder";
|
|
730
|
+
constructor(name) {
|
|
731
|
+
super(name, "number", "DatabendTinyInt");
|
|
732
|
+
}
|
|
733
|
+
/** @internal */
|
|
734
|
+
build(table) {
|
|
735
|
+
return new DatabendTinyInt(table, this.config);
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
var DatabendTinyInt = class extends DatabendColumn {
|
|
739
|
+
static [entityKind15] = "DatabendTinyInt";
|
|
740
|
+
getSQLType() {
|
|
741
|
+
return "tinyint";
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
function tinyint(name) {
|
|
745
|
+
return new DatabendTinyIntBuilder(name ?? "");
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// src/databend-core/columns/varchar.ts
|
|
749
|
+
import { entityKind as entityKind16 } from "drizzle-orm/entity";
|
|
750
|
+
var DatabendVarcharBuilder = class extends DatabendColumnBuilder {
|
|
751
|
+
static [entityKind16] = "DatabendVarcharBuilder";
|
|
752
|
+
constructor(name, length) {
|
|
753
|
+
super(name, "string", "DatabendVarchar");
|
|
754
|
+
this.config.length = length;
|
|
755
|
+
}
|
|
756
|
+
/** @internal */
|
|
757
|
+
build(table) {
|
|
758
|
+
return new DatabendVarchar(table, this.config);
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
var DatabendVarchar = class extends DatabendColumn {
|
|
762
|
+
static [entityKind16] = "DatabendVarchar";
|
|
763
|
+
length;
|
|
764
|
+
constructor(table, config) {
|
|
765
|
+
super(table, config);
|
|
766
|
+
this.length = config.length;
|
|
767
|
+
}
|
|
768
|
+
getSQLType() {
|
|
769
|
+
return this.length ? `varchar(${this.length})` : "varchar";
|
|
770
|
+
}
|
|
771
|
+
};
|
|
772
|
+
function varchar(name, config) {
|
|
773
|
+
return new DatabendVarcharBuilder(name ?? "", config?.length);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/databend-core/columns/variant.ts
|
|
777
|
+
import { entityKind as entityKind17 } from "drizzle-orm/entity";
|
|
778
|
+
var DatabendVariantBuilder = class extends DatabendColumnBuilder {
|
|
779
|
+
static [entityKind17] = "DatabendVariantBuilder";
|
|
780
|
+
constructor(name) {
|
|
781
|
+
super(name, "json", "DatabendVariant");
|
|
782
|
+
}
|
|
783
|
+
/** @internal */
|
|
784
|
+
build(table) {
|
|
785
|
+
return new DatabendVariant(table, this.config);
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
var DatabendVariant = class extends DatabendColumn {
|
|
789
|
+
static [entityKind17] = "DatabendVariant";
|
|
790
|
+
getSQLType() {
|
|
791
|
+
return "variant";
|
|
792
|
+
}
|
|
793
|
+
mapFromDriverValue(value) {
|
|
794
|
+
if (typeof value === "string") {
|
|
795
|
+
try {
|
|
796
|
+
return JSON.parse(value);
|
|
797
|
+
} catch {
|
|
798
|
+
return value;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return value;
|
|
802
|
+
}
|
|
803
|
+
mapToDriverValue(value) {
|
|
804
|
+
if (typeof value === "string") {
|
|
805
|
+
return value;
|
|
806
|
+
}
|
|
807
|
+
return JSON.stringify(value);
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
function variant(name) {
|
|
811
|
+
return new DatabendVariantBuilder(name ?? "");
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// src/databend-core/columns/all.ts
|
|
815
|
+
function getDatabendColumnBuilders() {
|
|
816
|
+
return {
|
|
817
|
+
bigint,
|
|
818
|
+
binary,
|
|
819
|
+
bitmap,
|
|
820
|
+
boolean,
|
|
821
|
+
customType,
|
|
822
|
+
date,
|
|
823
|
+
decimal,
|
|
824
|
+
doublePrecision,
|
|
825
|
+
float,
|
|
826
|
+
integer,
|
|
827
|
+
real,
|
|
828
|
+
smallint,
|
|
829
|
+
text,
|
|
830
|
+
timestamp,
|
|
831
|
+
tinyint,
|
|
832
|
+
varchar,
|
|
833
|
+
variant
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/databend-core/dialect.ts
|
|
838
|
+
import { aliasedTable, aliasedTableColumn, mapColumnsInAliasedSQLToAlias, mapColumnsInSQLToAlias } from "drizzle-orm/alias";
|
|
839
|
+
import { CasingCache } from "drizzle-orm/casing";
|
|
840
|
+
import { Column as Column2 } from "drizzle-orm/column";
|
|
841
|
+
import { entityKind as entityKind20, is } from "drizzle-orm/entity";
|
|
842
|
+
import { DrizzleError } from "drizzle-orm/errors";
|
|
843
|
+
import {
|
|
844
|
+
getOperators,
|
|
845
|
+
getOrderByOperators,
|
|
846
|
+
Many,
|
|
847
|
+
normalizeRelation,
|
|
848
|
+
One
|
|
849
|
+
} from "drizzle-orm/relations";
|
|
850
|
+
import { and, eq, View as View2 } from "drizzle-orm/sql";
|
|
851
|
+
import { Param, SQL, sql as sql3 } from "drizzle-orm/sql/sql";
|
|
852
|
+
import { Subquery } from "drizzle-orm/subquery";
|
|
853
|
+
import { getTableName, getTableUniqueName, Table as Table2 } from "drizzle-orm/table";
|
|
854
|
+
import { orderSelectedFields } from "drizzle-orm/utils";
|
|
855
|
+
import { ViewBaseConfig } from "drizzle-orm/view-common";
|
|
856
|
+
|
|
857
|
+
// src/databend-core/table.ts
|
|
858
|
+
import { entityKind as entityKind18 } from "drizzle-orm/entity";
|
|
859
|
+
import { Table } from "drizzle-orm/table";
|
|
860
|
+
var DatabendTable = class extends Table {
|
|
861
|
+
static [entityKind18] = "DatabendTable";
|
|
862
|
+
/** @internal */
|
|
863
|
+
static Symbol = Object.assign({}, Table.Symbol, {});
|
|
864
|
+
constructor(name, schema, baseName) {
|
|
865
|
+
super(name, schema, baseName);
|
|
866
|
+
this[Table.Symbol.ExtraConfigBuilder] = void 0;
|
|
867
|
+
this[Table.Symbol.ExtraConfigColumns] = {};
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
function databendTableWithSchema(name, columns, extraConfig, schema, baseName = name) {
|
|
871
|
+
const rawTable = new DatabendTable(name, schema, baseName);
|
|
872
|
+
const parsedColumns = typeof columns === "function" ? columns(getDatabendColumnBuilders()) : columns;
|
|
873
|
+
const builtColumns = Object.fromEntries(
|
|
874
|
+
Object.entries(parsedColumns).map(([name2, colBuilderBase]) => {
|
|
875
|
+
const colBuilder = colBuilderBase;
|
|
876
|
+
colBuilder.setName(name2);
|
|
877
|
+
const column = colBuilder.build(rawTable);
|
|
878
|
+
return [name2, column];
|
|
879
|
+
})
|
|
880
|
+
);
|
|
881
|
+
const builtColumnsForExtraConfig = Object.fromEntries(
|
|
882
|
+
Object.entries(parsedColumns).map(([name2, colBuilderBase]) => {
|
|
883
|
+
const colBuilder = colBuilderBase;
|
|
884
|
+
colBuilder.setName(name2);
|
|
885
|
+
const column = colBuilder.buildExtraConfigColumn(rawTable);
|
|
886
|
+
return [name2, column];
|
|
887
|
+
})
|
|
888
|
+
);
|
|
889
|
+
const table = Object.assign(rawTable, builtColumns);
|
|
890
|
+
table[Table.Symbol.Columns] = builtColumns;
|
|
891
|
+
table[Table.Symbol.ExtraConfigColumns] = builtColumnsForExtraConfig;
|
|
892
|
+
if (extraConfig) {
|
|
893
|
+
table[DatabendTable.Symbol.ExtraConfigBuilder] = extraConfig;
|
|
894
|
+
}
|
|
895
|
+
return table;
|
|
896
|
+
}
|
|
897
|
+
var databendTable = (name, columns, extraConfig) => {
|
|
898
|
+
return databendTableWithSchema(name, columns, extraConfig, void 0);
|
|
899
|
+
};
|
|
900
|
+
function databendTableCreator(customizeTableName) {
|
|
901
|
+
return (name, columns, extraConfig) => {
|
|
902
|
+
return databendTableWithSchema(customizeTableName(name), columns, extraConfig, void 0, name);
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/databend-core/view-base.ts
|
|
907
|
+
import { entityKind as entityKind19 } from "drizzle-orm/entity";
|
|
908
|
+
import { View } from "drizzle-orm/sql/sql";
|
|
909
|
+
var DatabendViewBase = class extends View {
|
|
910
|
+
static [entityKind19] = "DatabendViewBase";
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
// src/databend-core/dialect.ts
|
|
914
|
+
var DatabendDialect = class {
|
|
915
|
+
static [entityKind20] = "DatabendDialect";
|
|
916
|
+
/** @internal */
|
|
917
|
+
casing;
|
|
918
|
+
constructor(config) {
|
|
919
|
+
this.casing = new CasingCache(config?.casing);
|
|
920
|
+
}
|
|
921
|
+
async migrate(migrations, session, config) {
|
|
922
|
+
const migrationConfig = typeof config === "string" ? { migrationsFolder: config } : config;
|
|
923
|
+
const migrationsSchema = migrationConfig.migrationsSchema ?? "default";
|
|
924
|
+
const migrationsTable = migrationConfig.migrationsTable ?? "__drizzle_migrations";
|
|
925
|
+
const migrationTableCreate = sql3`
|
|
926
|
+
CREATE TABLE IF NOT EXISTS ${sql3.identifier(migrationsSchema)}.${sql3.identifier(
|
|
927
|
+
migrationsTable
|
|
928
|
+
)} (
|
|
929
|
+
id INT NOT NULL,
|
|
930
|
+
hash VARCHAR NOT NULL,
|
|
931
|
+
created_at BIGINT
|
|
932
|
+
)
|
|
933
|
+
`;
|
|
934
|
+
await session.execute(migrationTableCreate);
|
|
935
|
+
const dbMigrations = await session.all(
|
|
936
|
+
sql3`SELECT id, hash, created_at FROM ${sql3.identifier(
|
|
937
|
+
migrationsSchema
|
|
938
|
+
)}.${sql3.identifier(migrationsTable)} ORDER BY created_at DESC LIMIT 1`
|
|
939
|
+
);
|
|
940
|
+
const lastDbMigration = dbMigrations[0];
|
|
941
|
+
await session.transaction(async (tx) => {
|
|
942
|
+
for await (const migration of migrations) {
|
|
943
|
+
if (!lastDbMigration || Number(lastDbMigration.created_at) < migration.folderMillis) {
|
|
944
|
+
for (const stmt of migration.sql) {
|
|
945
|
+
await tx.execute(sql3.raw(stmt));
|
|
946
|
+
}
|
|
947
|
+
await tx.execute(
|
|
948
|
+
sql3`INSERT INTO ${sql3.identifier(
|
|
949
|
+
migrationsSchema
|
|
950
|
+
)}.${sql3.identifier(migrationsTable)} (id, hash, created_at)
|
|
951
|
+
VALUES (
|
|
952
|
+
(SELECT COALESCE(MAX(id), 0) + 1 FROM ${sql3.identifier(
|
|
953
|
+
migrationsSchema
|
|
954
|
+
)}.${sql3.identifier(migrationsTable)}),
|
|
955
|
+
${migration.hash},
|
|
956
|
+
${migration.folderMillis}
|
|
957
|
+
)`
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
escapeName(name) {
|
|
964
|
+
return `"${name}"`;
|
|
965
|
+
}
|
|
966
|
+
escapeParam(num) {
|
|
967
|
+
return `$${num + 1}`;
|
|
968
|
+
}
|
|
969
|
+
escapeString(str) {
|
|
970
|
+
return `'${str.replace(/'/g, "''")}'`;
|
|
971
|
+
}
|
|
972
|
+
buildWithCTE(queries) {
|
|
973
|
+
if (!queries?.length) return void 0;
|
|
974
|
+
const withSqlChunks = [sql3`with `];
|
|
975
|
+
for (const [i, w] of queries.entries()) {
|
|
976
|
+
withSqlChunks.push(sql3`${sql3.identifier(w._.alias)} as (${w._.sql})`);
|
|
977
|
+
if (i < queries.length - 1) {
|
|
978
|
+
withSqlChunks.push(sql3`, `);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
withSqlChunks.push(sql3` `);
|
|
982
|
+
return sql3.join(withSqlChunks);
|
|
983
|
+
}
|
|
984
|
+
buildDeleteQuery({ table, where, withList }) {
|
|
985
|
+
const withSql = this.buildWithCTE(withList);
|
|
986
|
+
const whereSql = where ? sql3` where ${where}` : void 0;
|
|
987
|
+
return sql3`${withSql}delete from ${table}${whereSql}`;
|
|
988
|
+
}
|
|
989
|
+
buildUpdateSet(table, set) {
|
|
990
|
+
const tableColumns = table[Table2.Symbol.Columns];
|
|
991
|
+
const columnNames = Object.keys(tableColumns).filter(
|
|
992
|
+
(colName) => set[colName] !== void 0 || tableColumns[colName]?.onUpdateFn !== void 0
|
|
993
|
+
);
|
|
994
|
+
const setSize = columnNames.length;
|
|
995
|
+
return sql3.join(
|
|
996
|
+
columnNames.flatMap((colName, i) => {
|
|
997
|
+
const col = tableColumns[colName];
|
|
998
|
+
const value = set[colName] ?? sql3.param(col.onUpdateFn(), col);
|
|
999
|
+
const res = sql3`${sql3.identifier(this.casing.getColumnCasing(col))} = ${value}`;
|
|
1000
|
+
if (i < setSize - 1) {
|
|
1001
|
+
return [res, sql3.raw(", ")];
|
|
1002
|
+
}
|
|
1003
|
+
return [res];
|
|
1004
|
+
})
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
buildUpdateQuery({ table, set, where, withList }) {
|
|
1008
|
+
const withSql = this.buildWithCTE(withList);
|
|
1009
|
+
const tableName = table[DatabendTable.Symbol.Name];
|
|
1010
|
+
const tableSchema = table[DatabendTable.Symbol.Schema];
|
|
1011
|
+
const origTableName = table[DatabendTable.Symbol.OriginalName];
|
|
1012
|
+
const alias2 = tableName === origTableName ? void 0 : tableName;
|
|
1013
|
+
const tableSql = sql3`${tableSchema ? sql3`${sql3.identifier(tableSchema)}.` : void 0}${sql3.identifier(origTableName)}${alias2 && sql3` ${sql3.identifier(alias2)}`}`;
|
|
1014
|
+
const setSql = this.buildUpdateSet(table, set);
|
|
1015
|
+
const whereSql = where ? sql3` where ${where}` : void 0;
|
|
1016
|
+
return sql3`${withSql}update ${tableSql} set ${setSql}${whereSql}`;
|
|
1017
|
+
}
|
|
1018
|
+
buildSelection(fields, { isSingleTable = false } = {}) {
|
|
1019
|
+
const columnsLen = fields.length;
|
|
1020
|
+
const chunks = fields.flatMap(({ field }, i) => {
|
|
1021
|
+
const chunk = [];
|
|
1022
|
+
if (is(field, SQL.Aliased) && field.isSelectionField) {
|
|
1023
|
+
chunk.push(sql3.identifier(field.fieldAlias));
|
|
1024
|
+
} else if (is(field, SQL.Aliased) || is(field, SQL)) {
|
|
1025
|
+
const query = is(field, SQL.Aliased) ? field.sql : field;
|
|
1026
|
+
if (isSingleTable) {
|
|
1027
|
+
chunk.push(
|
|
1028
|
+
new SQL(
|
|
1029
|
+
query.queryChunks.map((c) => {
|
|
1030
|
+
if (is(c, DatabendColumn)) {
|
|
1031
|
+
return sql3.identifier(this.casing.getColumnCasing(c));
|
|
1032
|
+
}
|
|
1033
|
+
return c;
|
|
1034
|
+
})
|
|
1035
|
+
)
|
|
1036
|
+
);
|
|
1037
|
+
} else {
|
|
1038
|
+
chunk.push(query);
|
|
1039
|
+
}
|
|
1040
|
+
if (is(field, SQL.Aliased)) {
|
|
1041
|
+
chunk.push(sql3` as ${sql3.identifier(field.fieldAlias)}`);
|
|
1042
|
+
}
|
|
1043
|
+
} else if (is(field, Column2)) {
|
|
1044
|
+
if (isSingleTable) {
|
|
1045
|
+
chunk.push(sql3.identifier(this.casing.getColumnCasing(field)));
|
|
1046
|
+
} else {
|
|
1047
|
+
chunk.push(field);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
if (i < columnsLen - 1) {
|
|
1051
|
+
chunk.push(sql3`, `);
|
|
1052
|
+
}
|
|
1053
|
+
return chunk;
|
|
1054
|
+
});
|
|
1055
|
+
return sql3.join(chunks);
|
|
1056
|
+
}
|
|
1057
|
+
buildJoins(joins) {
|
|
1058
|
+
if (!joins || joins.length === 0) {
|
|
1059
|
+
return void 0;
|
|
1060
|
+
}
|
|
1061
|
+
const joinsArray = [];
|
|
1062
|
+
for (const [index2, joinMeta] of joins.entries()) {
|
|
1063
|
+
if (index2 === 0) {
|
|
1064
|
+
joinsArray.push(sql3` `);
|
|
1065
|
+
}
|
|
1066
|
+
const table = joinMeta.table;
|
|
1067
|
+
const lateralSql = joinMeta.lateral ? sql3` lateral` : void 0;
|
|
1068
|
+
if (is(table, DatabendTable)) {
|
|
1069
|
+
const t = table;
|
|
1070
|
+
const tableName = t[DatabendTable.Symbol.Name];
|
|
1071
|
+
const tableSchema = t[DatabendTable.Symbol.Schema];
|
|
1072
|
+
const origTableName = t[DatabendTable.Symbol.OriginalName];
|
|
1073
|
+
const alias2 = tableName === origTableName ? void 0 : joinMeta.alias;
|
|
1074
|
+
joinsArray.push(
|
|
1075
|
+
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${tableSchema ? sql3`${sql3.identifier(tableSchema)}.` : void 0}${sql3.identifier(origTableName)}${alias2 && sql3` ${sql3.identifier(alias2)}`} on ${joinMeta.on}`
|
|
1076
|
+
);
|
|
1077
|
+
} else if (is(table, View2)) {
|
|
1078
|
+
const viewName = table[ViewBaseConfig].name;
|
|
1079
|
+
const viewSchema = table[ViewBaseConfig].schema;
|
|
1080
|
+
const origViewName = table[ViewBaseConfig].originalName;
|
|
1081
|
+
const alias2 = viewName === origViewName ? void 0 : joinMeta.alias;
|
|
1082
|
+
joinsArray.push(
|
|
1083
|
+
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${viewSchema ? sql3`${sql3.identifier(viewSchema)}.` : void 0}${sql3.identifier(origViewName)}${alias2 && sql3` ${sql3.identifier(alias2)}`} on ${joinMeta.on}`
|
|
1084
|
+
);
|
|
1085
|
+
} else {
|
|
1086
|
+
joinsArray.push(
|
|
1087
|
+
sql3`${sql3.raw(joinMeta.joinType)} join${lateralSql} ${table} on ${joinMeta.on}`
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
if (index2 < joins.length - 1) {
|
|
1091
|
+
joinsArray.push(sql3` `);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return sql3.join(joinsArray);
|
|
1095
|
+
}
|
|
1096
|
+
buildFromTable(table) {
|
|
1097
|
+
if (is(table, Table2)) {
|
|
1098
|
+
const t = table;
|
|
1099
|
+
if (t[Table2.Symbol.OriginalName] !== t[Table2.Symbol.Name]) {
|
|
1100
|
+
let fullName = sql3`${sql3.identifier(t[Table2.Symbol.OriginalName])}`;
|
|
1101
|
+
if (t[Table2.Symbol.Schema]) {
|
|
1102
|
+
fullName = sql3`${sql3.identifier(t[Table2.Symbol.Schema])}.${fullName}`;
|
|
1103
|
+
}
|
|
1104
|
+
return sql3`${fullName} ${sql3.identifier(t[Table2.Symbol.Name])}`;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return table;
|
|
1108
|
+
}
|
|
1109
|
+
buildSelectQuery({
|
|
1110
|
+
withList,
|
|
1111
|
+
fields,
|
|
1112
|
+
fieldsFlat,
|
|
1113
|
+
where,
|
|
1114
|
+
having,
|
|
1115
|
+
table,
|
|
1116
|
+
joins,
|
|
1117
|
+
orderBy,
|
|
1118
|
+
groupBy,
|
|
1119
|
+
limit,
|
|
1120
|
+
offset,
|
|
1121
|
+
distinct,
|
|
1122
|
+
setOperators
|
|
1123
|
+
}) {
|
|
1124
|
+
const fieldsList = fieldsFlat ?? orderSelectedFields(fields);
|
|
1125
|
+
for (const f of fieldsList) {
|
|
1126
|
+
if (is(f.field, Column2) && getTableName(f.field.table) !== (is(table, Subquery) ? table._.alias : is(table, DatabendViewBase) ? table[ViewBaseConfig].name : is(table, SQL) ? void 0 : getTableName(table)) && !((table2) => joins?.some(
|
|
1127
|
+
({ alias: alias2 }) => alias2 === (table2[Table2.Symbol.IsAlias] ? getTableName(table2) : table2[Table2.Symbol.BaseName])
|
|
1128
|
+
))(f.field.table)) {
|
|
1129
|
+
const tableName = getTableName(f.field.table);
|
|
1130
|
+
throw new Error(
|
|
1131
|
+
`Your "${f.path.join("->")}" field references a column "${tableName}"."${f.field.name}", but the table "${tableName}" is not part of the query! Did you forget to join it?`
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
const isSingleTable = !joins || joins.length === 0;
|
|
1136
|
+
const withSql = this.buildWithCTE(withList);
|
|
1137
|
+
let distinctSql;
|
|
1138
|
+
if (distinct) {
|
|
1139
|
+
distinctSql = distinct === true ? sql3` distinct` : sql3` distinct on (${sql3.join(distinct.on, sql3`, `)})`;
|
|
1140
|
+
}
|
|
1141
|
+
const selection = this.buildSelection(fieldsList, { isSingleTable });
|
|
1142
|
+
const tableSql = this.buildFromTable(table);
|
|
1143
|
+
const joinsSql = this.buildJoins(joins);
|
|
1144
|
+
const whereSql = where ? sql3` where ${where}` : void 0;
|
|
1145
|
+
const havingSql = having ? sql3` having ${having}` : void 0;
|
|
1146
|
+
let orderBySql;
|
|
1147
|
+
if (orderBy && orderBy.length > 0) {
|
|
1148
|
+
orderBySql = sql3` order by ${sql3.join(orderBy, sql3`, `)}`;
|
|
1149
|
+
}
|
|
1150
|
+
let groupBySql;
|
|
1151
|
+
if (groupBy && groupBy.length > 0) {
|
|
1152
|
+
groupBySql = sql3` group by ${sql3.join(groupBy, sql3`, `)}`;
|
|
1153
|
+
}
|
|
1154
|
+
const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? sql3` limit ${limit}` : void 0;
|
|
1155
|
+
const offsetSql = offset ? sql3` offset ${offset}` : void 0;
|
|
1156
|
+
const finalQuery = sql3`${withSql}select${distinctSql} ${selection} from ${tableSql}${joinsSql}${whereSql}${groupBySql}${havingSql}${orderBySql}${limitSql}${offsetSql}`;
|
|
1157
|
+
if (setOperators.length > 0) {
|
|
1158
|
+
return this.buildSetOperations(finalQuery, setOperators);
|
|
1159
|
+
}
|
|
1160
|
+
return finalQuery;
|
|
1161
|
+
}
|
|
1162
|
+
buildSetOperations(leftSelect, setOperators) {
|
|
1163
|
+
const [setOperator, ...rest] = setOperators;
|
|
1164
|
+
if (!setOperator) {
|
|
1165
|
+
throw new Error("Cannot pass undefined values to any set operator");
|
|
1166
|
+
}
|
|
1167
|
+
if (rest.length === 0) {
|
|
1168
|
+
return this.buildSetOperationQuery({ leftSelect, setOperator });
|
|
1169
|
+
}
|
|
1170
|
+
return this.buildSetOperations(
|
|
1171
|
+
this.buildSetOperationQuery({ leftSelect, setOperator }),
|
|
1172
|
+
rest
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
buildSetOperationQuery({
|
|
1176
|
+
leftSelect,
|
|
1177
|
+
setOperator: { type, isAll, rightSelect, limit, orderBy, offset }
|
|
1178
|
+
}) {
|
|
1179
|
+
const leftChunk = sql3`(${leftSelect.getSQL()}) `;
|
|
1180
|
+
const rightChunk = sql3`(${rightSelect.getSQL()})`;
|
|
1181
|
+
let orderBySql;
|
|
1182
|
+
if (orderBy && orderBy.length > 0) {
|
|
1183
|
+
const orderByValues = [];
|
|
1184
|
+
for (const singleOrderBy of orderBy) {
|
|
1185
|
+
if (is(singleOrderBy, DatabendColumn)) {
|
|
1186
|
+
orderByValues.push(sql3.identifier(singleOrderBy.name));
|
|
1187
|
+
} else if (is(singleOrderBy, SQL)) {
|
|
1188
|
+
for (let i = 0; i < singleOrderBy.queryChunks.length; i++) {
|
|
1189
|
+
const chunk = singleOrderBy.queryChunks[i];
|
|
1190
|
+
if (is(chunk, DatabendColumn)) {
|
|
1191
|
+
singleOrderBy.queryChunks[i] = sql3.identifier(chunk.name);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
orderByValues.push(sql3`${singleOrderBy}`);
|
|
1195
|
+
} else {
|
|
1196
|
+
orderByValues.push(sql3`${singleOrderBy}`);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
orderBySql = sql3` order by ${sql3.join(orderByValues, sql3`, `)} `;
|
|
1200
|
+
}
|
|
1201
|
+
const limitSql = typeof limit === "object" || typeof limit === "number" && limit >= 0 ? sql3` limit ${limit}` : void 0;
|
|
1202
|
+
const operatorChunk = sql3.raw(`${type} ${isAll ? "all " : ""}`);
|
|
1203
|
+
const offsetSql = offset ? sql3` offset ${offset}` : void 0;
|
|
1204
|
+
return sql3`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`;
|
|
1205
|
+
}
|
|
1206
|
+
buildInsertQuery({ table, values: valuesOrSelect, withList, select }) {
|
|
1207
|
+
const valuesSqlList = [];
|
|
1208
|
+
const columns = table[Table2.Symbol.Columns];
|
|
1209
|
+
const colEntries = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert());
|
|
1210
|
+
const insertOrder = colEntries.map(
|
|
1211
|
+
([, column]) => sql3.identifier(this.casing.getColumnCasing(column))
|
|
1212
|
+
);
|
|
1213
|
+
if (select) {
|
|
1214
|
+
const select2 = valuesOrSelect;
|
|
1215
|
+
if (is(select2, SQL)) {
|
|
1216
|
+
valuesSqlList.push(select2);
|
|
1217
|
+
} else {
|
|
1218
|
+
valuesSqlList.push(select2.getSQL());
|
|
1219
|
+
}
|
|
1220
|
+
} else {
|
|
1221
|
+
const values = valuesOrSelect;
|
|
1222
|
+
valuesSqlList.push(sql3.raw("values "));
|
|
1223
|
+
for (const [valueIndex, value] of values.entries()) {
|
|
1224
|
+
const valueList = [];
|
|
1225
|
+
for (const [fieldName, col] of colEntries) {
|
|
1226
|
+
const colValue = value[fieldName];
|
|
1227
|
+
if (colValue === void 0 || is(colValue, Param) && colValue.value === void 0) {
|
|
1228
|
+
if (col.defaultFn !== void 0) {
|
|
1229
|
+
const defaultFnResult = col.defaultFn();
|
|
1230
|
+
const defaultValue = is(defaultFnResult, SQL) ? defaultFnResult : sql3.param(defaultFnResult, col);
|
|
1231
|
+
valueList.push(defaultValue);
|
|
1232
|
+
} else if (!col.default && col.onUpdateFn !== void 0) {
|
|
1233
|
+
const onUpdateFnResult = col.onUpdateFn();
|
|
1234
|
+
const newValue = is(onUpdateFnResult, SQL) ? onUpdateFnResult : sql3.param(onUpdateFnResult, col);
|
|
1235
|
+
valueList.push(newValue);
|
|
1236
|
+
} else {
|
|
1237
|
+
valueList.push(sql3`default`);
|
|
1238
|
+
}
|
|
1239
|
+
} else {
|
|
1240
|
+
valueList.push(colValue);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
valuesSqlList.push(valueList);
|
|
1244
|
+
if (valueIndex < values.length - 1) {
|
|
1245
|
+
valuesSqlList.push(sql3`, `);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
const withSql = this.buildWithCTE(withList);
|
|
1250
|
+
const valuesSql = sql3.join(valuesSqlList);
|
|
1251
|
+
return sql3`${withSql}insert into ${table} ${insertOrder} ${valuesSql}`;
|
|
1252
|
+
}
|
|
1253
|
+
prepareTyping(encoder) {
|
|
1254
|
+
if (is(encoder, DatabendDecimal) || is(encoder, DatabendColumn)) {
|
|
1255
|
+
const sqlType = encoder.getSQLType?.();
|
|
1256
|
+
if (sqlType) {
|
|
1257
|
+
const lower = sqlType.toLowerCase();
|
|
1258
|
+
if (lower === "integer" || lower === "int" || lower === "smallint" || lower === "tinyint" || lower === "bigint" || lower === "real" || lower === "double" || lower === "float" || lower.startsWith("decimal")) {
|
|
1259
|
+
return "decimal";
|
|
1260
|
+
}
|
|
1261
|
+
if (lower === "timestamp") {
|
|
1262
|
+
return "timestamp";
|
|
1263
|
+
}
|
|
1264
|
+
if (lower === "date") {
|
|
1265
|
+
return "date";
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
if (is(encoder, DatabendTimestamp)) {
|
|
1270
|
+
return "timestamp";
|
|
1271
|
+
}
|
|
1272
|
+
if (is(encoder, DatabendVariant)) {
|
|
1273
|
+
return "none";
|
|
1274
|
+
}
|
|
1275
|
+
return "none";
|
|
1276
|
+
}
|
|
1277
|
+
sqlToQuery(sql22, invokeSource) {
|
|
1278
|
+
return sql22.toQuery({
|
|
1279
|
+
casing: this.casing,
|
|
1280
|
+
escapeName: this.escapeName,
|
|
1281
|
+
escapeParam: this.escapeParam,
|
|
1282
|
+
escapeString: this.escapeString,
|
|
1283
|
+
prepareTyping: this.prepareTyping.bind(this),
|
|
1284
|
+
invokeSource
|
|
1285
|
+
});
|
|
1286
|
+
}
|
|
1287
|
+
buildRelationalQueryWithoutPK({
|
|
1288
|
+
fullSchema,
|
|
1289
|
+
schema,
|
|
1290
|
+
tableNamesMap,
|
|
1291
|
+
table,
|
|
1292
|
+
tableConfig,
|
|
1293
|
+
queryConfig: config,
|
|
1294
|
+
tableAlias,
|
|
1295
|
+
nestedQueryRelation,
|
|
1296
|
+
joinOn
|
|
1297
|
+
}) {
|
|
1298
|
+
let selection = [];
|
|
1299
|
+
let limit, offset, orderBy = [], where;
|
|
1300
|
+
const joins = [];
|
|
1301
|
+
if (config === true) {
|
|
1302
|
+
const selectionEntries = Object.entries(tableConfig.columns);
|
|
1303
|
+
selection = selectionEntries.map(([key, value]) => ({
|
|
1304
|
+
dbKey: value.name,
|
|
1305
|
+
tsKey: key,
|
|
1306
|
+
field: aliasedTableColumn(value, tableAlias),
|
|
1307
|
+
relationTableTsKey: void 0,
|
|
1308
|
+
isJson: false,
|
|
1309
|
+
selection: []
|
|
1310
|
+
}));
|
|
1311
|
+
} else {
|
|
1312
|
+
const aliasedColumns = Object.fromEntries(
|
|
1313
|
+
Object.entries(tableConfig.columns).map(([key, value]) => [key, aliasedTableColumn(value, tableAlias)])
|
|
1314
|
+
);
|
|
1315
|
+
if (config.where) {
|
|
1316
|
+
const whereSql = typeof config.where === "function" ? config.where(aliasedColumns, getOperators()) : config.where;
|
|
1317
|
+
where = whereSql && mapColumnsInSQLToAlias(whereSql, tableAlias);
|
|
1318
|
+
}
|
|
1319
|
+
const fieldsSelection = [];
|
|
1320
|
+
let selectedColumns = [];
|
|
1321
|
+
if (config.columns) {
|
|
1322
|
+
let isIncludeMode = false;
|
|
1323
|
+
for (const [field, value] of Object.entries(config.columns)) {
|
|
1324
|
+
if (value === void 0) continue;
|
|
1325
|
+
if (field in tableConfig.columns) {
|
|
1326
|
+
if (!isIncludeMode && value === true) {
|
|
1327
|
+
isIncludeMode = true;
|
|
1328
|
+
}
|
|
1329
|
+
selectedColumns.push(field);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
if (selectedColumns.length > 0) {
|
|
1333
|
+
selectedColumns = isIncludeMode ? selectedColumns.filter((c) => config.columns?.[c] === true) : Object.keys(tableConfig.columns).filter((key) => !selectedColumns.includes(key));
|
|
1334
|
+
}
|
|
1335
|
+
} else {
|
|
1336
|
+
selectedColumns = Object.keys(tableConfig.columns);
|
|
1337
|
+
}
|
|
1338
|
+
for (const field of selectedColumns) {
|
|
1339
|
+
const column = tableConfig.columns[field];
|
|
1340
|
+
fieldsSelection.push({ tsKey: field, value: column });
|
|
1341
|
+
}
|
|
1342
|
+
let selectedRelations = [];
|
|
1343
|
+
if (config.with) {
|
|
1344
|
+
selectedRelations = Object.entries(config.with).filter((entry) => !!entry[1]).map(([tsKey, queryConfig]) => ({
|
|
1345
|
+
tsKey,
|
|
1346
|
+
queryConfig,
|
|
1347
|
+
relation: tableConfig.relations[tsKey]
|
|
1348
|
+
}));
|
|
1349
|
+
}
|
|
1350
|
+
if (config.extras) {
|
|
1351
|
+
const extras = typeof config.extras === "function" ? config.extras(aliasedColumns, { sql: sql3 }) : config.extras;
|
|
1352
|
+
for (const [tsKey, value] of Object.entries(extras)) {
|
|
1353
|
+
fieldsSelection.push({
|
|
1354
|
+
tsKey,
|
|
1355
|
+
value: mapColumnsInAliasedSQLToAlias(value, tableAlias)
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
for (const { tsKey, value } of fieldsSelection) {
|
|
1360
|
+
selection.push({
|
|
1361
|
+
dbKey: is(value, SQL.Aliased) ? value.fieldAlias : tableConfig.columns[tsKey].name,
|
|
1362
|
+
tsKey,
|
|
1363
|
+
field: is(value, Column2) ? aliasedTableColumn(value, tableAlias) : value,
|
|
1364
|
+
relationTableTsKey: void 0,
|
|
1365
|
+
isJson: false,
|
|
1366
|
+
selection: []
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
let orderByOrig = typeof config.orderBy === "function" ? config.orderBy(aliasedColumns, getOrderByOperators()) : config.orderBy ?? [];
|
|
1370
|
+
if (!Array.isArray(orderByOrig)) {
|
|
1371
|
+
orderByOrig = [orderByOrig];
|
|
1372
|
+
}
|
|
1373
|
+
orderBy = orderByOrig.map((orderByValue) => {
|
|
1374
|
+
if (is(orderByValue, Column2)) {
|
|
1375
|
+
return aliasedTableColumn(orderByValue, tableAlias);
|
|
1376
|
+
}
|
|
1377
|
+
return mapColumnsInSQLToAlias(orderByValue, tableAlias);
|
|
1378
|
+
});
|
|
1379
|
+
limit = config.limit;
|
|
1380
|
+
offset = config.offset;
|
|
1381
|
+
for (const {
|
|
1382
|
+
tsKey: selectedRelationTsKey,
|
|
1383
|
+
queryConfig: selectedRelationConfigValue,
|
|
1384
|
+
relation
|
|
1385
|
+
} of selectedRelations) {
|
|
1386
|
+
const normalizedRelation = normalizeRelation(schema, tableNamesMap, relation);
|
|
1387
|
+
const relationTableName = getTableUniqueName(relation.referencedTable);
|
|
1388
|
+
const relationTableTsName = tableNamesMap[relationTableName];
|
|
1389
|
+
const relationTableAlias = `${tableAlias}_${selectedRelationTsKey}`;
|
|
1390
|
+
const joinOn2 = and(
|
|
1391
|
+
...normalizedRelation.fields.map(
|
|
1392
|
+
(field2, i) => eq(
|
|
1393
|
+
aliasedTableColumn(normalizedRelation.references[i], relationTableAlias),
|
|
1394
|
+
aliasedTableColumn(field2, tableAlias)
|
|
1395
|
+
)
|
|
1396
|
+
)
|
|
1397
|
+
);
|
|
1398
|
+
const builtRelation = this.buildRelationalQueryWithoutPK({
|
|
1399
|
+
fullSchema,
|
|
1400
|
+
schema,
|
|
1401
|
+
tableNamesMap,
|
|
1402
|
+
table: fullSchema[relationTableTsName],
|
|
1403
|
+
tableConfig: schema[relationTableTsName],
|
|
1404
|
+
queryConfig: is(relation, One) ? selectedRelationConfigValue === true ? { limit: 1 } : { ...selectedRelationConfigValue, limit: 1 } : selectedRelationConfigValue,
|
|
1405
|
+
tableAlias: relationTableAlias,
|
|
1406
|
+
joinOn: joinOn2,
|
|
1407
|
+
nestedQueryRelation: relation
|
|
1408
|
+
});
|
|
1409
|
+
const field = sql3`${sql3.identifier(relationTableAlias)}.${sql3.identifier("data")}`.as(selectedRelationTsKey);
|
|
1410
|
+
joins.push({
|
|
1411
|
+
on: sql3`true`,
|
|
1412
|
+
table: new Subquery(builtRelation.sql, {}, relationTableAlias),
|
|
1413
|
+
alias: relationTableAlias,
|
|
1414
|
+
joinType: "left",
|
|
1415
|
+
lateral: true
|
|
1416
|
+
});
|
|
1417
|
+
selection.push({
|
|
1418
|
+
dbKey: selectedRelationTsKey,
|
|
1419
|
+
tsKey: selectedRelationTsKey,
|
|
1420
|
+
field,
|
|
1421
|
+
relationTableTsKey: relationTableTsName,
|
|
1422
|
+
isJson: true,
|
|
1423
|
+
selection: builtRelation.selection
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
if (selection.length === 0) {
|
|
1428
|
+
throw new DrizzleError({ message: `No fields selected for table "${tableConfig.tsName}" ("${tableAlias}")` });
|
|
1429
|
+
}
|
|
1430
|
+
let result;
|
|
1431
|
+
where = and(joinOn, where);
|
|
1432
|
+
if (nestedQueryRelation) {
|
|
1433
|
+
let field = sql3`json_build_array(${sql3.join(
|
|
1434
|
+
selection.map(
|
|
1435
|
+
({ field: field2, tsKey, isJson }) => isJson ? sql3`${sql3.identifier(`${tableAlias}_${tsKey}`)}.${sql3.identifier("data")}` : is(field2, SQL.Aliased) ? field2.sql : field2
|
|
1436
|
+
),
|
|
1437
|
+
sql3`, `
|
|
1438
|
+
)})`;
|
|
1439
|
+
if (is(nestedQueryRelation, Many)) {
|
|
1440
|
+
field = sql3`coalesce(json_agg(${field}${orderBy.length > 0 ? sql3` order by ${sql3.join(orderBy, sql3`, `)}` : void 0}), '[]'::json)`;
|
|
1441
|
+
}
|
|
1442
|
+
const nestedSelection = [{
|
|
1443
|
+
dbKey: "data",
|
|
1444
|
+
tsKey: "data",
|
|
1445
|
+
field: field.as("data"),
|
|
1446
|
+
isJson: true,
|
|
1447
|
+
relationTableTsKey: tableConfig.tsName,
|
|
1448
|
+
selection
|
|
1449
|
+
}];
|
|
1450
|
+
const needsSubquery = limit !== void 0 || offset !== void 0 || orderBy.length > 0;
|
|
1451
|
+
if (needsSubquery) {
|
|
1452
|
+
result = this.buildSelectQuery({
|
|
1453
|
+
table: aliasedTable(table, tableAlias),
|
|
1454
|
+
fields: {},
|
|
1455
|
+
fieldsFlat: [{ path: [], field: sql3.raw("*") }],
|
|
1456
|
+
where,
|
|
1457
|
+
limit,
|
|
1458
|
+
offset,
|
|
1459
|
+
orderBy,
|
|
1460
|
+
setOperators: []
|
|
1461
|
+
});
|
|
1462
|
+
where = void 0;
|
|
1463
|
+
limit = void 0;
|
|
1464
|
+
offset = void 0;
|
|
1465
|
+
orderBy = [];
|
|
1466
|
+
} else {
|
|
1467
|
+
result = aliasedTable(table, tableAlias);
|
|
1468
|
+
}
|
|
1469
|
+
result = this.buildSelectQuery({
|
|
1470
|
+
table: is(result, DatabendTable) ? result : new Subquery(result, {}, tableAlias),
|
|
1471
|
+
fields: {},
|
|
1472
|
+
fieldsFlat: nestedSelection.map(({ field: field2 }) => ({
|
|
1473
|
+
path: [],
|
|
1474
|
+
field: is(field2, Column2) ? aliasedTableColumn(field2, tableAlias) : field2
|
|
1475
|
+
})),
|
|
1476
|
+
joins,
|
|
1477
|
+
where,
|
|
1478
|
+
limit,
|
|
1479
|
+
offset,
|
|
1480
|
+
orderBy,
|
|
1481
|
+
setOperators: []
|
|
1482
|
+
});
|
|
1483
|
+
} else {
|
|
1484
|
+
result = this.buildSelectQuery({
|
|
1485
|
+
table: aliasedTable(table, tableAlias),
|
|
1486
|
+
fields: {},
|
|
1487
|
+
fieldsFlat: selection.map(({ field }) => ({
|
|
1488
|
+
path: [],
|
|
1489
|
+
field: is(field, Column2) ? aliasedTableColumn(field, tableAlias) : field
|
|
1490
|
+
})),
|
|
1491
|
+
joins,
|
|
1492
|
+
where,
|
|
1493
|
+
limit,
|
|
1494
|
+
offset,
|
|
1495
|
+
orderBy,
|
|
1496
|
+
setOperators: []
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
return {
|
|
1500
|
+
tableTsKey: tableConfig.tsName,
|
|
1501
|
+
sql: result,
|
|
1502
|
+
selection
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
};
|
|
1506
|
+
|
|
1507
|
+
// src/databend-core/indexes.ts
|
|
1508
|
+
import { entityKind as entityKind21, is as is2 } from "drizzle-orm/entity";
|
|
1509
|
+
import { SQL as SQL2 } from "drizzle-orm/sql/sql";
|
|
1510
|
+
var IndexBuilderOn = class {
|
|
1511
|
+
constructor(unique, name) {
|
|
1512
|
+
this.unique = unique;
|
|
1513
|
+
this.name = name;
|
|
1514
|
+
}
|
|
1515
|
+
static [entityKind21] = "DatabendIndexBuilderOn";
|
|
1516
|
+
on(...columns) {
|
|
1517
|
+
return new IndexBuilder(
|
|
1518
|
+
columns.map((it) => {
|
|
1519
|
+
if (is2(it, SQL2)) {
|
|
1520
|
+
return it;
|
|
1521
|
+
}
|
|
1522
|
+
const clonedIndexedColumn = new IndexedColumn(it.name, !!it.keyAsName, it.columnType, it.indexConfig);
|
|
1523
|
+
it.indexConfig = JSON.parse(JSON.stringify(it.defaultConfig));
|
|
1524
|
+
return clonedIndexedColumn;
|
|
1525
|
+
}),
|
|
1526
|
+
this.unique,
|
|
1527
|
+
this.name
|
|
1528
|
+
);
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
var IndexBuilder = class {
|
|
1532
|
+
static [entityKind21] = "DatabendIndexBuilder";
|
|
1533
|
+
/** @internal */
|
|
1534
|
+
config;
|
|
1535
|
+
constructor(columns, unique, name) {
|
|
1536
|
+
this.config = {
|
|
1537
|
+
name,
|
|
1538
|
+
columns,
|
|
1539
|
+
unique
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
where(condition) {
|
|
1543
|
+
this.config.where = condition;
|
|
1544
|
+
return this;
|
|
1545
|
+
}
|
|
1546
|
+
/** @internal */
|
|
1547
|
+
build(table) {
|
|
1548
|
+
return new Index(this.config, table);
|
|
1549
|
+
}
|
|
1550
|
+
};
|
|
1551
|
+
var Index = class {
|
|
1552
|
+
static [entityKind21] = "DatabendIndex";
|
|
1553
|
+
config;
|
|
1554
|
+
constructor(config, table) {
|
|
1555
|
+
this.config = { ...config, table };
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1558
|
+
function index(name) {
|
|
1559
|
+
return new IndexBuilderOn(false, name);
|
|
1560
|
+
}
|
|
1561
|
+
function uniqueIndex(name) {
|
|
1562
|
+
return new IndexBuilderOn(true, name);
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
// src/databend-core/primary-keys.ts
|
|
1566
|
+
import { entityKind as entityKind22 } from "drizzle-orm/entity";
|
|
1567
|
+
function primaryKey(...config) {
|
|
1568
|
+
if (config[0].columns) {
|
|
1569
|
+
return new PrimaryKeyBuilder(config[0].columns, config[0].name);
|
|
1570
|
+
}
|
|
1571
|
+
return new PrimaryKeyBuilder(config);
|
|
1572
|
+
}
|
|
1573
|
+
var PrimaryKeyBuilder = class {
|
|
1574
|
+
static [entityKind22] = "DatabendPrimaryKeyBuilder";
|
|
1575
|
+
/** @internal */
|
|
1576
|
+
columns;
|
|
1577
|
+
/** @internal */
|
|
1578
|
+
name;
|
|
1579
|
+
constructor(columns, name) {
|
|
1580
|
+
this.columns = columns;
|
|
1581
|
+
this.name = name;
|
|
1582
|
+
}
|
|
1583
|
+
/** @internal */
|
|
1584
|
+
build(table) {
|
|
1585
|
+
return new PrimaryKey(table, this.columns, this.name);
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
var PrimaryKey = class {
|
|
1589
|
+
constructor(table, columns, name) {
|
|
1590
|
+
this.table = table;
|
|
1591
|
+
this.columns = columns;
|
|
1592
|
+
this.name = name;
|
|
1593
|
+
}
|
|
1594
|
+
static [entityKind22] = "DatabendPrimaryKey";
|
|
1595
|
+
columns;
|
|
1596
|
+
name;
|
|
1597
|
+
getName() {
|
|
1598
|
+
return this.name ?? `${this.table[DatabendTable.Symbol.Name]}_${this.columns.map((column) => column.name).join("_")}_pk`;
|
|
1599
|
+
}
|
|
1600
|
+
};
|
|
1601
|
+
|
|
1602
|
+
// src/databend-core/schema.ts
|
|
1603
|
+
import { entityKind as entityKind23, is as is3 } from "drizzle-orm/entity";
|
|
1604
|
+
import { SQL as SQL3, sql as sql4 } from "drizzle-orm/sql/sql";
|
|
1605
|
+
var DatabendSchema = class {
|
|
1606
|
+
constructor(schemaName) {
|
|
1607
|
+
this.schemaName = schemaName;
|
|
1608
|
+
}
|
|
1609
|
+
static [entityKind23] = "DatabendSchema";
|
|
1610
|
+
table = (name, columns, extraConfig) => {
|
|
1611
|
+
return databendTableWithSchema(name, columns, extraConfig, this.schemaName);
|
|
1612
|
+
};
|
|
1613
|
+
getSQL() {
|
|
1614
|
+
return new SQL3([sql4.identifier(this.schemaName)]);
|
|
1615
|
+
}
|
|
1616
|
+
shouldOmitSQLParens() {
|
|
1617
|
+
return true;
|
|
1618
|
+
}
|
|
1619
|
+
};
|
|
1620
|
+
function databendSchema(name) {
|
|
1621
|
+
return new DatabendSchema(name);
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
// src/databend-core/utils.ts
|
|
1625
|
+
import { is as is4 } from "drizzle-orm/entity";
|
|
1626
|
+
import { Table as Table3 } from "drizzle-orm/table";
|
|
1627
|
+
function getTableConfig(table) {
|
|
1628
|
+
const columns = Object.values(table[Table3.Symbol.Columns]);
|
|
1629
|
+
const indexes = [];
|
|
1630
|
+
const primaryKeys = [];
|
|
1631
|
+
const name = table[Table3.Symbol.Name];
|
|
1632
|
+
const schema = table[Table3.Symbol.Schema];
|
|
1633
|
+
const extraConfigBuilder = table[DatabendTable.Symbol.ExtraConfigBuilder];
|
|
1634
|
+
if (extraConfigBuilder !== void 0) {
|
|
1635
|
+
const extraConfig = extraConfigBuilder(table[Table3.Symbol.ExtraConfigColumns]);
|
|
1636
|
+
const extraValues = Array.isArray(extraConfig) ? extraConfig.flat(1) : Object.values(extraConfig);
|
|
1637
|
+
for (const builder of extraValues) {
|
|
1638
|
+
if (is4(builder, IndexBuilder)) {
|
|
1639
|
+
indexes.push(builder.build(table));
|
|
1640
|
+
} else if (is4(builder, PrimaryKeyBuilder)) {
|
|
1641
|
+
primaryKeys.push(builder.build(table));
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
return {
|
|
1646
|
+
columns,
|
|
1647
|
+
indexes,
|
|
1648
|
+
primaryKeys,
|
|
1649
|
+
name,
|
|
1650
|
+
schema
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
// src/databend-core/view.ts
|
|
1655
|
+
import { entityKind as entityKind26, is as is7 } from "drizzle-orm/entity";
|
|
1656
|
+
import { SelectionProxyHandler as SelectionProxyHandler3 } from "drizzle-orm/selection-proxy";
|
|
1657
|
+
import { getTableColumns as getTableColumns2 } from "drizzle-orm/utils";
|
|
1658
|
+
|
|
1659
|
+
// src/databend-core/query-builders/query-builder.ts
|
|
1660
|
+
import { entityKind as entityKind25, is as is6 } from "drizzle-orm/entity";
|
|
1661
|
+
import { SelectionProxyHandler as SelectionProxyHandler2 } from "drizzle-orm/selection-proxy";
|
|
1662
|
+
import { WithSubquery } from "drizzle-orm/subquery";
|
|
1663
|
+
|
|
1664
|
+
// src/databend-core/query-builders/select.ts
|
|
1665
|
+
import { entityKind as entityKind24, is as is5 } from "drizzle-orm/entity";
|
|
1666
|
+
import { TypedQueryBuilder } from "drizzle-orm/query-builders/query-builder";
|
|
1667
|
+
import { QueryPromise } from "drizzle-orm/query-promise";
|
|
1668
|
+
import { SelectionProxyHandler } from "drizzle-orm/selection-proxy";
|
|
1669
|
+
import { SQL as SQL4, View as View3 } from "drizzle-orm/sql/sql";
|
|
1670
|
+
import { Subquery as Subquery2 } from "drizzle-orm/subquery";
|
|
1671
|
+
import { Table as Table4 } from "drizzle-orm/table";
|
|
1672
|
+
import { tracer } from "drizzle-orm/tracing";
|
|
1673
|
+
import {
|
|
1674
|
+
applyMixins,
|
|
1675
|
+
getTableColumns,
|
|
1676
|
+
getTableLikeName,
|
|
1677
|
+
haveSameKeys,
|
|
1678
|
+
orderSelectedFields as orderSelectedFields2
|
|
1679
|
+
} from "drizzle-orm/utils";
|
|
1680
|
+
import { ViewBaseConfig as ViewBaseConfig2 } from "drizzle-orm/view-common";
|
|
1681
|
+
var DatabendSelectBuilder = class {
|
|
1682
|
+
static [entityKind24] = "DatabendSelectBuilder";
|
|
1683
|
+
fields;
|
|
1684
|
+
session;
|
|
1685
|
+
dialect;
|
|
1686
|
+
withList = [];
|
|
1687
|
+
distinct;
|
|
1688
|
+
constructor(config) {
|
|
1689
|
+
this.fields = config.fields;
|
|
1690
|
+
this.session = config.session;
|
|
1691
|
+
this.dialect = config.dialect;
|
|
1692
|
+
if (config.withList) {
|
|
1693
|
+
this.withList = config.withList;
|
|
1694
|
+
}
|
|
1695
|
+
this.distinct = config.distinct;
|
|
1696
|
+
}
|
|
1697
|
+
from(source) {
|
|
1698
|
+
const isPartialSelect = !!this.fields;
|
|
1699
|
+
let fields;
|
|
1700
|
+
if (this.fields) {
|
|
1701
|
+
fields = this.fields;
|
|
1702
|
+
} else if (is5(source, Subquery2)) {
|
|
1703
|
+
fields = Object.fromEntries(
|
|
1704
|
+
Object.keys(source._.selectedFields).map((key) => [key, source[key]])
|
|
1705
|
+
);
|
|
1706
|
+
} else if (is5(source, DatabendViewBase)) {
|
|
1707
|
+
fields = source[ViewBaseConfig2].selectedFields;
|
|
1708
|
+
} else if (is5(source, SQL4)) {
|
|
1709
|
+
fields = {};
|
|
1710
|
+
} else {
|
|
1711
|
+
fields = getTableColumns(source);
|
|
1712
|
+
}
|
|
1713
|
+
return new DatabendSelectBase({
|
|
1714
|
+
table: source,
|
|
1715
|
+
fields,
|
|
1716
|
+
isPartialSelect,
|
|
1717
|
+
session: this.session,
|
|
1718
|
+
dialect: this.dialect,
|
|
1719
|
+
withList: this.withList,
|
|
1720
|
+
distinct: this.distinct
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
};
|
|
1724
|
+
var DatabendSelectQueryBuilderBase = class extends TypedQueryBuilder {
|
|
1725
|
+
static [entityKind24] = "DatabendSelectQueryBuilder";
|
|
1726
|
+
_;
|
|
1727
|
+
config;
|
|
1728
|
+
joinsNotNullableMap;
|
|
1729
|
+
tableName;
|
|
1730
|
+
isPartialSelect;
|
|
1731
|
+
session;
|
|
1732
|
+
dialect;
|
|
1733
|
+
constructor({ table, fields, isPartialSelect, session, dialect, withList, distinct }) {
|
|
1734
|
+
super();
|
|
1735
|
+
this.config = {
|
|
1736
|
+
withList,
|
|
1737
|
+
table,
|
|
1738
|
+
fields: { ...fields },
|
|
1739
|
+
distinct,
|
|
1740
|
+
setOperators: []
|
|
1741
|
+
};
|
|
1742
|
+
this.isPartialSelect = isPartialSelect;
|
|
1743
|
+
this.session = session;
|
|
1744
|
+
this.dialect = dialect;
|
|
1745
|
+
this._ = {
|
|
1746
|
+
selectedFields: fields
|
|
1747
|
+
};
|
|
1748
|
+
this.tableName = getTableLikeName(table);
|
|
1749
|
+
this.joinsNotNullableMap = typeof this.tableName === "string" ? { [this.tableName]: true } : {};
|
|
1750
|
+
}
|
|
1751
|
+
createJoin(joinType) {
|
|
1752
|
+
return (table, on) => {
|
|
1753
|
+
const baseTableName = this.tableName;
|
|
1754
|
+
const tableName = getTableLikeName(table);
|
|
1755
|
+
if (typeof tableName === "string" && this.config.joins?.some((join) => join.alias === tableName)) {
|
|
1756
|
+
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
1757
|
+
}
|
|
1758
|
+
if (!this.isPartialSelect) {
|
|
1759
|
+
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") {
|
|
1760
|
+
this.config.fields = {
|
|
1761
|
+
[baseTableName]: this.config.fields
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
if (typeof tableName === "string" && !is5(table, SQL4)) {
|
|
1765
|
+
const selection = is5(table, Subquery2) ? table._.selectedFields : is5(table, View3) ? table[ViewBaseConfig2].selectedFields : table[Table4.Symbol.Columns];
|
|
1766
|
+
this.config.fields[tableName] = selection;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
if (typeof on === "function") {
|
|
1770
|
+
on = on(
|
|
1771
|
+
new Proxy(
|
|
1772
|
+
this.config.fields,
|
|
1773
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
|
|
1774
|
+
)
|
|
1775
|
+
);
|
|
1776
|
+
}
|
|
1777
|
+
if (!this.config.joins) {
|
|
1778
|
+
this.config.joins = [];
|
|
1779
|
+
}
|
|
1780
|
+
this.config.joins.push({ on, table, joinType, alias: tableName });
|
|
1781
|
+
if (typeof tableName === "string") {
|
|
1782
|
+
switch (joinType) {
|
|
1783
|
+
case "left":
|
|
1784
|
+
this.joinsNotNullableMap[tableName] = false;
|
|
1785
|
+
break;
|
|
1786
|
+
case "right":
|
|
1787
|
+
this.joinsNotNullableMap = Object.fromEntries(
|
|
1788
|
+
Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
|
|
1789
|
+
);
|
|
1790
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
1791
|
+
break;
|
|
1792
|
+
case "inner":
|
|
1793
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
1794
|
+
break;
|
|
1795
|
+
case "full":
|
|
1796
|
+
this.joinsNotNullableMap = Object.fromEntries(
|
|
1797
|
+
Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
|
|
1798
|
+
);
|
|
1799
|
+
this.joinsNotNullableMap[tableName] = false;
|
|
1800
|
+
break;
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
return this;
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
leftJoin = this.createJoin("left");
|
|
1807
|
+
rightJoin = this.createJoin("right");
|
|
1808
|
+
innerJoin = this.createJoin("inner");
|
|
1809
|
+
fullJoin = this.createJoin("full");
|
|
1810
|
+
createSetOperator(type, isAll) {
|
|
1811
|
+
return (rightSelection) => {
|
|
1812
|
+
const rightSelect = typeof rightSelection === "function" ? rightSelection(getDatabendSetOperators()) : rightSelection;
|
|
1813
|
+
if (!haveSameKeys(this.getSelectedFields(), rightSelect.getSelectedFields())) {
|
|
1814
|
+
throw new Error(
|
|
1815
|
+
"Set operator error (union / intersect / except): selected fields are not the same or are in a different order"
|
|
1816
|
+
);
|
|
1817
|
+
}
|
|
1818
|
+
this.config.setOperators.push({ type, isAll, rightSelect });
|
|
1819
|
+
return this;
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
union = this.createSetOperator("union", false);
|
|
1823
|
+
unionAll = this.createSetOperator("union", true);
|
|
1824
|
+
intersect = this.createSetOperator("intersect", false);
|
|
1825
|
+
intersectAll = this.createSetOperator("intersect", true);
|
|
1826
|
+
except = this.createSetOperator("except", false);
|
|
1827
|
+
exceptAll = this.createSetOperator("except", true);
|
|
1828
|
+
/** @internal */
|
|
1829
|
+
addSetOperators(setOperators) {
|
|
1830
|
+
this.config.setOperators.push(...setOperators);
|
|
1831
|
+
return this;
|
|
1832
|
+
}
|
|
1833
|
+
where(where) {
|
|
1834
|
+
if (typeof where === "function") {
|
|
1835
|
+
where = where(
|
|
1836
|
+
new Proxy(
|
|
1837
|
+
this.config.fields,
|
|
1838
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
|
|
1839
|
+
)
|
|
1840
|
+
);
|
|
1841
|
+
}
|
|
1842
|
+
this.config.where = where;
|
|
1843
|
+
return this;
|
|
1844
|
+
}
|
|
1845
|
+
having(having) {
|
|
1846
|
+
if (typeof having === "function") {
|
|
1847
|
+
having = having(
|
|
1848
|
+
new Proxy(
|
|
1849
|
+
this.config.fields,
|
|
1850
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: "sql", sqlBehavior: "sql" })
|
|
1851
|
+
)
|
|
1852
|
+
);
|
|
1853
|
+
}
|
|
1854
|
+
this.config.having = having;
|
|
1855
|
+
return this;
|
|
1856
|
+
}
|
|
1857
|
+
groupBy(...columns) {
|
|
1858
|
+
if (typeof columns[0] === "function") {
|
|
1859
|
+
const groupBy = columns[0](
|
|
1860
|
+
new Proxy(
|
|
1861
|
+
this.config.fields,
|
|
1862
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" })
|
|
1863
|
+
)
|
|
1864
|
+
);
|
|
1865
|
+
this.config.groupBy = Array.isArray(groupBy) ? groupBy : [groupBy];
|
|
1866
|
+
} else {
|
|
1867
|
+
this.config.groupBy = columns;
|
|
1868
|
+
}
|
|
1869
|
+
return this;
|
|
1870
|
+
}
|
|
1871
|
+
orderBy(...columns) {
|
|
1872
|
+
if (typeof columns[0] === "function") {
|
|
1873
|
+
const orderBy = columns[0](
|
|
1874
|
+
new Proxy(
|
|
1875
|
+
this.config.fields,
|
|
1876
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: "alias", sqlBehavior: "sql" })
|
|
1877
|
+
)
|
|
1878
|
+
);
|
|
1879
|
+
const orderByArray = Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
1880
|
+
if (this.config.setOperators.length > 0) {
|
|
1881
|
+
this.config.setOperators.at(-1).orderBy = orderByArray;
|
|
1882
|
+
} else {
|
|
1883
|
+
this.config.orderBy = orderByArray;
|
|
1884
|
+
}
|
|
1885
|
+
} else {
|
|
1886
|
+
const orderByArray = columns;
|
|
1887
|
+
if (this.config.setOperators.length > 0) {
|
|
1888
|
+
this.config.setOperators.at(-1).orderBy = orderByArray;
|
|
1889
|
+
} else {
|
|
1890
|
+
this.config.orderBy = orderByArray;
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
return this;
|
|
1894
|
+
}
|
|
1895
|
+
limit(limit) {
|
|
1896
|
+
if (this.config.setOperators.length > 0) {
|
|
1897
|
+
this.config.setOperators.at(-1).limit = limit;
|
|
1898
|
+
} else {
|
|
1899
|
+
this.config.limit = limit;
|
|
1900
|
+
}
|
|
1901
|
+
return this;
|
|
1902
|
+
}
|
|
1903
|
+
offset(offset) {
|
|
1904
|
+
if (this.config.setOperators.length > 0) {
|
|
1905
|
+
this.config.setOperators.at(-1).offset = offset;
|
|
1906
|
+
} else {
|
|
1907
|
+
this.config.offset = offset;
|
|
1908
|
+
}
|
|
1909
|
+
return this;
|
|
1910
|
+
}
|
|
1911
|
+
/** @internal */
|
|
1912
|
+
getSQL() {
|
|
1913
|
+
return this.dialect.buildSelectQuery(this.config);
|
|
1914
|
+
}
|
|
1915
|
+
toSQL() {
|
|
1916
|
+
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
|
|
1917
|
+
return rest;
|
|
1918
|
+
}
|
|
1919
|
+
as(alias2) {
|
|
1920
|
+
return new Proxy(
|
|
1921
|
+
new Subquery2(this.getSQL(), this.config.fields, alias2),
|
|
1922
|
+
new SelectionProxyHandler({ alias: alias2, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
/** @internal */
|
|
1926
|
+
getSelectedFields() {
|
|
1927
|
+
return new Proxy(
|
|
1928
|
+
this.config.fields,
|
|
1929
|
+
new SelectionProxyHandler({ alias: this.tableName, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1932
|
+
$dynamic() {
|
|
1933
|
+
return this;
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
var DatabendSelectBase = class extends DatabendSelectQueryBuilderBase {
|
|
1937
|
+
static [entityKind24] = "DatabendSelect";
|
|
1938
|
+
/** @internal */
|
|
1939
|
+
_prepare(name) {
|
|
1940
|
+
const { session, config, dialect, joinsNotNullableMap } = this;
|
|
1941
|
+
if (!session) {
|
|
1942
|
+
throw new Error("Cannot execute a query on a query builder. Please use a database instance instead.");
|
|
1943
|
+
}
|
|
1944
|
+
return tracer.startActiveSpan("drizzle.prepareQuery", () => {
|
|
1945
|
+
const fieldsList = orderSelectedFields2(config.fields);
|
|
1946
|
+
const query = session.prepareQuery(dialect.sqlToQuery(this.getSQL()), fieldsList, name, true);
|
|
1947
|
+
query.joinsNotNullableMap = joinsNotNullableMap;
|
|
1948
|
+
return query;
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
prepare(name) {
|
|
1952
|
+
return this._prepare(name);
|
|
1953
|
+
}
|
|
1954
|
+
execute = (placeholderValues) => {
|
|
1955
|
+
return tracer.startActiveSpan("drizzle.operation", () => {
|
|
1956
|
+
return this._prepare().execute(placeholderValues);
|
|
1957
|
+
});
|
|
1958
|
+
};
|
|
1959
|
+
};
|
|
1960
|
+
applyMixins(DatabendSelectBase, [QueryPromise]);
|
|
1961
|
+
function createSetOperator(type, isAll) {
|
|
1962
|
+
return (leftSelect, rightSelect, ...restSelects) => {
|
|
1963
|
+
const setOperators = [rightSelect, ...restSelects].map((select) => ({
|
|
1964
|
+
type,
|
|
1965
|
+
isAll,
|
|
1966
|
+
rightSelect: select
|
|
1967
|
+
}));
|
|
1968
|
+
for (const setOperator of setOperators) {
|
|
1969
|
+
if (!haveSameKeys(leftSelect.getSelectedFields(), setOperator.rightSelect.getSelectedFields())) {
|
|
1970
|
+
throw new Error(
|
|
1971
|
+
"Set operator error (union / intersect / except): selected fields are not the same or are in a different order"
|
|
1972
|
+
);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
return leftSelect.addSetOperators(setOperators);
|
|
1976
|
+
};
|
|
1977
|
+
}
|
|
1978
|
+
var getDatabendSetOperators = () => ({
|
|
1979
|
+
union,
|
|
1980
|
+
unionAll,
|
|
1981
|
+
intersect,
|
|
1982
|
+
intersectAll,
|
|
1983
|
+
except,
|
|
1984
|
+
exceptAll
|
|
1985
|
+
});
|
|
1986
|
+
var union = createSetOperator("union", false);
|
|
1987
|
+
var unionAll = createSetOperator("union", true);
|
|
1988
|
+
var intersect = createSetOperator("intersect", false);
|
|
1989
|
+
var intersectAll = createSetOperator("intersect", true);
|
|
1990
|
+
var except = createSetOperator("except", false);
|
|
1991
|
+
var exceptAll = createSetOperator("except", true);
|
|
1992
|
+
|
|
1993
|
+
// src/databend-core/query-builders/query-builder.ts
|
|
1994
|
+
var QueryBuilder = class {
|
|
1995
|
+
static [entityKind25] = "DatabendQueryBuilder";
|
|
1996
|
+
dialect;
|
|
1997
|
+
dialectConfig;
|
|
1998
|
+
constructor(dialect) {
|
|
1999
|
+
this.dialect = is6(dialect, DatabendDialect) ? dialect : void 0;
|
|
2000
|
+
this.dialectConfig = is6(dialect, DatabendDialect) ? void 0 : dialect;
|
|
2001
|
+
}
|
|
2002
|
+
$with(alias2) {
|
|
2003
|
+
const queryBuilder = this;
|
|
2004
|
+
return {
|
|
2005
|
+
as(qb) {
|
|
2006
|
+
if (typeof qb === "function") {
|
|
2007
|
+
qb = qb(queryBuilder);
|
|
2008
|
+
}
|
|
2009
|
+
return new Proxy(
|
|
2010
|
+
new WithSubquery(qb.getSQL(), qb.getSelectedFields(), alias2, true),
|
|
2011
|
+
new SelectionProxyHandler2({ alias: alias2, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
|
|
2012
|
+
);
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
with(...queries) {
|
|
2017
|
+
const self = this;
|
|
2018
|
+
function select(fields) {
|
|
2019
|
+
return new DatabendSelectBuilder({
|
|
2020
|
+
fields: fields ?? void 0,
|
|
2021
|
+
session: void 0,
|
|
2022
|
+
dialect: self.getDialect(),
|
|
2023
|
+
withList: queries
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
function selectDistinct(fields) {
|
|
2027
|
+
return new DatabendSelectBuilder({
|
|
2028
|
+
fields: fields ?? void 0,
|
|
2029
|
+
session: void 0,
|
|
2030
|
+
dialect: self.getDialect(),
|
|
2031
|
+
distinct: true
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
return { select, selectDistinct };
|
|
2035
|
+
}
|
|
2036
|
+
select(fields) {
|
|
2037
|
+
return new DatabendSelectBuilder({
|
|
2038
|
+
fields: fields ?? void 0,
|
|
2039
|
+
session: void 0,
|
|
2040
|
+
dialect: this.getDialect()
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
selectDistinct(fields) {
|
|
2044
|
+
return new DatabendSelectBuilder({
|
|
2045
|
+
fields: fields ?? void 0,
|
|
2046
|
+
session: void 0,
|
|
2047
|
+
dialect: this.getDialect(),
|
|
2048
|
+
distinct: true
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
getDialect() {
|
|
2052
|
+
if (!this.dialect) {
|
|
2053
|
+
this.dialect = new DatabendDialect(this.dialectConfig);
|
|
2054
|
+
}
|
|
2055
|
+
return this.dialect;
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
2058
|
+
|
|
2059
|
+
// src/databend-core/view-common.ts
|
|
2060
|
+
var DatabendViewConfig = Symbol.for("drizzle:DatabendViewConfig");
|
|
2061
|
+
|
|
2062
|
+
// src/databend-core/view.ts
|
|
2063
|
+
var DefaultViewBuilderCore = class {
|
|
2064
|
+
constructor(name, schema) {
|
|
2065
|
+
this.name = name;
|
|
2066
|
+
this.schema = schema;
|
|
2067
|
+
}
|
|
2068
|
+
static [entityKind26] = "DatabendDefaultViewBuilderCore";
|
|
2069
|
+
config = {};
|
|
2070
|
+
with(config) {
|
|
2071
|
+
this.config.with = config;
|
|
2072
|
+
return this;
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
var ViewBuilder = class extends DefaultViewBuilderCore {
|
|
2076
|
+
static [entityKind26] = "DatabendViewBuilder";
|
|
2077
|
+
as(qb) {
|
|
2078
|
+
if (typeof qb === "function") {
|
|
2079
|
+
qb = qb(new QueryBuilder());
|
|
2080
|
+
}
|
|
2081
|
+
const selectionProxy = new SelectionProxyHandler3({
|
|
2082
|
+
alias: this.name,
|
|
2083
|
+
sqlBehavior: "error",
|
|
2084
|
+
sqlAliasedBehavior: "alias",
|
|
2085
|
+
replaceOriginalName: true
|
|
2086
|
+
});
|
|
2087
|
+
const aliasedSelection = new Proxy(qb.getSelectedFields(), selectionProxy);
|
|
2088
|
+
return new Proxy(
|
|
2089
|
+
new DatabendView({
|
|
2090
|
+
databendConfig: this.config,
|
|
2091
|
+
config: {
|
|
2092
|
+
name: this.name,
|
|
2093
|
+
schema: this.schema,
|
|
2094
|
+
selectedFields: aliasedSelection,
|
|
2095
|
+
query: qb.getSQL().inlineParams()
|
|
2096
|
+
}
|
|
2097
|
+
}),
|
|
2098
|
+
selectionProxy
|
|
2099
|
+
);
|
|
2100
|
+
}
|
|
2101
|
+
};
|
|
2102
|
+
var ManualViewBuilder = class extends DefaultViewBuilderCore {
|
|
2103
|
+
static [entityKind26] = "DatabendManualViewBuilder";
|
|
2104
|
+
columns;
|
|
2105
|
+
constructor(name, columns, schema) {
|
|
2106
|
+
super(name, schema);
|
|
2107
|
+
this.columns = getTableColumns2(databendTable(name, columns));
|
|
2108
|
+
}
|
|
2109
|
+
existing() {
|
|
2110
|
+
return new Proxy(
|
|
2111
|
+
new DatabendView({
|
|
2112
|
+
databendConfig: void 0,
|
|
2113
|
+
config: {
|
|
2114
|
+
name: this.name,
|
|
2115
|
+
schema: this.schema,
|
|
2116
|
+
selectedFields: this.columns,
|
|
2117
|
+
query: void 0
|
|
2118
|
+
}
|
|
2119
|
+
}),
|
|
2120
|
+
new SelectionProxyHandler3({
|
|
2121
|
+
alias: this.name,
|
|
2122
|
+
sqlBehavior: "error",
|
|
2123
|
+
sqlAliasedBehavior: "alias",
|
|
2124
|
+
replaceOriginalName: true
|
|
2125
|
+
})
|
|
2126
|
+
);
|
|
2127
|
+
}
|
|
2128
|
+
as(query) {
|
|
2129
|
+
return new Proxy(
|
|
2130
|
+
new DatabendView({
|
|
2131
|
+
databendConfig: this.config,
|
|
2132
|
+
config: {
|
|
2133
|
+
name: this.name,
|
|
2134
|
+
schema: this.schema,
|
|
2135
|
+
selectedFields: this.columns,
|
|
2136
|
+
query: query.inlineParams()
|
|
2137
|
+
}
|
|
2138
|
+
}),
|
|
2139
|
+
new SelectionProxyHandler3({
|
|
2140
|
+
alias: this.name,
|
|
2141
|
+
sqlBehavior: "error",
|
|
2142
|
+
sqlAliasedBehavior: "alias",
|
|
2143
|
+
replaceOriginalName: true
|
|
2144
|
+
})
|
|
2145
|
+
);
|
|
2146
|
+
}
|
|
2147
|
+
};
|
|
2148
|
+
var DatabendView = class extends DatabendViewBase {
|
|
2149
|
+
static [entityKind26] = "DatabendView";
|
|
2150
|
+
[DatabendViewConfig];
|
|
2151
|
+
constructor({ databendConfig, config }) {
|
|
2152
|
+
super(config);
|
|
2153
|
+
if (databendConfig) {
|
|
2154
|
+
this[DatabendViewConfig] = {
|
|
2155
|
+
with: databendConfig.with
|
|
2156
|
+
};
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
function databendViewWithSchema(name, selection, schema) {
|
|
2161
|
+
if (selection) {
|
|
2162
|
+
return new ManualViewBuilder(name, selection, schema);
|
|
2163
|
+
}
|
|
2164
|
+
return new ViewBuilder(name, schema);
|
|
2165
|
+
}
|
|
2166
|
+
function databendView(name, columns) {
|
|
2167
|
+
return databendViewWithSchema(name, columns, void 0);
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
// src/driver.ts
|
|
2171
|
+
import { Client } from "databend-driver";
|
|
2172
|
+
import { entityKind as entityKind36 } from "drizzle-orm/entity";
|
|
2173
|
+
import { DefaultLogger } from "drizzle-orm/logger";
|
|
2174
|
+
import {
|
|
2175
|
+
createTableRelationsHelpers,
|
|
2176
|
+
extractTablesRelationalConfig
|
|
2177
|
+
} from "drizzle-orm/relations";
|
|
2178
|
+
|
|
2179
|
+
// src/databend-core/db.ts
|
|
2180
|
+
import { entityKind as entityKind33 } from "drizzle-orm/entity";
|
|
2181
|
+
import { SelectionProxyHandler as SelectionProxyHandler4 } from "drizzle-orm/selection-proxy";
|
|
2182
|
+
import { sql as sql6 } from "drizzle-orm/sql/sql";
|
|
2183
|
+
import { WithSubquery as WithSubquery2 } from "drizzle-orm/subquery";
|
|
2184
|
+
|
|
2185
|
+
// src/databend-core/query-builders/count.ts
|
|
2186
|
+
import { entityKind as entityKind27 } from "drizzle-orm/entity";
|
|
2187
|
+
import { SQL as SQL5, sql as sql5 } from "drizzle-orm/sql/sql";
|
|
2188
|
+
var DatabendCountBuilder = class _DatabendCountBuilder extends SQL5 {
|
|
2189
|
+
static [entityKind27] = "DatabendCountBuilder";
|
|
2190
|
+
[Symbol.toStringTag] = "DatabendCountBuilder";
|
|
2191
|
+
sql;
|
|
2192
|
+
session;
|
|
2193
|
+
constructor(params) {
|
|
2194
|
+
super(_DatabendCountBuilder.buildEmbeddedCount(params.source, params.filters).queryChunks);
|
|
2195
|
+
this.mapWith(Number);
|
|
2196
|
+
this.session = params.session;
|
|
2197
|
+
this.sql = _DatabendCountBuilder.buildCount(params.source, params.filters);
|
|
2198
|
+
}
|
|
2199
|
+
static buildEmbeddedCount(source, filters) {
|
|
2200
|
+
return sql5`(select count(*) from ${source}${sql5.raw(" where ").if(filters)}${filters})`;
|
|
2201
|
+
}
|
|
2202
|
+
static buildCount(source, filters) {
|
|
2203
|
+
return sql5`select count(*) as count from ${source}${sql5.raw(" where ").if(filters)}${filters};`;
|
|
2204
|
+
}
|
|
2205
|
+
// biome-ignore lint/suspicious/noThenProperty: Promise-like interface required for await support
|
|
2206
|
+
then(onfulfilled, onrejected) {
|
|
2207
|
+
return Promise.resolve(this.session.count(this.sql)).then(onfulfilled, onrejected);
|
|
2208
|
+
}
|
|
2209
|
+
catch(onRejected) {
|
|
2210
|
+
return this.then(void 0, onRejected);
|
|
2211
|
+
}
|
|
2212
|
+
finally(onFinally) {
|
|
2213
|
+
return this.then(
|
|
2214
|
+
(value) => {
|
|
2215
|
+
onFinally?.();
|
|
2216
|
+
return value;
|
|
2217
|
+
},
|
|
2218
|
+
(reason) => {
|
|
2219
|
+
onFinally?.();
|
|
2220
|
+
throw reason;
|
|
2221
|
+
}
|
|
2222
|
+
);
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
|
|
2226
|
+
// src/databend-core/query-builders/delete.ts
|
|
2227
|
+
import { entityKind as entityKind28 } from "drizzle-orm/entity";
|
|
2228
|
+
import { QueryPromise as QueryPromise2 } from "drizzle-orm/query-promise";
|
|
2229
|
+
import { tracer as tracer2 } from "drizzle-orm/tracing";
|
|
2230
|
+
var DatabendDeleteBase = class extends QueryPromise2 {
|
|
2231
|
+
constructor(table, session, dialect, withList) {
|
|
2232
|
+
super();
|
|
2233
|
+
this.session = session;
|
|
2234
|
+
this.dialect = dialect;
|
|
2235
|
+
this.config = { table, withList };
|
|
2236
|
+
}
|
|
2237
|
+
static [entityKind28] = "DatabendDelete";
|
|
2238
|
+
config;
|
|
2239
|
+
where(where) {
|
|
2240
|
+
this.config.where = where;
|
|
2241
|
+
return this;
|
|
2242
|
+
}
|
|
2243
|
+
/** @internal */
|
|
2244
|
+
getSQL() {
|
|
2245
|
+
return this.dialect.buildDeleteQuery(this.config);
|
|
2246
|
+
}
|
|
2247
|
+
toSQL() {
|
|
2248
|
+
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
|
|
2249
|
+
return rest;
|
|
2250
|
+
}
|
|
2251
|
+
/** @internal */
|
|
2252
|
+
_prepare(name) {
|
|
2253
|
+
return tracer2.startActiveSpan("drizzle.prepareQuery", () => {
|
|
2254
|
+
return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()), void 0, name, true);
|
|
2255
|
+
});
|
|
2256
|
+
}
|
|
2257
|
+
prepare(name) {
|
|
2258
|
+
return this._prepare(name);
|
|
2259
|
+
}
|
|
2260
|
+
execute = (placeholderValues) => {
|
|
2261
|
+
return tracer2.startActiveSpan("drizzle.operation", () => {
|
|
2262
|
+
return this._prepare().execute(placeholderValues);
|
|
2263
|
+
});
|
|
2264
|
+
};
|
|
2265
|
+
$dynamic() {
|
|
2266
|
+
return this;
|
|
2267
|
+
}
|
|
2268
|
+
};
|
|
2269
|
+
|
|
2270
|
+
// src/databend-core/query-builders/insert.ts
|
|
2271
|
+
import { entityKind as entityKind29, is as is8 } from "drizzle-orm/entity";
|
|
2272
|
+
import { QueryPromise as QueryPromise3 } from "drizzle-orm/query-promise";
|
|
2273
|
+
import { Param as Param2, SQL as SQL6 } from "drizzle-orm/sql/sql";
|
|
2274
|
+
import { Table as Table5 } from "drizzle-orm/table";
|
|
2275
|
+
import { tracer as tracer3 } from "drizzle-orm/tracing";
|
|
2276
|
+
import { haveSameKeys as haveSameKeys2 } from "drizzle-orm/utils";
|
|
2277
|
+
var DatabendInsertBuilder = class {
|
|
2278
|
+
constructor(table, session, dialect, withList) {
|
|
2279
|
+
this.table = table;
|
|
2280
|
+
this.session = session;
|
|
2281
|
+
this.dialect = dialect;
|
|
2282
|
+
this.withList = withList;
|
|
2283
|
+
}
|
|
2284
|
+
static [entityKind29] = "DatabendInsertBuilder";
|
|
2285
|
+
values(values) {
|
|
2286
|
+
values = Array.isArray(values) ? values : [values];
|
|
2287
|
+
if (values.length === 0) {
|
|
2288
|
+
throw new Error("values() must be called with at least one value");
|
|
2289
|
+
}
|
|
2290
|
+
const mappedValues = values.map((entry) => {
|
|
2291
|
+
const result = {};
|
|
2292
|
+
const cols = this.table[Table5.Symbol.Columns];
|
|
2293
|
+
for (const colKey of Object.keys(entry)) {
|
|
2294
|
+
const colValue = entry[colKey];
|
|
2295
|
+
result[colKey] = is8(colValue, SQL6) ? colValue : new Param2(colValue, cols[colKey]);
|
|
2296
|
+
}
|
|
2297
|
+
return result;
|
|
2298
|
+
});
|
|
2299
|
+
return new DatabendInsertBase(
|
|
2300
|
+
this.table,
|
|
2301
|
+
mappedValues,
|
|
2302
|
+
this.session,
|
|
2303
|
+
this.dialect,
|
|
2304
|
+
this.withList,
|
|
2305
|
+
false
|
|
2306
|
+
);
|
|
2307
|
+
}
|
|
2308
|
+
select(selectQuery) {
|
|
2309
|
+
const select = typeof selectQuery === "function" ? selectQuery(new QueryBuilder()) : selectQuery;
|
|
2310
|
+
if (!is8(select, SQL6) && !haveSameKeys2(this.table[Table5.Symbol.Columns], select._.selectedFields)) {
|
|
2311
|
+
throw new Error(
|
|
2312
|
+
"Insert select error: selected fields are not the same or are in a different order compared to the table definition"
|
|
2313
|
+
);
|
|
2314
|
+
}
|
|
2315
|
+
return new DatabendInsertBase(this.table, select, this.session, this.dialect, this.withList, true);
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
var DatabendInsertBase = class extends QueryPromise3 {
|
|
2319
|
+
constructor(table, values, session, dialect, withList, select) {
|
|
2320
|
+
super();
|
|
2321
|
+
this.session = session;
|
|
2322
|
+
this.dialect = dialect;
|
|
2323
|
+
this.config = { table, values, withList, select };
|
|
2324
|
+
}
|
|
2325
|
+
static [entityKind29] = "DatabendInsert";
|
|
2326
|
+
config;
|
|
2327
|
+
/** @internal */
|
|
2328
|
+
getSQL() {
|
|
2329
|
+
return this.dialect.buildInsertQuery(this.config);
|
|
2330
|
+
}
|
|
2331
|
+
toSQL() {
|
|
2332
|
+
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
|
|
2333
|
+
return rest;
|
|
2334
|
+
}
|
|
2335
|
+
/** @internal */
|
|
2336
|
+
_prepare(name) {
|
|
2337
|
+
return tracer3.startActiveSpan("drizzle.prepareQuery", () => {
|
|
2338
|
+
return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()), void 0, name, true);
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
prepare(name) {
|
|
2342
|
+
return this._prepare(name);
|
|
2343
|
+
}
|
|
2344
|
+
execute = (placeholderValues) => {
|
|
2345
|
+
return tracer3.startActiveSpan("drizzle.operation", () => {
|
|
2346
|
+
return this._prepare().execute(placeholderValues);
|
|
2347
|
+
});
|
|
2348
|
+
};
|
|
2349
|
+
$dynamic() {
|
|
2350
|
+
return this;
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
|
|
2354
|
+
// src/databend-core/query-builders/update.ts
|
|
2355
|
+
import { entityKind as entityKind30 } from "drizzle-orm/entity";
|
|
2356
|
+
import { QueryPromise as QueryPromise4 } from "drizzle-orm/query-promise";
|
|
2357
|
+
import "drizzle-orm/sql/sql";
|
|
2358
|
+
import "drizzle-orm/table";
|
|
2359
|
+
import { tracer as tracer4 } from "drizzle-orm/tracing";
|
|
2360
|
+
import { mapUpdateSet } from "drizzle-orm/utils";
|
|
2361
|
+
var DatabendUpdateBuilder = class {
|
|
2362
|
+
constructor(table, session, dialect, withList) {
|
|
2363
|
+
this.table = table;
|
|
2364
|
+
this.session = session;
|
|
2365
|
+
this.dialect = dialect;
|
|
2366
|
+
this.withList = withList;
|
|
2367
|
+
}
|
|
2368
|
+
static [entityKind30] = "DatabendUpdateBuilder";
|
|
2369
|
+
set(values) {
|
|
2370
|
+
return new DatabendUpdateBase(
|
|
2371
|
+
this.table,
|
|
2372
|
+
mapUpdateSet(this.table, values),
|
|
2373
|
+
this.session,
|
|
2374
|
+
this.dialect,
|
|
2375
|
+
this.withList
|
|
2376
|
+
);
|
|
2377
|
+
}
|
|
2378
|
+
};
|
|
2379
|
+
var DatabendUpdateBase = class extends QueryPromise4 {
|
|
2380
|
+
constructor(table, set, session, dialect, withList) {
|
|
2381
|
+
super();
|
|
2382
|
+
this.session = session;
|
|
2383
|
+
this.dialect = dialect;
|
|
2384
|
+
this.config = { set, table, withList };
|
|
2385
|
+
}
|
|
2386
|
+
static [entityKind30] = "DatabendUpdate";
|
|
2387
|
+
config;
|
|
2388
|
+
where(where) {
|
|
2389
|
+
this.config.where = where;
|
|
2390
|
+
return this;
|
|
2391
|
+
}
|
|
2392
|
+
/** @internal */
|
|
2393
|
+
getSQL() {
|
|
2394
|
+
return this.dialect.buildUpdateQuery(this.config);
|
|
2395
|
+
}
|
|
2396
|
+
toSQL() {
|
|
2397
|
+
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
|
|
2398
|
+
return rest;
|
|
2399
|
+
}
|
|
2400
|
+
/** @internal */
|
|
2401
|
+
_prepare(name) {
|
|
2402
|
+
return tracer4.startActiveSpan("drizzle.prepareQuery", () => {
|
|
2403
|
+
return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()), void 0, name, true);
|
|
2404
|
+
});
|
|
2405
|
+
}
|
|
2406
|
+
prepare(name) {
|
|
2407
|
+
return this._prepare(name);
|
|
2408
|
+
}
|
|
2409
|
+
execute = (placeholderValues) => {
|
|
2410
|
+
return tracer4.startActiveSpan("drizzle.operation", () => {
|
|
2411
|
+
return this._prepare().execute(placeholderValues);
|
|
2412
|
+
});
|
|
2413
|
+
};
|
|
2414
|
+
$dynamic() {
|
|
2415
|
+
return this;
|
|
2416
|
+
}
|
|
2417
|
+
};
|
|
2418
|
+
|
|
2419
|
+
// src/databend-core/query-builders/query.ts
|
|
2420
|
+
import { entityKind as entityKind31 } from "drizzle-orm/entity";
|
|
2421
|
+
import { QueryPromise as QueryPromise5 } from "drizzle-orm/query-promise";
|
|
2422
|
+
import { mapRelationalRow } from "drizzle-orm/relations";
|
|
2423
|
+
import { tracer as tracer5 } from "drizzle-orm/tracing";
|
|
2424
|
+
var RelationalQueryBuilder = class {
|
|
2425
|
+
constructor(fullSchema, schema, tableNamesMap, table, tableConfig, dialect, session) {
|
|
2426
|
+
this.fullSchema = fullSchema;
|
|
2427
|
+
this.schema = schema;
|
|
2428
|
+
this.tableNamesMap = tableNamesMap;
|
|
2429
|
+
this.table = table;
|
|
2430
|
+
this.tableConfig = tableConfig;
|
|
2431
|
+
this.dialect = dialect;
|
|
2432
|
+
this.session = session;
|
|
2433
|
+
}
|
|
2434
|
+
static [entityKind31] = "DatabendRelationalQueryBuilder";
|
|
2435
|
+
findMany(config) {
|
|
2436
|
+
return new DatabendRelationalQuery(
|
|
2437
|
+
this.fullSchema,
|
|
2438
|
+
this.schema,
|
|
2439
|
+
this.tableNamesMap,
|
|
2440
|
+
this.table,
|
|
2441
|
+
this.tableConfig,
|
|
2442
|
+
this.dialect,
|
|
2443
|
+
this.session,
|
|
2444
|
+
config ? config : {},
|
|
2445
|
+
"many"
|
|
2446
|
+
);
|
|
2447
|
+
}
|
|
2448
|
+
findFirst(config) {
|
|
2449
|
+
return new DatabendRelationalQuery(
|
|
2450
|
+
this.fullSchema,
|
|
2451
|
+
this.schema,
|
|
2452
|
+
this.tableNamesMap,
|
|
2453
|
+
this.table,
|
|
2454
|
+
this.tableConfig,
|
|
2455
|
+
this.dialect,
|
|
2456
|
+
this.session,
|
|
2457
|
+
config ? { ...config, limit: 1 } : { limit: 1 },
|
|
2458
|
+
"first"
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2462
|
+
var DatabendRelationalQuery = class extends QueryPromise5 {
|
|
2463
|
+
constructor(fullSchema, schema, tableNamesMap, table, tableConfig, dialect, session, config, mode) {
|
|
2464
|
+
super();
|
|
2465
|
+
this.fullSchema = fullSchema;
|
|
2466
|
+
this.schema = schema;
|
|
2467
|
+
this.tableNamesMap = tableNamesMap;
|
|
2468
|
+
this.table = table;
|
|
2469
|
+
this.tableConfig = tableConfig;
|
|
2470
|
+
this.dialect = dialect;
|
|
2471
|
+
this.session = session;
|
|
2472
|
+
this.config = config;
|
|
2473
|
+
this.mode = mode;
|
|
2474
|
+
}
|
|
2475
|
+
static [entityKind31] = "DatabendRelationalQuery";
|
|
2476
|
+
/** @internal */
|
|
2477
|
+
_prepare(name) {
|
|
2478
|
+
return tracer5.startActiveSpan("drizzle.prepareQuery", () => {
|
|
2479
|
+
const { query, builtQuery } = this._toSQL();
|
|
2480
|
+
return this.session.prepareQuery(
|
|
2481
|
+
builtQuery,
|
|
2482
|
+
void 0,
|
|
2483
|
+
name,
|
|
2484
|
+
true,
|
|
2485
|
+
(rawRows, mapColumnValue) => {
|
|
2486
|
+
const rows = rawRows.map(
|
|
2487
|
+
(row) => mapRelationalRow(this.schema, this.tableConfig, row, query.selection, mapColumnValue)
|
|
2488
|
+
);
|
|
2489
|
+
if (this.mode === "first") {
|
|
2490
|
+
return rows[0];
|
|
2491
|
+
}
|
|
2492
|
+
return rows;
|
|
2493
|
+
}
|
|
2494
|
+
);
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2497
|
+
prepare(name) {
|
|
2498
|
+
return this._prepare(name);
|
|
2499
|
+
}
|
|
2500
|
+
_getQuery() {
|
|
2501
|
+
return this.dialect.buildRelationalQueryWithoutPK({
|
|
2502
|
+
fullSchema: this.fullSchema,
|
|
2503
|
+
schema: this.schema,
|
|
2504
|
+
tableNamesMap: this.tableNamesMap,
|
|
2505
|
+
table: this.table,
|
|
2506
|
+
tableConfig: this.tableConfig,
|
|
2507
|
+
queryConfig: this.config,
|
|
2508
|
+
tableAlias: this.tableConfig.tsName
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
/** @internal */
|
|
2512
|
+
getSQL() {
|
|
2513
|
+
return this._getQuery().sql;
|
|
2514
|
+
}
|
|
2515
|
+
_toSQL() {
|
|
2516
|
+
const query = this._getQuery();
|
|
2517
|
+
const builtQuery = this.dialect.sqlToQuery(query.sql);
|
|
2518
|
+
return { query, builtQuery };
|
|
2519
|
+
}
|
|
2520
|
+
toSQL() {
|
|
2521
|
+
return this._toSQL().builtQuery;
|
|
2522
|
+
}
|
|
2523
|
+
execute() {
|
|
2524
|
+
return tracer5.startActiveSpan("drizzle.operation", () => {
|
|
2525
|
+
return this._prepare().execute(void 0);
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2528
|
+
};
|
|
2529
|
+
|
|
2530
|
+
// src/databend-core/query-builders/raw.ts
|
|
2531
|
+
import { entityKind as entityKind32 } from "drizzle-orm/entity";
|
|
2532
|
+
import { QueryPromise as QueryPromise6 } from "drizzle-orm/query-promise";
|
|
2533
|
+
var DatabendRaw = class extends QueryPromise6 {
|
|
2534
|
+
constructor(execute, sql8, query, mapBatchResult) {
|
|
2535
|
+
super();
|
|
2536
|
+
this.execute = execute;
|
|
2537
|
+
this.sql = sql8;
|
|
2538
|
+
this.query = query;
|
|
2539
|
+
this.mapBatchResult = mapBatchResult;
|
|
2540
|
+
}
|
|
2541
|
+
static [entityKind32] = "DatabendRaw";
|
|
2542
|
+
/** @internal */
|
|
2543
|
+
getSQL() {
|
|
2544
|
+
return this.sql;
|
|
2545
|
+
}
|
|
2546
|
+
getQuery() {
|
|
2547
|
+
return this.query;
|
|
2548
|
+
}
|
|
2549
|
+
mapResult(result, isFromBatch) {
|
|
2550
|
+
return isFromBatch ? this.mapBatchResult(result) : result;
|
|
2551
|
+
}
|
|
2552
|
+
_prepare() {
|
|
2553
|
+
return this;
|
|
2554
|
+
}
|
|
2555
|
+
/** @internal */
|
|
2556
|
+
isResponseInArrayMode() {
|
|
2557
|
+
return false;
|
|
2558
|
+
}
|
|
2559
|
+
};
|
|
2560
|
+
|
|
2561
|
+
// src/databend-core/db.ts
|
|
2562
|
+
var DatabendDatabase = class {
|
|
2563
|
+
constructor(dialect, session, schema) {
|
|
2564
|
+
this.dialect = dialect;
|
|
2565
|
+
this.session = session;
|
|
2566
|
+
this._ = schema ? {
|
|
2567
|
+
schema: schema.schema,
|
|
2568
|
+
fullSchema: schema.fullSchema,
|
|
2569
|
+
tableNamesMap: schema.tableNamesMap,
|
|
2570
|
+
session
|
|
2571
|
+
} : {
|
|
2572
|
+
schema: void 0,
|
|
2573
|
+
fullSchema: {},
|
|
2574
|
+
tableNamesMap: {},
|
|
2575
|
+
session
|
|
2576
|
+
};
|
|
2577
|
+
this.query = {};
|
|
2578
|
+
if (this._.schema) {
|
|
2579
|
+
for (const [tableName, columns] of Object.entries(this._.schema)) {
|
|
2580
|
+
this.query[tableName] = new RelationalQueryBuilder(
|
|
2581
|
+
schema.fullSchema,
|
|
2582
|
+
this._.schema,
|
|
2583
|
+
this._.tableNamesMap,
|
|
2584
|
+
schema.fullSchema[tableName],
|
|
2585
|
+
columns,
|
|
2586
|
+
dialect,
|
|
2587
|
+
session
|
|
2588
|
+
);
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
static [entityKind33] = "DatabendDatabase";
|
|
2593
|
+
_;
|
|
2594
|
+
query;
|
|
2595
|
+
$with(alias2) {
|
|
2596
|
+
const self = this;
|
|
2597
|
+
return {
|
|
2598
|
+
as(qb) {
|
|
2599
|
+
if (typeof qb === "function") {
|
|
2600
|
+
qb = qb(new QueryBuilder(self.dialect));
|
|
2601
|
+
}
|
|
2602
|
+
const sqlObj = typeof qb.getSQL === "function" ? qb.getSQL() : qb;
|
|
2603
|
+
const fields = typeof qb.getSelectedFields === "function" ? qb.getSelectedFields() : {};
|
|
2604
|
+
return new Proxy(
|
|
2605
|
+
new WithSubquery2(sqlObj, fields, alias2, true),
|
|
2606
|
+
new SelectionProxyHandler4({ alias: alias2, sqlAliasedBehavior: "alias", sqlBehavior: "error" })
|
|
2607
|
+
);
|
|
2608
|
+
}
|
|
2609
|
+
};
|
|
2610
|
+
}
|
|
2611
|
+
$count(source, filters) {
|
|
2612
|
+
return new DatabendCountBuilder({ source, filters, session: this.session });
|
|
2613
|
+
}
|
|
2614
|
+
with(...queries) {
|
|
2615
|
+
const self = this;
|
|
2616
|
+
function select(fields) {
|
|
2617
|
+
return new DatabendSelectBuilder({
|
|
2618
|
+
fields: fields ?? void 0,
|
|
2619
|
+
session: self.session,
|
|
2620
|
+
dialect: self.dialect,
|
|
2621
|
+
withList: queries
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
function selectDistinct(fields) {
|
|
2625
|
+
return new DatabendSelectBuilder({
|
|
2626
|
+
fields: fields ?? void 0,
|
|
2627
|
+
session: self.session,
|
|
2628
|
+
dialect: self.dialect,
|
|
2629
|
+
withList: queries,
|
|
2630
|
+
distinct: true
|
|
2631
|
+
});
|
|
2632
|
+
}
|
|
2633
|
+
function update(table) {
|
|
2634
|
+
return new DatabendUpdateBuilder(table, self.session, self.dialect, queries);
|
|
2635
|
+
}
|
|
2636
|
+
function insert(table) {
|
|
2637
|
+
return new DatabendInsertBuilder(table, self.session, self.dialect, queries);
|
|
2638
|
+
}
|
|
2639
|
+
function delete_(table) {
|
|
2640
|
+
return new DatabendDeleteBase(table, self.session, self.dialect, queries);
|
|
2641
|
+
}
|
|
2642
|
+
return { select, selectDistinct, update, insert, delete: delete_ };
|
|
2643
|
+
}
|
|
2644
|
+
select(fields) {
|
|
2645
|
+
return new DatabendSelectBuilder({
|
|
2646
|
+
fields: fields ?? void 0,
|
|
2647
|
+
session: this.session,
|
|
2648
|
+
dialect: this.dialect
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
selectDistinct(fields) {
|
|
2652
|
+
return new DatabendSelectBuilder({
|
|
2653
|
+
fields: fields ?? void 0,
|
|
2654
|
+
session: this.session,
|
|
2655
|
+
dialect: this.dialect,
|
|
2656
|
+
distinct: true
|
|
2657
|
+
});
|
|
2658
|
+
}
|
|
2659
|
+
update(table) {
|
|
2660
|
+
return new DatabendUpdateBuilder(table, this.session, this.dialect);
|
|
2661
|
+
}
|
|
2662
|
+
insert(table) {
|
|
2663
|
+
return new DatabendInsertBuilder(table, this.session, this.dialect);
|
|
2664
|
+
}
|
|
2665
|
+
delete(table) {
|
|
2666
|
+
return new DatabendDeleteBase(table, this.session, this.dialect);
|
|
2667
|
+
}
|
|
2668
|
+
execute(query) {
|
|
2669
|
+
const sequel = typeof query === "string" ? sql6.raw(query) : query.getSQL();
|
|
2670
|
+
const builtQuery = this.dialect.sqlToQuery(sequel);
|
|
2671
|
+
const prepared = this.session.prepareQuery(builtQuery, void 0, void 0, false);
|
|
2672
|
+
return new DatabendRaw(
|
|
2673
|
+
() => prepared.execute(void 0),
|
|
2674
|
+
sequel,
|
|
2675
|
+
builtQuery,
|
|
2676
|
+
(result) => prepared.mapResult(result, true)
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
transaction(transaction) {
|
|
2680
|
+
return this.session.transaction(transaction);
|
|
2681
|
+
}
|
|
2682
|
+
};
|
|
2683
|
+
|
|
2684
|
+
// src/pool.ts
|
|
2685
|
+
function createDatabendConnectionPool(client, options = {}) {
|
|
2686
|
+
const size = options.size && options.size > 0 ? options.size : 4;
|
|
2687
|
+
const acquireTimeout = options.acquireTimeout ?? 3e4;
|
|
2688
|
+
const maxWaitingRequests = options.maxWaitingRequests ?? 100;
|
|
2689
|
+
const maxLifetimeMs = options.maxLifetimeMs;
|
|
2690
|
+
const idleTimeoutMs = options.idleTimeoutMs;
|
|
2691
|
+
const metadata = /* @__PURE__ */ new WeakMap();
|
|
2692
|
+
const idle = [];
|
|
2693
|
+
const waiting = [];
|
|
2694
|
+
let total = 0;
|
|
2695
|
+
let closed = false;
|
|
2696
|
+
let pendingAcquires = 0;
|
|
2697
|
+
const shouldRecycle = (conn, now) => {
|
|
2698
|
+
if (maxLifetimeMs !== void 0 && now - conn.createdAt >= maxLifetimeMs) {
|
|
2699
|
+
return true;
|
|
2700
|
+
}
|
|
2701
|
+
if (idleTimeoutMs !== void 0 && now - conn.lastUsedAt >= idleTimeoutMs) {
|
|
2702
|
+
return true;
|
|
2703
|
+
}
|
|
2704
|
+
return false;
|
|
2705
|
+
};
|
|
2706
|
+
const acquire = async () => {
|
|
2707
|
+
if (closed) {
|
|
2708
|
+
throw new Error("Databend connection pool is closed");
|
|
2709
|
+
}
|
|
2710
|
+
while (idle.length > 0) {
|
|
2711
|
+
const pooled = idle.pop();
|
|
2712
|
+
const now = Date.now();
|
|
2713
|
+
if (shouldRecycle(pooled, now)) {
|
|
2714
|
+
await closeClientConnection(pooled.connection);
|
|
2715
|
+
total = Math.max(0, total - 1);
|
|
2716
|
+
metadata.delete(pooled.connection);
|
|
2717
|
+
continue;
|
|
2718
|
+
}
|
|
2719
|
+
pooled.lastUsedAt = now;
|
|
2720
|
+
metadata.set(pooled.connection, {
|
|
2721
|
+
createdAt: pooled.createdAt,
|
|
2722
|
+
lastUsedAt: pooled.lastUsedAt
|
|
2723
|
+
});
|
|
2724
|
+
return pooled.connection;
|
|
2725
|
+
}
|
|
2726
|
+
if (total < size) {
|
|
2727
|
+
pendingAcquires += 1;
|
|
2728
|
+
total += 1;
|
|
2729
|
+
try {
|
|
2730
|
+
const connection = await client.getConn();
|
|
2731
|
+
if (closed) {
|
|
2732
|
+
await closeClientConnection(connection);
|
|
2733
|
+
total -= 1;
|
|
2734
|
+
throw new Error("Databend connection pool is closed");
|
|
2735
|
+
}
|
|
2736
|
+
const now = Date.now();
|
|
2737
|
+
metadata.set(connection, { createdAt: now, lastUsedAt: now });
|
|
2738
|
+
return connection;
|
|
2739
|
+
} catch (error) {
|
|
2740
|
+
total -= 1;
|
|
2741
|
+
throw error;
|
|
2742
|
+
} finally {
|
|
2743
|
+
pendingAcquires -= 1;
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
if (waiting.length >= maxWaitingRequests) {
|
|
2747
|
+
throw new Error(
|
|
2748
|
+
`Databend connection pool queue is full (max ${maxWaitingRequests} waiting requests)`
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2751
|
+
return await new Promise((resolve, reject) => {
|
|
2752
|
+
const timeoutId = setTimeout(() => {
|
|
2753
|
+
const idx = waiting.findIndex((w) => w.timeoutId === timeoutId);
|
|
2754
|
+
if (idx !== -1) {
|
|
2755
|
+
waiting.splice(idx, 1);
|
|
2756
|
+
}
|
|
2757
|
+
reject(
|
|
2758
|
+
new Error(
|
|
2759
|
+
`Databend connection pool acquire timeout after ${acquireTimeout}ms`
|
|
2760
|
+
)
|
|
2761
|
+
);
|
|
2762
|
+
}, acquireTimeout);
|
|
2763
|
+
waiting.push({ resolve, reject, timeoutId });
|
|
2764
|
+
});
|
|
2765
|
+
};
|
|
2766
|
+
const release = async (connection) => {
|
|
2767
|
+
const waiter = waiting.shift();
|
|
2768
|
+
if (waiter) {
|
|
2769
|
+
clearTimeout(waiter.timeoutId);
|
|
2770
|
+
const now2 = Date.now();
|
|
2771
|
+
const meta = metadata.get(connection) ?? { createdAt: now2, lastUsedAt: now2 };
|
|
2772
|
+
const expired = maxLifetimeMs !== void 0 && now2 - meta.createdAt >= maxLifetimeMs;
|
|
2773
|
+
if (closed) {
|
|
2774
|
+
await closeClientConnection(connection);
|
|
2775
|
+
total = Math.max(0, total - 1);
|
|
2776
|
+
metadata.delete(connection);
|
|
2777
|
+
waiter.reject(new Error("Databend connection pool is closed"));
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
if (expired) {
|
|
2781
|
+
await closeClientConnection(connection);
|
|
2782
|
+
total = Math.max(0, total - 1);
|
|
2783
|
+
metadata.delete(connection);
|
|
2784
|
+
try {
|
|
2785
|
+
const replacement = await acquire();
|
|
2786
|
+
waiter.resolve(replacement);
|
|
2787
|
+
} catch (error) {
|
|
2788
|
+
waiter.reject(error);
|
|
2789
|
+
}
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
meta.lastUsedAt = now2;
|
|
2793
|
+
metadata.set(connection, meta);
|
|
2794
|
+
waiter.resolve(connection);
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
if (closed) {
|
|
2798
|
+
await closeClientConnection(connection);
|
|
2799
|
+
metadata.delete(connection);
|
|
2800
|
+
total = Math.max(0, total - 1);
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
const now = Date.now();
|
|
2804
|
+
const existingMeta = metadata.get(connection) ?? { createdAt: now, lastUsedAt: now };
|
|
2805
|
+
existingMeta.lastUsedAt = now;
|
|
2806
|
+
metadata.set(connection, existingMeta);
|
|
2807
|
+
if (maxLifetimeMs !== void 0 && now - existingMeta.createdAt >= maxLifetimeMs) {
|
|
2808
|
+
await closeClientConnection(connection);
|
|
2809
|
+
total -= 1;
|
|
2810
|
+
metadata.delete(connection);
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
idle.push({
|
|
2814
|
+
connection,
|
|
2815
|
+
createdAt: existingMeta.createdAt,
|
|
2816
|
+
lastUsedAt: existingMeta.lastUsedAt
|
|
2817
|
+
});
|
|
2818
|
+
};
|
|
2819
|
+
const close = async () => {
|
|
2820
|
+
closed = true;
|
|
2821
|
+
const waiters = waiting.splice(0, waiting.length);
|
|
2822
|
+
for (const waiter of waiters) {
|
|
2823
|
+
clearTimeout(waiter.timeoutId);
|
|
2824
|
+
waiter.reject(new Error("Databend connection pool is closed"));
|
|
2825
|
+
}
|
|
2826
|
+
const toClose = idle.splice(0, idle.length);
|
|
2827
|
+
await Promise.allSettled(
|
|
2828
|
+
toClose.map((item) => closeClientConnection(item.connection))
|
|
2829
|
+
);
|
|
2830
|
+
total = Math.max(0, total - toClose.length);
|
|
2831
|
+
for (const item of toClose) {
|
|
2832
|
+
metadata.delete(item.connection);
|
|
2833
|
+
}
|
|
2834
|
+
const maxWait = 5e3;
|
|
2835
|
+
const start = Date.now();
|
|
2836
|
+
while (pendingAcquires > 0 && Date.now() - start < maxWait) {
|
|
2837
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
2838
|
+
}
|
|
2839
|
+
};
|
|
2840
|
+
return {
|
|
2841
|
+
acquire,
|
|
2842
|
+
release,
|
|
2843
|
+
close,
|
|
2844
|
+
size
|
|
2845
|
+
};
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
// src/session.ts
|
|
2849
|
+
import { entityKind as entityKind35 } from "drizzle-orm/entity";
|
|
2850
|
+
import { TransactionRollbackError as TransactionRollbackError2 } from "drizzle-orm/errors";
|
|
2851
|
+
import { NoopLogger } from "drizzle-orm/logger";
|
|
2852
|
+
import { fillPlaceholders, sql as sql7 } from "drizzle-orm/sql/sql";
|
|
2853
|
+
|
|
2854
|
+
// src/databend-core/session.ts
|
|
2855
|
+
import { entityKind as entityKind34 } from "drizzle-orm/entity";
|
|
2856
|
+
import { TransactionRollbackError } from "drizzle-orm/errors";
|
|
2857
|
+
import { tracer as tracer6 } from "drizzle-orm/tracing";
|
|
2858
|
+
var DatabendPreparedQuery = class {
|
|
2859
|
+
constructor(query) {
|
|
2860
|
+
this.query = query;
|
|
2861
|
+
}
|
|
2862
|
+
static [entityKind34] = "DatabendPreparedQuery";
|
|
2863
|
+
/** @internal */
|
|
2864
|
+
joinsNotNullableMap;
|
|
2865
|
+
getQuery() {
|
|
2866
|
+
return this.query;
|
|
2867
|
+
}
|
|
2868
|
+
mapResult(response, _isFromBatch) {
|
|
2869
|
+
return response;
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
var DatabendSession = class {
|
|
2873
|
+
constructor(dialect) {
|
|
2874
|
+
this.dialect = dialect;
|
|
2875
|
+
}
|
|
2876
|
+
static [entityKind34] = "DatabendSession";
|
|
2877
|
+
execute(query) {
|
|
2878
|
+
return tracer6.startActiveSpan("drizzle.operation", () => {
|
|
2879
|
+
const prepared = tracer6.startActiveSpan("drizzle.prepareQuery", () => {
|
|
2880
|
+
return this.prepareQuery(
|
|
2881
|
+
this.dialect.sqlToQuery(query),
|
|
2882
|
+
void 0,
|
|
2883
|
+
void 0,
|
|
2884
|
+
false
|
|
2885
|
+
);
|
|
2886
|
+
});
|
|
2887
|
+
return prepared.execute(void 0);
|
|
2888
|
+
});
|
|
2889
|
+
}
|
|
2890
|
+
all(query) {
|
|
2891
|
+
return this.prepareQuery(
|
|
2892
|
+
this.dialect.sqlToQuery(query),
|
|
2893
|
+
void 0,
|
|
2894
|
+
void 0,
|
|
2895
|
+
false
|
|
2896
|
+
).all();
|
|
2897
|
+
}
|
|
2898
|
+
async count(sql8) {
|
|
2899
|
+
const res = await this.execute(sql8);
|
|
2900
|
+
return Number(res[0]["count"]);
|
|
2901
|
+
}
|
|
2902
|
+
prepareQuery(_query, _fields, _name, _isResponseInArrayMode, _customResultMapper) {
|
|
2903
|
+
throw new Error("prepareQuery not implemented");
|
|
2904
|
+
}
|
|
2905
|
+
transaction(_transaction, _config) {
|
|
2906
|
+
throw new Error("transaction not implemented");
|
|
2907
|
+
}
|
|
2908
|
+
};
|
|
2909
|
+
var DatabendTransaction = class extends DatabendDatabase {
|
|
2910
|
+
constructor(dialect, session, schema, nestedIndex = 0) {
|
|
2911
|
+
super(dialect, session, schema);
|
|
2912
|
+
this.nestedIndex = nestedIndex;
|
|
2913
|
+
this.schema = schema;
|
|
2914
|
+
}
|
|
2915
|
+
static [entityKind34] = "DatabendTransaction";
|
|
2916
|
+
rollback() {
|
|
2917
|
+
throw new TransactionRollbackError();
|
|
2918
|
+
}
|
|
2919
|
+
};
|
|
2920
|
+
|
|
2921
|
+
// src/sql/result-mapper.ts
|
|
2922
|
+
import {
|
|
2923
|
+
Column as Column3,
|
|
2924
|
+
getTableName as getTableName2,
|
|
2925
|
+
is as is10,
|
|
2926
|
+
SQL as SQL8
|
|
2927
|
+
} from "drizzle-orm";
|
|
2928
|
+
function toDecoderInput(decoder, value) {
|
|
2929
|
+
void decoder;
|
|
2930
|
+
return value;
|
|
2931
|
+
}
|
|
2932
|
+
function normalizeTimestamp(value, _withTimezone) {
|
|
2933
|
+
if (value instanceof Date) {
|
|
2934
|
+
return value;
|
|
2935
|
+
}
|
|
2936
|
+
if (typeof value === "string") {
|
|
2937
|
+
const hasOffset = value.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(value.trim());
|
|
2938
|
+
const spaced = value.replace(" ", "T");
|
|
2939
|
+
const normalized = hasOffset ? spaced : `${spaced}Z`;
|
|
2940
|
+
return new Date(normalized);
|
|
2941
|
+
}
|
|
2942
|
+
return value;
|
|
2943
|
+
}
|
|
2944
|
+
function normalizeDateString(value) {
|
|
2945
|
+
if (value instanceof Date) {
|
|
2946
|
+
return value.toISOString().slice(0, 10);
|
|
2947
|
+
}
|
|
2948
|
+
if (typeof value === "string") {
|
|
2949
|
+
return value.slice(0, 10);
|
|
2950
|
+
}
|
|
2951
|
+
return value;
|
|
2952
|
+
}
|
|
2953
|
+
function mapDriverValue(decoder, rawValue) {
|
|
2954
|
+
if (is10(decoder, DatabendTimestamp)) {
|
|
2955
|
+
const normalized = normalizeTimestamp(rawValue, false);
|
|
2956
|
+
if (normalized instanceof Date) {
|
|
2957
|
+
return normalized;
|
|
2958
|
+
}
|
|
2959
|
+
return decoder.mapFromDriverValue(toDecoderInput(decoder, normalized));
|
|
2960
|
+
}
|
|
2961
|
+
if (is10(decoder, DatabendDate)) {
|
|
2962
|
+
return decoder.mapFromDriverValue(
|
|
2963
|
+
toDecoderInput(decoder, normalizeDateString(rawValue))
|
|
2964
|
+
);
|
|
2965
|
+
}
|
|
2966
|
+
return decoder.mapFromDriverValue(toDecoderInput(decoder, rawValue));
|
|
2967
|
+
}
|
|
2968
|
+
function mapResultRow(columns, row, joinsNotNullableMap) {
|
|
2969
|
+
const nullifyMap = {};
|
|
2970
|
+
const result = columns.reduce(
|
|
2971
|
+
(acc, { path, field }, columnIndex) => {
|
|
2972
|
+
let decoder;
|
|
2973
|
+
if (is10(field, Column3)) {
|
|
2974
|
+
decoder = field;
|
|
2975
|
+
} else if (is10(field, SQL8)) {
|
|
2976
|
+
decoder = field.decoder;
|
|
2977
|
+
} else {
|
|
2978
|
+
const col = field.sql.queryChunks.find((chunk) => is10(chunk, Column3));
|
|
2979
|
+
if (is10(col, DatabendCustomColumn)) {
|
|
2980
|
+
decoder = col;
|
|
2981
|
+
} else {
|
|
2982
|
+
decoder = field.sql.decoder;
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
let node = acc;
|
|
2986
|
+
for (const [pathChunkIndex, pathChunk] of path.entries()) {
|
|
2987
|
+
if (pathChunkIndex < path.length - 1) {
|
|
2988
|
+
if (!(pathChunk in node)) {
|
|
2989
|
+
node[pathChunk] = {};
|
|
2990
|
+
}
|
|
2991
|
+
node = node[pathChunk];
|
|
2992
|
+
continue;
|
|
2993
|
+
}
|
|
2994
|
+
const rawValue = row[columnIndex];
|
|
2995
|
+
const value = node[pathChunk] = rawValue === null ? null : mapDriverValue(decoder, rawValue);
|
|
2996
|
+
if (joinsNotNullableMap && is10(field, Column3) && path.length === 2) {
|
|
2997
|
+
const objectName = path[0];
|
|
2998
|
+
if (!(objectName in nullifyMap)) {
|
|
2999
|
+
nullifyMap[objectName] = value === null ? getTableName2(field.table) : false;
|
|
3000
|
+
} else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName2(field.table)) {
|
|
3001
|
+
nullifyMap[objectName] = false;
|
|
3002
|
+
}
|
|
3003
|
+
continue;
|
|
3004
|
+
}
|
|
3005
|
+
if (joinsNotNullableMap && is10(field, SQL8.Aliased) && path.length === 2) {
|
|
3006
|
+
const col = field.sql.queryChunks.find((chunk) => is10(chunk, Column3));
|
|
3007
|
+
const tableName = col?.table && getTableName2(col?.table);
|
|
3008
|
+
if (!tableName) {
|
|
3009
|
+
continue;
|
|
3010
|
+
}
|
|
3011
|
+
const objectName = path[0];
|
|
3012
|
+
if (!(objectName in nullifyMap)) {
|
|
3013
|
+
nullifyMap[objectName] = value === null ? tableName : false;
|
|
3014
|
+
continue;
|
|
3015
|
+
}
|
|
3016
|
+
if (nullifyMap[objectName] && nullifyMap[objectName] !== tableName) {
|
|
3017
|
+
nullifyMap[objectName] = false;
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
return acc;
|
|
3022
|
+
},
|
|
3023
|
+
{}
|
|
3024
|
+
);
|
|
3025
|
+
if (joinsNotNullableMap && Object.keys(nullifyMap).length > 0) {
|
|
3026
|
+
for (const [objectName, tableName] of Object.entries(nullifyMap)) {
|
|
3027
|
+
if (typeof tableName === "string" && !joinsNotNullableMap[tableName]) {
|
|
3028
|
+
result[objectName] = null;
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
return result;
|
|
3033
|
+
}
|
|
3034
|
+
|
|
3035
|
+
// src/session.ts
|
|
3036
|
+
var DatabendPreparedQuery2 = class extends DatabendPreparedQuery {
|
|
3037
|
+
constructor(client, queryString, params, logger, fields, _isResponseInArrayMode, customResultMapper, typings) {
|
|
3038
|
+
super({ sql: queryString, params });
|
|
3039
|
+
this.client = client;
|
|
3040
|
+
this.queryString = queryString;
|
|
3041
|
+
this.params = params;
|
|
3042
|
+
this.logger = logger;
|
|
3043
|
+
this.fields = fields;
|
|
3044
|
+
this._isResponseInArrayMode = _isResponseInArrayMode;
|
|
3045
|
+
this.customResultMapper = customResultMapper;
|
|
3046
|
+
this.typings = typings;
|
|
3047
|
+
}
|
|
3048
|
+
static [entityKind35] = "DatabendPreparedQuery";
|
|
3049
|
+
async execute(placeholderValues = {}) {
|
|
3050
|
+
const params = fillPlaceholders(this.params, placeholderValues);
|
|
3051
|
+
this.logger.logQuery(this.queryString, params);
|
|
3052
|
+
const { fields, joinsNotNullableMap, customResultMapper, typings } = this;
|
|
3053
|
+
if (fields) {
|
|
3054
|
+
const { rows: rows2 } = await executeArraysOnClient(
|
|
3055
|
+
this.client,
|
|
3056
|
+
this.queryString,
|
|
3057
|
+
params,
|
|
3058
|
+
typings
|
|
3059
|
+
);
|
|
3060
|
+
if (rows2.length === 0) {
|
|
3061
|
+
return [];
|
|
3062
|
+
}
|
|
3063
|
+
return customResultMapper ? customResultMapper(rows2) : rows2.map(
|
|
3064
|
+
(row) => mapResultRow(fields, row, joinsNotNullableMap)
|
|
3065
|
+
);
|
|
3066
|
+
}
|
|
3067
|
+
const rows = await executeOnClient(this.client, this.queryString, params, typings);
|
|
3068
|
+
return rows;
|
|
3069
|
+
}
|
|
3070
|
+
all(placeholderValues = {}) {
|
|
3071
|
+
return this.execute(placeholderValues);
|
|
3072
|
+
}
|
|
3073
|
+
isResponseInArrayMode() {
|
|
3074
|
+
return this._isResponseInArrayMode;
|
|
3075
|
+
}
|
|
3076
|
+
};
|
|
3077
|
+
var DatabendSession2 = class _DatabendSession extends DatabendSession {
|
|
3078
|
+
constructor(client, dialect, schema, options = {}) {
|
|
3079
|
+
super(dialect);
|
|
3080
|
+
this.client = client;
|
|
3081
|
+
this.schema = schema;
|
|
3082
|
+
this.options = options;
|
|
3083
|
+
this.dialect = dialect;
|
|
3084
|
+
this.logger = options.logger ?? new NoopLogger();
|
|
3085
|
+
}
|
|
3086
|
+
static [entityKind35] = "DatabendSession";
|
|
3087
|
+
dialect;
|
|
3088
|
+
logger;
|
|
3089
|
+
rollbackOnly = false;
|
|
3090
|
+
prepareQuery(query, fields, name, isResponseInArrayMode, customResultMapper) {
|
|
3091
|
+
void name;
|
|
3092
|
+
return new DatabendPreparedQuery2(
|
|
3093
|
+
this.client,
|
|
3094
|
+
query.sql,
|
|
3095
|
+
query.params,
|
|
3096
|
+
this.logger,
|
|
3097
|
+
fields,
|
|
3098
|
+
isResponseInArrayMode,
|
|
3099
|
+
customResultMapper,
|
|
3100
|
+
query.typings
|
|
3101
|
+
);
|
|
3102
|
+
}
|
|
3103
|
+
async transaction(transaction, config) {
|
|
3104
|
+
let pinnedConnection;
|
|
3105
|
+
let pool;
|
|
3106
|
+
let clientForTx = this.client;
|
|
3107
|
+
if (isPool(this.client)) {
|
|
3108
|
+
pool = this.client;
|
|
3109
|
+
pinnedConnection = await pool.acquire();
|
|
3110
|
+
clientForTx = pinnedConnection;
|
|
3111
|
+
}
|
|
3112
|
+
const session = new _DatabendSession(
|
|
3113
|
+
clientForTx,
|
|
3114
|
+
this.dialect,
|
|
3115
|
+
this.schema,
|
|
3116
|
+
this.options
|
|
3117
|
+
);
|
|
3118
|
+
const tx = new DatabendTransaction2(
|
|
3119
|
+
this.dialect,
|
|
3120
|
+
session,
|
|
3121
|
+
this.schema
|
|
3122
|
+
);
|
|
3123
|
+
try {
|
|
3124
|
+
await tx.execute(sql7`BEGIN`);
|
|
3125
|
+
if (config) {
|
|
3126
|
+
await tx.setTransaction(config);
|
|
3127
|
+
}
|
|
3128
|
+
try {
|
|
3129
|
+
const result = await transaction(tx);
|
|
3130
|
+
if (session.isRollbackOnly()) {
|
|
3131
|
+
await tx.execute(sql7`ROLLBACK`);
|
|
3132
|
+
throw new TransactionRollbackError2();
|
|
3133
|
+
}
|
|
3134
|
+
await tx.execute(sql7`COMMIT`);
|
|
3135
|
+
return result;
|
|
3136
|
+
} catch (error) {
|
|
3137
|
+
await tx.execute(sql7`ROLLBACK`);
|
|
3138
|
+
throw error;
|
|
3139
|
+
}
|
|
3140
|
+
} finally {
|
|
3141
|
+
if (pinnedConnection && pool) {
|
|
3142
|
+
await pool.release(pinnedConnection);
|
|
3143
|
+
}
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
markRollbackOnly() {
|
|
3147
|
+
this.rollbackOnly = true;
|
|
3148
|
+
}
|
|
3149
|
+
isRollbackOnly() {
|
|
3150
|
+
return this.rollbackOnly;
|
|
3151
|
+
}
|
|
3152
|
+
};
|
|
3153
|
+
var VALID_TRANSACTION_ISOLATION_LEVELS = /* @__PURE__ */ new Set([
|
|
3154
|
+
"read uncommitted",
|
|
3155
|
+
"read committed",
|
|
3156
|
+
"repeatable read",
|
|
3157
|
+
"serializable"
|
|
3158
|
+
]);
|
|
3159
|
+
var VALID_TRANSACTION_ACCESS_MODES = /* @__PURE__ */ new Set([
|
|
3160
|
+
"read only",
|
|
3161
|
+
"read write"
|
|
3162
|
+
]);
|
|
3163
|
+
var DatabendTransaction2 = class _DatabendTransaction extends DatabendTransaction {
|
|
3164
|
+
static [entityKind35] = "DatabendTransaction";
|
|
3165
|
+
rollback() {
|
|
3166
|
+
throw new TransactionRollbackError2();
|
|
3167
|
+
}
|
|
3168
|
+
getTransactionConfigSQL(config) {
|
|
3169
|
+
if (config.isolationLevel && !VALID_TRANSACTION_ISOLATION_LEVELS.has(config.isolationLevel)) {
|
|
3170
|
+
throw new Error(
|
|
3171
|
+
`Invalid transaction isolation level "${config.isolationLevel}". Expected one of: ${Array.from(
|
|
3172
|
+
VALID_TRANSACTION_ISOLATION_LEVELS
|
|
3173
|
+
).join(", ")}.`
|
|
3174
|
+
);
|
|
3175
|
+
}
|
|
3176
|
+
if (config.accessMode && !VALID_TRANSACTION_ACCESS_MODES.has(config.accessMode)) {
|
|
3177
|
+
throw new Error(
|
|
3178
|
+
`Invalid transaction access mode "${config.accessMode}". Expected one of: ${Array.from(
|
|
3179
|
+
VALID_TRANSACTION_ACCESS_MODES
|
|
3180
|
+
).join(", ")}.`
|
|
3181
|
+
);
|
|
3182
|
+
}
|
|
3183
|
+
const chunks = [];
|
|
3184
|
+
if (config.isolationLevel) {
|
|
3185
|
+
chunks.push(`isolation level ${config.isolationLevel}`);
|
|
3186
|
+
}
|
|
3187
|
+
if (config.accessMode) {
|
|
3188
|
+
chunks.push(config.accessMode);
|
|
3189
|
+
}
|
|
3190
|
+
return sql7.raw(chunks.join(" "));
|
|
3191
|
+
}
|
|
3192
|
+
setTransaction(config) {
|
|
3193
|
+
return this.session.execute(
|
|
3194
|
+
sql7`SET TRANSACTION ${this.getTransactionConfigSQL(config)}`
|
|
3195
|
+
);
|
|
3196
|
+
}
|
|
3197
|
+
async transaction(transaction) {
|
|
3198
|
+
const internals = this;
|
|
3199
|
+
const nestedTx = new _DatabendTransaction(
|
|
3200
|
+
internals.dialect,
|
|
3201
|
+
internals.session,
|
|
3202
|
+
this.schema,
|
|
3203
|
+
this.nestedIndex + 1
|
|
3204
|
+
);
|
|
3205
|
+
return transaction(nestedTx).catch((error) => {
|
|
3206
|
+
internals.session.markRollbackOnly();
|
|
3207
|
+
throw error;
|
|
3208
|
+
});
|
|
3209
|
+
}
|
|
3210
|
+
};
|
|
3211
|
+
|
|
3212
|
+
// src/driver.ts
|
|
3213
|
+
var DatabendDriver = class {
|
|
3214
|
+
constructor(client, dialect, options = {}) {
|
|
3215
|
+
this.client = client;
|
|
3216
|
+
this.dialect = dialect;
|
|
3217
|
+
this.options = options;
|
|
3218
|
+
}
|
|
3219
|
+
static [entityKind36] = "DatabendDriver";
|
|
3220
|
+
createSession(schema) {
|
|
3221
|
+
return new DatabendSession2(this.client, this.dialect, schema, {
|
|
3222
|
+
logger: this.options.logger
|
|
3223
|
+
});
|
|
3224
|
+
}
|
|
3225
|
+
};
|
|
3226
|
+
function isConfigObject(data) {
|
|
3227
|
+
if (typeof data !== "object" || data === null) return false;
|
|
3228
|
+
if (data.constructor?.name !== "Object") return false;
|
|
3229
|
+
return "connection" in data || "client" in data || "pool" in data || "schema" in data || "logger" in data;
|
|
3230
|
+
}
|
|
3231
|
+
function createFromClient(client, config = {}, databendClient) {
|
|
3232
|
+
const dialect = new DatabendDialect();
|
|
3233
|
+
const logger = config.logger === true ? new DefaultLogger() : config.logger || void 0;
|
|
3234
|
+
let schema;
|
|
3235
|
+
if (config.schema) {
|
|
3236
|
+
const tablesConfig = extractTablesRelationalConfig(
|
|
3237
|
+
config.schema,
|
|
3238
|
+
createTableRelationsHelpers
|
|
3239
|
+
);
|
|
3240
|
+
schema = {
|
|
3241
|
+
fullSchema: config.schema,
|
|
3242
|
+
schema: tablesConfig.tables,
|
|
3243
|
+
tableNamesMap: tablesConfig.tableNamesMap
|
|
3244
|
+
};
|
|
3245
|
+
}
|
|
3246
|
+
const driver = new DatabendDriver(client, dialect, { logger });
|
|
3247
|
+
const session = driver.createSession(schema);
|
|
3248
|
+
const db = new DatabendDatabase2(
|
|
3249
|
+
dialect,
|
|
3250
|
+
session,
|
|
3251
|
+
schema,
|
|
3252
|
+
client,
|
|
3253
|
+
databendClient
|
|
3254
|
+
);
|
|
3255
|
+
return db;
|
|
3256
|
+
}
|
|
3257
|
+
async function createFromDsn(dsn, config = {}) {
|
|
3258
|
+
const databendClient = new Client(dsn);
|
|
3259
|
+
if (config.pool === false) {
|
|
3260
|
+
const connection = await databendClient.getConn();
|
|
3261
|
+
return createFromClient(connection, config, databendClient);
|
|
3262
|
+
}
|
|
3263
|
+
const poolSize = config.pool?.size ?? 4;
|
|
3264
|
+
const pool = createDatabendConnectionPool(databendClient, { size: poolSize });
|
|
3265
|
+
return createFromClient(pool, config, databendClient);
|
|
3266
|
+
}
|
|
3267
|
+
function drizzle(clientOrConfigOrDsn, config) {
|
|
3268
|
+
if (typeof clientOrConfigOrDsn === "string") {
|
|
3269
|
+
return createFromDsn(clientOrConfigOrDsn, config);
|
|
3270
|
+
}
|
|
3271
|
+
if (isConfigObject(clientOrConfigOrDsn)) {
|
|
3272
|
+
const configObj = clientOrConfigOrDsn;
|
|
3273
|
+
if ("connection" in configObj) {
|
|
3274
|
+
const connConfig = configObj;
|
|
3275
|
+
const { connection, ...restConfig } = connConfig;
|
|
3276
|
+
return createFromDsn(
|
|
3277
|
+
connection,
|
|
3278
|
+
restConfig
|
|
3279
|
+
);
|
|
3280
|
+
}
|
|
3281
|
+
if ("client" in configObj) {
|
|
3282
|
+
const clientConfig = configObj;
|
|
3283
|
+
const { client: clientValue, ...restConfig } = clientConfig;
|
|
3284
|
+
return createFromClient(
|
|
3285
|
+
clientValue,
|
|
3286
|
+
restConfig
|
|
3287
|
+
);
|
|
3288
|
+
}
|
|
3289
|
+
throw new Error(
|
|
3290
|
+
"Invalid drizzle config: either connection or client must be provided"
|
|
3291
|
+
);
|
|
3292
|
+
}
|
|
3293
|
+
return createFromClient(clientOrConfigOrDsn, config);
|
|
3294
|
+
}
|
|
3295
|
+
var DatabendDatabase2 = class extends DatabendDatabase {
|
|
3296
|
+
constructor(dialect, session, schema, client, databendClient) {
|
|
3297
|
+
super(dialect, session, schema);
|
|
3298
|
+
this.dialect = dialect;
|
|
3299
|
+
this.session = session;
|
|
3300
|
+
this.$client = client;
|
|
3301
|
+
this.$databendClient = databendClient;
|
|
3302
|
+
}
|
|
3303
|
+
static [entityKind36] = "DatabendDatabase";
|
|
3304
|
+
/** The underlying connection or pool */
|
|
3305
|
+
$client;
|
|
3306
|
+
/** The Databend Client instance (when created from DSN) */
|
|
3307
|
+
$databendClient;
|
|
3308
|
+
async close() {
|
|
3309
|
+
if (isPool(this.$client) && this.$client.close) {
|
|
3310
|
+
await this.$client.close();
|
|
3311
|
+
}
|
|
3312
|
+
if (!isPool(this.$client)) {
|
|
3313
|
+
await closeClientConnection(this.$client);
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
async transaction(transaction) {
|
|
3317
|
+
return await this.session.transaction(transaction);
|
|
3318
|
+
}
|
|
3319
|
+
};
|
|
3320
|
+
|
|
3321
|
+
// src/migrator.ts
|
|
3322
|
+
import { readMigrationFiles } from "drizzle-orm/migrator";
|
|
3323
|
+
async function migrate(db, config) {
|
|
3324
|
+
const migrationConfig = typeof config === "string" ? { migrationsFolder: config } : config;
|
|
3325
|
+
const migrations = readMigrationFiles(migrationConfig);
|
|
3326
|
+
await db.dialect.migrate(
|
|
3327
|
+
migrations,
|
|
3328
|
+
db.session,
|
|
3329
|
+
migrationConfig
|
|
3330
|
+
);
|
|
3331
|
+
}
|
|
3332
|
+
export {
|
|
3333
|
+
DatabendColumn,
|
|
3334
|
+
DatabendColumnBuilder,
|
|
3335
|
+
DatabendDatabase2 as DatabendDatabase,
|
|
3336
|
+
DatabendDialect,
|
|
3337
|
+
DatabendDriver,
|
|
3338
|
+
DatabendPreparedQuery2 as DatabendPreparedQuery,
|
|
3339
|
+
DatabendSession2 as DatabendSession,
|
|
3340
|
+
DatabendTable,
|
|
3341
|
+
DatabendTransaction2 as DatabendTransaction,
|
|
3342
|
+
alias,
|
|
3343
|
+
bigint,
|
|
3344
|
+
binary,
|
|
3345
|
+
bitmap,
|
|
3346
|
+
boolean,
|
|
3347
|
+
closeClientConnection,
|
|
3348
|
+
createDatabendConnectionPool,
|
|
3349
|
+
databendArray,
|
|
3350
|
+
databendDate,
|
|
3351
|
+
databendMap,
|
|
3352
|
+
databendSchema,
|
|
3353
|
+
databendTable,
|
|
3354
|
+
databendTableCreator,
|
|
3355
|
+
databendTimestamp,
|
|
3356
|
+
databendTuple,
|
|
3357
|
+
databendVariant,
|
|
3358
|
+
databendView,
|
|
3359
|
+
date,
|
|
3360
|
+
decimal,
|
|
3361
|
+
doublePrecision,
|
|
3362
|
+
drizzle,
|
|
3363
|
+
execOnClient,
|
|
3364
|
+
executeArraysOnClient,
|
|
3365
|
+
executeOnClient,
|
|
3366
|
+
float,
|
|
3367
|
+
getTableConfig,
|
|
3368
|
+
index,
|
|
3369
|
+
integer,
|
|
3370
|
+
isPool,
|
|
3371
|
+
migrate,
|
|
3372
|
+
prepareParams,
|
|
3373
|
+
primaryKey,
|
|
3374
|
+
real,
|
|
3375
|
+
smallint,
|
|
3376
|
+
text,
|
|
3377
|
+
timestamp,
|
|
3378
|
+
tinyint,
|
|
3379
|
+
uniqueIndex,
|
|
3380
|
+
varchar,
|
|
3381
|
+
variant
|
|
931
3382
|
};
|