drizzle-databend 0.1.11 → 0.1.13
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 +66 -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 +4 -4
- package/dist/index.d.ts +10 -0
- package/dist/index.mjs +2611 -205
- package/dist/session.d.ts +22 -19
- package/dist/sql/result-mapper.d.ts +2 -3
- package/dist/sql/selection.d.ts +2 -1
- package/package.json +4 -4
- 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 +725 -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 +412 -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 +6 -7
- package/src/index.ts +27 -0
- package/src/migrator.ts +1 -2
- package/src/session.ts +42 -57
- package/src/sql/result-mapper.ts +12 -54
- package/src/sql/selection.ts +2 -1
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { entityKind, is } from 'drizzle-orm/entity';
|
|
2
|
+
import { TypedQueryBuilder } from 'drizzle-orm/query-builders/query-builder';
|
|
3
|
+
import { QueryPromise } from 'drizzle-orm/query-promise';
|
|
4
|
+
import { SelectionProxyHandler } from 'drizzle-orm/selection-proxy';
|
|
5
|
+
import { SQL, View } from 'drizzle-orm/sql/sql';
|
|
6
|
+
import { Subquery } from 'drizzle-orm/subquery';
|
|
7
|
+
import { Table } from 'drizzle-orm/table';
|
|
8
|
+
// @ts-expect-error - tracer is exported at runtime but not in .d.ts
|
|
9
|
+
import { tracer } from 'drizzle-orm/tracing';
|
|
10
|
+
import {
|
|
11
|
+
// @ts-expect-error - exported at runtime but not in .d.ts
|
|
12
|
+
applyMixins,
|
|
13
|
+
getTableColumns,
|
|
14
|
+
// @ts-expect-error - exported at runtime but not in .d.ts
|
|
15
|
+
getTableLikeName,
|
|
16
|
+
haveSameKeys,
|
|
17
|
+
// @ts-expect-error - exported at runtime but not in .d.ts
|
|
18
|
+
orderSelectedFields,
|
|
19
|
+
} from 'drizzle-orm/utils';
|
|
20
|
+
import { ViewBaseConfig } from 'drizzle-orm/view-common';
|
|
21
|
+
import { DatabendColumn } from '../columns/common.ts';
|
|
22
|
+
import { DatabendViewBase } from '../view-base.ts';
|
|
23
|
+
|
|
24
|
+
export class DatabendSelectBuilder {
|
|
25
|
+
static readonly [entityKind]: string = 'DatabendSelectBuilder';
|
|
26
|
+
|
|
27
|
+
fields: any;
|
|
28
|
+
session: any;
|
|
29
|
+
dialect: any;
|
|
30
|
+
withList: any[] = [];
|
|
31
|
+
distinct: any;
|
|
32
|
+
|
|
33
|
+
constructor(config: any) {
|
|
34
|
+
this.fields = config.fields;
|
|
35
|
+
this.session = config.session;
|
|
36
|
+
this.dialect = config.dialect;
|
|
37
|
+
if (config.withList) {
|
|
38
|
+
this.withList = config.withList;
|
|
39
|
+
}
|
|
40
|
+
this.distinct = config.distinct;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
from(source: any): any {
|
|
44
|
+
const isPartialSelect = !!this.fields;
|
|
45
|
+
|
|
46
|
+
let fields: any;
|
|
47
|
+
if (this.fields) {
|
|
48
|
+
fields = this.fields;
|
|
49
|
+
} else if (is(source, Subquery)) {
|
|
50
|
+
fields = Object.fromEntries(
|
|
51
|
+
Object.keys(source._.selectedFields).map((key) => [key, (source as any)[key]])
|
|
52
|
+
);
|
|
53
|
+
} else if (is(source, DatabendViewBase)) {
|
|
54
|
+
fields = (source as any)[ViewBaseConfig].selectedFields;
|
|
55
|
+
} else if (is(source, SQL)) {
|
|
56
|
+
fields = {};
|
|
57
|
+
} else {
|
|
58
|
+
fields = getTableColumns(source);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return new DatabendSelectBase({
|
|
62
|
+
table: source,
|
|
63
|
+
fields,
|
|
64
|
+
isPartialSelect,
|
|
65
|
+
session: this.session,
|
|
66
|
+
dialect: this.dialect,
|
|
67
|
+
withList: this.withList,
|
|
68
|
+
distinct: this.distinct,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
class DatabendSelectQueryBuilderBase extends TypedQueryBuilder<any, any> {
|
|
74
|
+
static readonly [entityKind]: string = 'DatabendSelectQueryBuilder';
|
|
75
|
+
|
|
76
|
+
_: any;
|
|
77
|
+
config: any;
|
|
78
|
+
joinsNotNullableMap: any;
|
|
79
|
+
tableName: any;
|
|
80
|
+
isPartialSelect: any;
|
|
81
|
+
session: any;
|
|
82
|
+
dialect: any;
|
|
83
|
+
|
|
84
|
+
constructor({ table, fields, isPartialSelect, session, dialect, withList, distinct }: any) {
|
|
85
|
+
super();
|
|
86
|
+
this.config = {
|
|
87
|
+
withList,
|
|
88
|
+
table,
|
|
89
|
+
fields: { ...fields },
|
|
90
|
+
distinct,
|
|
91
|
+
setOperators: [],
|
|
92
|
+
};
|
|
93
|
+
this.isPartialSelect = isPartialSelect;
|
|
94
|
+
this.session = session;
|
|
95
|
+
this.dialect = dialect;
|
|
96
|
+
this._ = {
|
|
97
|
+
selectedFields: fields,
|
|
98
|
+
};
|
|
99
|
+
this.tableName = getTableLikeName(table);
|
|
100
|
+
this.joinsNotNullableMap = typeof this.tableName === 'string' ? { [this.tableName]: true } : {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private createJoin(joinType: string) {
|
|
104
|
+
return (table: any, on: any) => {
|
|
105
|
+
const baseTableName = this.tableName;
|
|
106
|
+
const tableName = getTableLikeName(table);
|
|
107
|
+
|
|
108
|
+
if (typeof tableName === 'string' && this.config.joins?.some((join: any) => join.alias === tableName)) {
|
|
109
|
+
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!this.isPartialSelect) {
|
|
113
|
+
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === 'string') {
|
|
114
|
+
this.config.fields = {
|
|
115
|
+
[baseTableName]: this.config.fields,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (typeof tableName === 'string' && !is(table, SQL)) {
|
|
119
|
+
const selection = is(table, Subquery)
|
|
120
|
+
? table._.selectedFields
|
|
121
|
+
: is(table, View)
|
|
122
|
+
? (table as any)[ViewBaseConfig].selectedFields
|
|
123
|
+
: table[(Table as any).Symbol.Columns];
|
|
124
|
+
this.config.fields[tableName] = selection;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (typeof on === 'function') {
|
|
129
|
+
on = on(
|
|
130
|
+
new Proxy(
|
|
131
|
+
this.config.fields,
|
|
132
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' })
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!this.config.joins) {
|
|
138
|
+
this.config.joins = [];
|
|
139
|
+
}
|
|
140
|
+
this.config.joins.push({ on, table, joinType, alias: tableName });
|
|
141
|
+
|
|
142
|
+
if (typeof tableName === 'string') {
|
|
143
|
+
switch (joinType) {
|
|
144
|
+
case 'left':
|
|
145
|
+
this.joinsNotNullableMap[tableName] = false;
|
|
146
|
+
break;
|
|
147
|
+
case 'right':
|
|
148
|
+
this.joinsNotNullableMap = Object.fromEntries(
|
|
149
|
+
Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
|
|
150
|
+
);
|
|
151
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
152
|
+
break;
|
|
153
|
+
case 'inner':
|
|
154
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
155
|
+
break;
|
|
156
|
+
case 'full':
|
|
157
|
+
this.joinsNotNullableMap = Object.fromEntries(
|
|
158
|
+
Object.entries(this.joinsNotNullableMap).map(([key]) => [key, false])
|
|
159
|
+
);
|
|
160
|
+
this.joinsNotNullableMap[tableName] = false;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return this;
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
leftJoin = this.createJoin('left');
|
|
169
|
+
rightJoin = this.createJoin('right');
|
|
170
|
+
innerJoin = this.createJoin('inner');
|
|
171
|
+
fullJoin = this.createJoin('full');
|
|
172
|
+
|
|
173
|
+
crossJoin = (table: any) => {
|
|
174
|
+
const baseTableName = this.tableName;
|
|
175
|
+
const tableName = getTableLikeName(table);
|
|
176
|
+
|
|
177
|
+
if (typeof tableName === 'string' && this.config.joins?.some((join: any) => join.alias === tableName)) {
|
|
178
|
+
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (!this.isPartialSelect) {
|
|
182
|
+
if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === 'string') {
|
|
183
|
+
this.config.fields = {
|
|
184
|
+
[baseTableName]: this.config.fields,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (typeof tableName === 'string' && !is(table, SQL)) {
|
|
188
|
+
const selection = is(table, Subquery)
|
|
189
|
+
? table._.selectedFields
|
|
190
|
+
: is(table, View)
|
|
191
|
+
? (table as any)[ViewBaseConfig].selectedFields
|
|
192
|
+
: table[(Table as any).Symbol.Columns];
|
|
193
|
+
this.config.fields[tableName] = selection;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!this.config.joins) {
|
|
198
|
+
this.config.joins = [];
|
|
199
|
+
}
|
|
200
|
+
this.config.joins.push({ on: undefined, table, joinType: 'cross', alias: tableName });
|
|
201
|
+
|
|
202
|
+
if (typeof tableName === 'string') {
|
|
203
|
+
this.joinsNotNullableMap[tableName] = true;
|
|
204
|
+
}
|
|
205
|
+
return this;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
private createSetOperator(type: string, isAll: boolean) {
|
|
209
|
+
return (rightSelection: any) => {
|
|
210
|
+
const rightSelect = typeof rightSelection === 'function'
|
|
211
|
+
? rightSelection(getDatabendSetOperators())
|
|
212
|
+
: rightSelection;
|
|
213
|
+
if (!haveSameKeys(this.getSelectedFields(), rightSelect.getSelectedFields())) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
'Set operator error (union / intersect / except): selected fields are not the same or are in a different order'
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
this.config.setOperators.push({ type, isAll, rightSelect });
|
|
219
|
+
return this;
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
union = this.createSetOperator('union', false);
|
|
224
|
+
unionAll = this.createSetOperator('union', true);
|
|
225
|
+
intersect = this.createSetOperator('intersect', false);
|
|
226
|
+
intersectAll = this.createSetOperator('intersect', true);
|
|
227
|
+
except = this.createSetOperator('except', false);
|
|
228
|
+
exceptAll = this.createSetOperator('except', true);
|
|
229
|
+
|
|
230
|
+
/** @internal */
|
|
231
|
+
addSetOperators(setOperators: any[]) {
|
|
232
|
+
this.config.setOperators.push(...setOperators);
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
where(where: any) {
|
|
237
|
+
if (typeof where === 'function') {
|
|
238
|
+
where = where(
|
|
239
|
+
new Proxy(
|
|
240
|
+
this.config.fields,
|
|
241
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' })
|
|
242
|
+
)
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
this.config.where = where;
|
|
246
|
+
return this;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
having(having: any) {
|
|
250
|
+
if (typeof having === 'function') {
|
|
251
|
+
having = having(
|
|
252
|
+
new Proxy(
|
|
253
|
+
this.config.fields,
|
|
254
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' })
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
this.config.having = having;
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
groupBy(...columns: any[]) {
|
|
263
|
+
if (typeof columns[0] === 'function') {
|
|
264
|
+
const groupBy = columns[0](
|
|
265
|
+
new Proxy(
|
|
266
|
+
this.config.fields,
|
|
267
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: 'alias', sqlBehavior: 'sql' })
|
|
268
|
+
)
|
|
269
|
+
);
|
|
270
|
+
this.config.groupBy = Array.isArray(groupBy) ? groupBy : [groupBy];
|
|
271
|
+
} else {
|
|
272
|
+
this.config.groupBy = columns;
|
|
273
|
+
}
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
orderBy(...columns: any[]) {
|
|
278
|
+
if (typeof columns[0] === 'function') {
|
|
279
|
+
const orderBy = columns[0](
|
|
280
|
+
new Proxy(
|
|
281
|
+
this.config.fields,
|
|
282
|
+
new SelectionProxyHandler({ sqlAliasedBehavior: 'alias', sqlBehavior: 'sql' })
|
|
283
|
+
)
|
|
284
|
+
);
|
|
285
|
+
const orderByArray = Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
286
|
+
if (this.config.setOperators.length > 0) {
|
|
287
|
+
this.config.setOperators.at(-1).orderBy = orderByArray;
|
|
288
|
+
} else {
|
|
289
|
+
this.config.orderBy = orderByArray;
|
|
290
|
+
}
|
|
291
|
+
} else {
|
|
292
|
+
const orderByArray = columns;
|
|
293
|
+
if (this.config.setOperators.length > 0) {
|
|
294
|
+
this.config.setOperators.at(-1).orderBy = orderByArray;
|
|
295
|
+
} else {
|
|
296
|
+
this.config.orderBy = orderByArray;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return this;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
limit(limit: any) {
|
|
303
|
+
if (this.config.setOperators.length > 0) {
|
|
304
|
+
this.config.setOperators.at(-1).limit = limit;
|
|
305
|
+
} else {
|
|
306
|
+
this.config.limit = limit;
|
|
307
|
+
}
|
|
308
|
+
return this;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
offset(offset: any) {
|
|
312
|
+
if (this.config.setOperators.length > 0) {
|
|
313
|
+
this.config.setOperators.at(-1).offset = offset;
|
|
314
|
+
} else {
|
|
315
|
+
this.config.offset = offset;
|
|
316
|
+
}
|
|
317
|
+
return this;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** @internal */
|
|
321
|
+
getSQL() {
|
|
322
|
+
return this.dialect.buildSelectQuery(this.config);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
toSQL() {
|
|
326
|
+
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
|
|
327
|
+
return rest;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
as(alias: string) {
|
|
331
|
+
return new Proxy(
|
|
332
|
+
new Subquery(this.getSQL(), this.config.fields, alias),
|
|
333
|
+
new SelectionProxyHandler({ alias, sqlAliasedBehavior: 'alias', sqlBehavior: 'error' })
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** @internal */
|
|
338
|
+
getSelectedFields() {
|
|
339
|
+
return new Proxy(
|
|
340
|
+
this.config.fields,
|
|
341
|
+
new SelectionProxyHandler({ alias: this.tableName, sqlAliasedBehavior: 'alias', sqlBehavior: 'error' })
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
$dynamic() {
|
|
346
|
+
return this;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export class DatabendSelectBase extends DatabendSelectQueryBuilderBase {
|
|
351
|
+
static override readonly [entityKind]: string = 'DatabendSelect';
|
|
352
|
+
|
|
353
|
+
/** @internal */
|
|
354
|
+
_prepare(name?: string) {
|
|
355
|
+
const { session, config, dialect, joinsNotNullableMap } = this;
|
|
356
|
+
if (!session) {
|
|
357
|
+
throw new Error('Cannot execute a query on a query builder. Please use a database instance instead.');
|
|
358
|
+
}
|
|
359
|
+
return tracer.startActiveSpan('drizzle.prepareQuery', () => {
|
|
360
|
+
const fieldsList = orderSelectedFields(config.fields);
|
|
361
|
+
const query = session.prepareQuery(dialect.sqlToQuery(this.getSQL()), fieldsList, name, true);
|
|
362
|
+
query.joinsNotNullableMap = joinsNotNullableMap;
|
|
363
|
+
return query;
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
prepare(name: string) {
|
|
368
|
+
return this._prepare(name);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
execute = (placeholderValues?: any) => {
|
|
372
|
+
return tracer.startActiveSpan('drizzle.operation', () => {
|
|
373
|
+
return this._prepare().execute(placeholderValues);
|
|
374
|
+
});
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
applyMixins(DatabendSelectBase, [QueryPromise]);
|
|
379
|
+
|
|
380
|
+
function createSetOperator(type: string, isAll: boolean) {
|
|
381
|
+
return (leftSelect: any, rightSelect: any, ...restSelects: any[]) => {
|
|
382
|
+
const setOperators = [rightSelect, ...restSelects].map((select) => ({
|
|
383
|
+
type,
|
|
384
|
+
isAll,
|
|
385
|
+
rightSelect: select,
|
|
386
|
+
}));
|
|
387
|
+
for (const setOperator of setOperators) {
|
|
388
|
+
if (!haveSameKeys(leftSelect.getSelectedFields(), setOperator.rightSelect.getSelectedFields())) {
|
|
389
|
+
throw new Error(
|
|
390
|
+
'Set operator error (union / intersect / except): selected fields are not the same or are in a different order'
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return leftSelect.addSetOperators(setOperators);
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const getDatabendSetOperators = () => ({
|
|
399
|
+
union,
|
|
400
|
+
unionAll,
|
|
401
|
+
intersect,
|
|
402
|
+
intersectAll,
|
|
403
|
+
except,
|
|
404
|
+
exceptAll,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
export const union = createSetOperator('union', false);
|
|
408
|
+
export const unionAll = createSetOperator('union', true);
|
|
409
|
+
export const intersect = createSetOperator('intersect', false);
|
|
410
|
+
export const intersectAll = createSetOperator('intersect', true);
|
|
411
|
+
export const except = createSetOperator('except', false);
|
|
412
|
+
export const exceptAll = createSetOperator('except', true);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { entityKind, is } from 'drizzle-orm/entity';
|
|
2
|
+
import { QueryPromise } from 'drizzle-orm/query-promise';
|
|
3
|
+
import { SQL } from 'drizzle-orm/sql/sql';
|
|
4
|
+
import { Table } from 'drizzle-orm/table';
|
|
5
|
+
// @ts-expect-error - tracer is exported at runtime but not in .d.ts
|
|
6
|
+
import { tracer } from 'drizzle-orm/tracing';
|
|
7
|
+
// @ts-expect-error - mapUpdateSet is exported at runtime but not in .d.ts
|
|
8
|
+
import { mapUpdateSet } from 'drizzle-orm/utils';
|
|
9
|
+
|
|
10
|
+
export class DatabendUpdateBuilder {
|
|
11
|
+
static readonly [entityKind]: string = 'DatabendUpdateBuilder';
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
private table: any,
|
|
15
|
+
private session: any,
|
|
16
|
+
private dialect: any,
|
|
17
|
+
private withList?: any[]
|
|
18
|
+
) {}
|
|
19
|
+
|
|
20
|
+
set(values: any) {
|
|
21
|
+
return new DatabendUpdateBase(
|
|
22
|
+
this.table,
|
|
23
|
+
mapUpdateSet(this.table, values),
|
|
24
|
+
this.session,
|
|
25
|
+
this.dialect,
|
|
26
|
+
this.withList
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class DatabendUpdateBase extends QueryPromise<any> {
|
|
32
|
+
static readonly [entityKind]: string = 'DatabendUpdate';
|
|
33
|
+
|
|
34
|
+
config: any;
|
|
35
|
+
|
|
36
|
+
constructor(
|
|
37
|
+
table: any,
|
|
38
|
+
set: any,
|
|
39
|
+
private session: any,
|
|
40
|
+
private dialect: any,
|
|
41
|
+
withList?: any[]
|
|
42
|
+
) {
|
|
43
|
+
super();
|
|
44
|
+
this.config = { set, table, withList };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
where(where: any) {
|
|
48
|
+
this.config.where = where;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @internal */
|
|
53
|
+
getSQL() {
|
|
54
|
+
return this.dialect.buildUpdateQuery(this.config);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
toSQL() {
|
|
58
|
+
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
|
|
59
|
+
return rest;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @internal */
|
|
63
|
+
_prepare(name?: string) {
|
|
64
|
+
return tracer.startActiveSpan('drizzle.prepareQuery', () => {
|
|
65
|
+
return this.session.prepareQuery(this.dialect.sqlToQuery(this.getSQL()), undefined, name, true);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
prepare(name: string) {
|
|
70
|
+
return this._prepare(name);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
execute = (placeholderValues?: any) => {
|
|
74
|
+
return tracer.startActiveSpan('drizzle.operation', () => {
|
|
75
|
+
return this._prepare().execute(placeholderValues);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
$dynamic() {
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { entityKind, is } from 'drizzle-orm/entity';
|
|
2
|
+
import { SQL, sql } from 'drizzle-orm/sql/sql';
|
|
3
|
+
import { databendTableWithSchema } from './table.ts';
|
|
4
|
+
|
|
5
|
+
export class DatabendSchema {
|
|
6
|
+
static readonly [entityKind]: string = 'DatabendSchema';
|
|
7
|
+
|
|
8
|
+
constructor(public schemaName: string) {}
|
|
9
|
+
|
|
10
|
+
table = (name: string, columns: any, extraConfig?: any): any => {
|
|
11
|
+
return databendTableWithSchema(name, columns, extraConfig, this.schemaName);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
getSQL(): SQL {
|
|
15
|
+
return new SQL([sql.identifier(this.schemaName)]);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
shouldOmitSQLParens() {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function isDatabendSchema(obj: unknown): obj is DatabendSchema {
|
|
24
|
+
return is(obj, DatabendSchema);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function databendSchema(name: string) {
|
|
28
|
+
return new DatabendSchema(name);
|
|
29
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { entityKind } from 'drizzle-orm/entity';
|
|
2
|
+
import { TransactionRollbackError } from 'drizzle-orm/errors';
|
|
3
|
+
// @ts-expect-error - tracer is exported at runtime but not in .d.ts
|
|
4
|
+
import { tracer } from 'drizzle-orm/tracing';
|
|
5
|
+
import { DatabendDatabase } from './db.ts';
|
|
6
|
+
|
|
7
|
+
export class DatabendPreparedQuery {
|
|
8
|
+
static readonly [entityKind]: string = 'DatabendPreparedQuery';
|
|
9
|
+
|
|
10
|
+
/** @internal */
|
|
11
|
+
joinsNotNullableMap: Record<string, boolean> | undefined;
|
|
12
|
+
|
|
13
|
+
constructor(public query: any) {}
|
|
14
|
+
|
|
15
|
+
getQuery() {
|
|
16
|
+
return this.query;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
mapResult(response: any, _isFromBatch?: boolean) {
|
|
20
|
+
return response;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class DatabendSession {
|
|
25
|
+
static readonly [entityKind]: string = 'DatabendSession';
|
|
26
|
+
|
|
27
|
+
constructor(public dialect: any) {}
|
|
28
|
+
|
|
29
|
+
execute(query: any): any {
|
|
30
|
+
return tracer.startActiveSpan('drizzle.operation', () => {
|
|
31
|
+
const prepared = tracer.startActiveSpan('drizzle.prepareQuery', () => {
|
|
32
|
+
return this.prepareQuery(
|
|
33
|
+
this.dialect.sqlToQuery(query),
|
|
34
|
+
undefined,
|
|
35
|
+
undefined,
|
|
36
|
+
false
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
return prepared.execute(undefined);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
all(query: any): any {
|
|
44
|
+
return this.prepareQuery(
|
|
45
|
+
this.dialect.sqlToQuery(query),
|
|
46
|
+
undefined,
|
|
47
|
+
undefined,
|
|
48
|
+
false
|
|
49
|
+
).all();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async count(sql: any): Promise<number> {
|
|
53
|
+
const res = await this.execute(sql);
|
|
54
|
+
return Number(res[0]['count']);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
prepareQuery(
|
|
58
|
+
_query: any,
|
|
59
|
+
_fields: any,
|
|
60
|
+
_name: any,
|
|
61
|
+
_isResponseInArrayMode: boolean,
|
|
62
|
+
_customResultMapper?: any
|
|
63
|
+
): any {
|
|
64
|
+
throw new Error('prepareQuery not implemented');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
transaction(_transaction: any, _config?: any): Promise<any> {
|
|
68
|
+
throw new Error('transaction not implemented');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class DatabendTransaction extends DatabendDatabase {
|
|
73
|
+
static override readonly [entityKind]: string = 'DatabendTransaction';
|
|
74
|
+
|
|
75
|
+
declare readonly schema: any;
|
|
76
|
+
|
|
77
|
+
constructor(dialect: any, session: any, schema: any, public nestedIndex = 0) {
|
|
78
|
+
super(dialect, session, schema);
|
|
79
|
+
this.schema = schema;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
rollback(): never {
|
|
83
|
+
throw new TransactionRollbackError();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Databend subquery types - re-exported from drizzle-orm core
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { entityKind } from 'drizzle-orm/entity';
|
|
2
|
+
import { Table } from 'drizzle-orm/table';
|
|
3
|
+
import { getDatabendColumnBuilders } from './columns/all.ts';
|
|
4
|
+
|
|
5
|
+
export class DatabendTable extends Table {
|
|
6
|
+
static readonly [entityKind]: string = 'DatabendTable';
|
|
7
|
+
|
|
8
|
+
/** @internal */
|
|
9
|
+
static Symbol = Object.assign({}, (Table as any).Symbol, {});
|
|
10
|
+
|
|
11
|
+
constructor(name: string, schema: string | undefined, baseName: string) {
|
|
12
|
+
super(name, schema, baseName);
|
|
13
|
+
(this as any)[(Table as any).Symbol.ExtraConfigBuilder] = undefined;
|
|
14
|
+
(this as any)[(Table as any).Symbol.ExtraConfigColumns] = {};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function databendTableWithSchema(
|
|
19
|
+
name: string,
|
|
20
|
+
columns: any,
|
|
21
|
+
extraConfig: any,
|
|
22
|
+
schema: string | undefined,
|
|
23
|
+
baseName = name
|
|
24
|
+
): any {
|
|
25
|
+
const rawTable = new DatabendTable(name, schema, baseName);
|
|
26
|
+
const parsedColumns = typeof columns === 'function' ? columns(getDatabendColumnBuilders()) : columns;
|
|
27
|
+
|
|
28
|
+
const builtColumns = Object.fromEntries(
|
|
29
|
+
Object.entries(parsedColumns).map(([name, colBuilderBase]: [string, any]) => {
|
|
30
|
+
const colBuilder = colBuilderBase;
|
|
31
|
+
colBuilder.setName(name);
|
|
32
|
+
const column = colBuilder.build(rawTable);
|
|
33
|
+
return [name, column];
|
|
34
|
+
})
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const builtColumnsForExtraConfig = Object.fromEntries(
|
|
38
|
+
Object.entries(parsedColumns).map(([name, colBuilderBase]: [string, any]) => {
|
|
39
|
+
const colBuilder = colBuilderBase;
|
|
40
|
+
colBuilder.setName(name);
|
|
41
|
+
const column = colBuilder.buildExtraConfigColumn(rawTable);
|
|
42
|
+
return [name, column];
|
|
43
|
+
})
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const table = Object.assign(rawTable, builtColumns);
|
|
47
|
+
table[(Table as any).Symbol.Columns] = builtColumns;
|
|
48
|
+
table[(Table as any).Symbol.ExtraConfigColumns] = builtColumnsForExtraConfig;
|
|
49
|
+
|
|
50
|
+
if (extraConfig) {
|
|
51
|
+
table[(DatabendTable as any).Symbol.ExtraConfigBuilder] = extraConfig;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return table;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const databendTable = (name: string, columns: any, extraConfig?: any): any => {
|
|
58
|
+
return databendTableWithSchema(name, columns, extraConfig, undefined);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export function databendTableCreator(customizeTableName: (name: string) => string) {
|
|
62
|
+
return (name: string, columns: any, extraConfig?: any) => {
|
|
63
|
+
return databendTableWithSchema(customizeTableName(name), columns, extraConfig, undefined, name);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { databendTableWithSchema };
|