rado 1.2.1 → 1.3.0-preview.1
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/README.md +163 -257
- package/dist/compat.d.ts +3 -0
- package/dist/core/Builder.d.ts +16 -9
- package/dist/core/Builder.js +52 -4
- package/dist/core/Column.d.ts +25 -21
- package/dist/core/Column.js +39 -23
- package/dist/core/Constraint.d.ts +2 -1
- package/dist/core/Constraint.js +2 -1
- package/dist/core/Database.d.ts +5 -4
- package/dist/core/Database.js +14 -13
- package/dist/core/Emitter.d.ts +2 -2
- package/dist/core/Index.d.ts +1 -1
- package/dist/core/Internal.d.ts +19 -2
- package/dist/core/Internal.js +29 -11
- package/dist/core/Param.js +2 -0
- package/dist/core/Queries.d.ts +1 -0
- package/dist/core/Queries.js +11 -1
- package/dist/core/Resolver.js +2 -2
- package/dist/core/Schema.d.ts +1 -3
- package/dist/core/Selection.d.ts +9 -4
- package/dist/core/Selection.js +94 -5
- package/dist/core/Sql.d.ts +4 -3
- package/dist/core/Sql.js +8 -2
- package/dist/core/Table.d.ts +18 -11
- package/dist/core/Table.js +45 -25
- package/dist/core/View.d.ts +34 -0
- package/dist/core/View.js +153 -0
- package/dist/core/Virtual.d.ts +7 -2
- package/dist/core/Virtual.js +14 -10
- package/dist/core/expr/Conditions.d.ts +7 -7
- package/dist/core/expr/Include.d.ts +4 -4
- package/dist/core/expr/Include.js +2 -2
- package/dist/core/expr/Input.d.ts +1 -1
- package/dist/core/expr/Input.js +5 -1
- package/dist/core/query/CTE.d.ts +3 -5
- package/dist/core/query/CTE.js +1 -13
- package/dist/core/query/Delete.d.ts +10 -10
- package/dist/core/query/Delete.js +2 -2
- package/dist/core/query/Insert.d.ts +6 -5
- package/dist/core/query/Insert.js +22 -9
- package/dist/core/query/Query.d.ts +26 -11
- package/dist/core/query/Select.d.ts +41 -8
- package/dist/core/query/Select.js +235 -25
- package/dist/core/query/Shared.d.ts +2 -1
- package/dist/core/query/Shared.js +8 -5
- package/dist/core/query/Update.d.ts +9 -9
- package/dist/core/query/Update.js +24 -12
- package/dist/driver/better-sqlite3.js +4 -0
- package/dist/driver/bun-sqlite.js +3 -0
- package/dist/driver/d1.js +3 -0
- package/dist/driver/libsql.js +4 -0
- package/dist/driver/mysql2.js +5 -0
- package/dist/driver/pg.d.ts +17 -1
- package/dist/driver/pg.js +10 -1
- package/dist/driver/pglite.js +21 -6
- package/dist/driver/sql.js.js +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mysql/columns.d.ts +30 -30
- package/dist/mysql/columns.js +25 -24
- package/dist/mysql/dialect.js +6 -2
- package/dist/mysql/diff.js +1 -1
- package/dist/mysql.d.ts +1 -0
- package/dist/mysql.js +2 -0
- package/dist/postgres/columns.d.ts +103 -33
- package/dist/postgres/columns.js +317 -35
- package/dist/postgres/diff.js +3 -3
- package/dist/postgres/enum.d.ts +17 -0
- package/dist/postgres/enum.js +64 -0
- package/dist/postgres/schema.d.ts +19 -0
- package/dist/postgres/schema.js +47 -0
- package/dist/postgres.d.ts +3 -1
- package/dist/postgres.js +9 -2
- package/dist/sqlite/columns.d.ts +29 -14
- package/dist/sqlite/columns.js +41 -9
- package/dist/sqlite/dialect.js +3 -1
- package/dist/sqlite/diff.js +1 -1
- package/dist/sqlite/functions.d.ts +1 -1
- package/dist/sqlite/functions.js +1 -1
- package/dist/sqlite.d.ts +1 -0
- package/dist/sqlite.js +3 -6
- package/dist/universal/columns.d.ts +8 -8
- package/dist/universal/columns.js +10 -9
- package/dist/universal/functions.d.ts +1 -1
- package/dist/universal/functions.js +1 -1
- package/package.json +57 -38
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// src/core/query/Select.ts
|
|
2
|
+
import { and } from "../expr/Conditions.js";
|
|
2
3
|
import {
|
|
3
4
|
getData,
|
|
5
|
+
getField,
|
|
4
6
|
getQuery,
|
|
5
7
|
getSelection,
|
|
6
8
|
getSql,
|
|
9
|
+
getTable,
|
|
7
10
|
getTarget,
|
|
11
|
+
hasField,
|
|
8
12
|
hasSelection,
|
|
9
13
|
hasSql,
|
|
14
|
+
hasTable,
|
|
10
15
|
hasTarget,
|
|
11
16
|
internalData,
|
|
12
17
|
internalQuery,
|
|
@@ -19,9 +24,23 @@ import {
|
|
|
19
24
|
selection
|
|
20
25
|
} from "../Selection.js";
|
|
21
26
|
import { Sql, sql } from "../Sql.js";
|
|
22
|
-
import { and } from "../expr/Conditions.js";
|
|
23
27
|
import { formatCTE } from "./CTE.js";
|
|
24
28
|
import { formatModifiers } from "./Shared.js";
|
|
29
|
+
function isUnionQuery(query) {
|
|
30
|
+
return Array.isArray(query.select);
|
|
31
|
+
}
|
|
32
|
+
function mapScalarSelection(query, selected) {
|
|
33
|
+
if (hasSql(selected)) return query.mapWith(getSql(selected));
|
|
34
|
+
if (selected && typeof selected === "object") {
|
|
35
|
+
const values = Object.values(selected);
|
|
36
|
+
if (values.length === 1) {
|
|
37
|
+
const first = values[0];
|
|
38
|
+
if (first && typeof first === "object" && hasSql(first))
|
|
39
|
+
return query.mapWith(getSql(first));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return query;
|
|
43
|
+
}
|
|
25
44
|
var SelectFirst = class extends SingleQuery {
|
|
26
45
|
[internalData];
|
|
27
46
|
constructor(data) {
|
|
@@ -36,7 +55,10 @@ var SelectFirst = class extends SingleQuery {
|
|
|
36
55
|
return selectQuery(getData(this));
|
|
37
56
|
}
|
|
38
57
|
get [internalSql]() {
|
|
39
|
-
return
|
|
58
|
+
return mapScalarSelection(
|
|
59
|
+
sql`(${getQuery(this)})`,
|
|
60
|
+
getSelection(this).input
|
|
61
|
+
);
|
|
40
62
|
}
|
|
41
63
|
};
|
|
42
64
|
var UnionBase = class extends SingleQuery {
|
|
@@ -46,9 +68,14 @@ var UnionBase = class extends SingleQuery {
|
|
|
46
68
|
this[internalData] = data;
|
|
47
69
|
}
|
|
48
70
|
as(alias) {
|
|
49
|
-
const
|
|
50
|
-
|
|
71
|
+
const selected = getSelection(this);
|
|
72
|
+
const fields = selected.makeVirtual(alias);
|
|
73
|
+
return Object.assign({}, fields, {
|
|
51
74
|
[internalSelection]: selection(fields),
|
|
75
|
+
[internalSql]: mapScalarSelection(
|
|
76
|
+
sql`(${getQuery(this)})`,
|
|
77
|
+
selected.input
|
|
78
|
+
),
|
|
52
79
|
[internalTarget]: sql`(${getQuery(this)}) as ${sql.identifier(
|
|
53
80
|
alias
|
|
54
81
|
)}`.inlineFields(true)
|
|
@@ -63,15 +90,73 @@ var UnionBase = class extends SingleQuery {
|
|
|
63
90
|
if (!("compound" in data)) throw new Error("No compound defined");
|
|
64
91
|
return data.compound;
|
|
65
92
|
}
|
|
93
|
+
#selectFields(select) {
|
|
94
|
+
return querySelection(select).fieldNames();
|
|
95
|
+
}
|
|
96
|
+
#segmentSelect(segment) {
|
|
97
|
+
const query = segment;
|
|
98
|
+
if (isUnionQuery(query)) return query.select[0];
|
|
99
|
+
if ("union" in segment) return this.#segmentSelect(segment.union);
|
|
100
|
+
if ("unionAll" in segment) return this.#segmentSelect(segment.unionAll);
|
|
101
|
+
if ("intersect" in segment) return this.#segmentSelect(segment.intersect);
|
|
102
|
+
if ("intersectAll" in segment)
|
|
103
|
+
return this.#segmentSelect(segment.intersectAll);
|
|
104
|
+
if ("except" in segment) return this.#segmentSelect(segment.except);
|
|
105
|
+
if ("exceptAll" in segment) return this.#segmentSelect(segment.exceptAll);
|
|
106
|
+
return segment;
|
|
107
|
+
}
|
|
108
|
+
#unionSegment(op, query) {
|
|
109
|
+
switch (op) {
|
|
110
|
+
case "union":
|
|
111
|
+
return { union: query };
|
|
112
|
+
case "unionAll":
|
|
113
|
+
return { unionAll: query };
|
|
114
|
+
case "intersect":
|
|
115
|
+
return { intersect: query };
|
|
116
|
+
case "intersectAll":
|
|
117
|
+
return { intersectAll: query };
|
|
118
|
+
case "except":
|
|
119
|
+
return { except: query };
|
|
120
|
+
case "exceptAll":
|
|
121
|
+
return { exceptAll: query };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
#assertMatchingFields(left, right) {
|
|
125
|
+
const fields = this.#selectFields(left[0]);
|
|
126
|
+
const assert = (query) => {
|
|
127
|
+
const names = this.#selectFields(query);
|
|
128
|
+
if (fields.length !== names.length)
|
|
129
|
+
throw new Error("Union segments must have the same fields");
|
|
130
|
+
for (let i = 0; i < fields.length; i++)
|
|
131
|
+
if (fields[i] !== names[i])
|
|
132
|
+
throw new Error("Union segments must have the same fields");
|
|
133
|
+
};
|
|
134
|
+
for (const segment of left.slice(1)) assert(this.#segmentSelect(segment));
|
|
135
|
+
for (const segment of right) assert(this.#segmentSelect(segment));
|
|
136
|
+
}
|
|
137
|
+
#appendCompound(left, op, right) {
|
|
138
|
+
const [firstRight, ...restRight] = right.select;
|
|
139
|
+
if (restRight.length === 0)
|
|
140
|
+
return [...left, this.#unionSegment(op, firstRight)];
|
|
141
|
+
return [...left, this.#unionSegment(op, right)];
|
|
142
|
+
}
|
|
66
143
|
#compound(op, target) {
|
|
67
144
|
const left = this.#getSelect(this);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
);
|
|
71
|
-
const
|
|
72
|
-
|
|
145
|
+
const rightBase = typeof target === "function" ? target(this.#makeSelf()) : target;
|
|
146
|
+
const rightData = getData(rightBase);
|
|
147
|
+
const rightSelect = this.#getSelect(rightBase);
|
|
148
|
+
const right = { ...rightData, select: rightSelect };
|
|
149
|
+
this.#assertMatchingFields(left, rightSelect);
|
|
150
|
+
const select = this.#appendCompound(left, op, right);
|
|
151
|
+
const {
|
|
152
|
+
resolver,
|
|
153
|
+
with: withDefs,
|
|
154
|
+
withRecursive
|
|
155
|
+
} = getData(this);
|
|
73
156
|
return new Union({
|
|
74
|
-
|
|
157
|
+
resolver,
|
|
158
|
+
with: withDefs,
|
|
159
|
+
withRecursive,
|
|
75
160
|
select
|
|
76
161
|
});
|
|
77
162
|
}
|
|
@@ -94,6 +179,7 @@ var UnionBase = class extends SingleQuery {
|
|
|
94
179
|
return this.#compound("exceptAll", target);
|
|
95
180
|
}
|
|
96
181
|
};
|
|
182
|
+
var forKeywords = ["update", "no key update", "share", "key share"];
|
|
97
183
|
var Select = class _Select extends UnionBase {
|
|
98
184
|
[internalData];
|
|
99
185
|
constructor(data) {
|
|
@@ -105,6 +191,18 @@ var Select = class _Select extends UnionBase {
|
|
|
105
191
|
from(from) {
|
|
106
192
|
return new _Select({ ...getData(this), from });
|
|
107
193
|
}
|
|
194
|
+
for(keyword, config = {}) {
|
|
195
|
+
if (!forKeywords.includes(keyword))
|
|
196
|
+
throw new Error(`Invalid FOR keyword: ${keyword}`);
|
|
197
|
+
return new _Select({
|
|
198
|
+
...getData(this),
|
|
199
|
+
for: sql.query(sql.unsafe(keyword), {
|
|
200
|
+
of: config.of && sql.join([config.of].flat().map(getTarget), sql`, `),
|
|
201
|
+
nowait: config.noWait,
|
|
202
|
+
skipLocked: config.skipLocked
|
|
203
|
+
})
|
|
204
|
+
});
|
|
205
|
+
}
|
|
108
206
|
#fromTarget() {
|
|
109
207
|
const { from } = getData(this);
|
|
110
208
|
if (!from) throw new Error("No target defined");
|
|
@@ -117,17 +215,26 @@ var Select = class _Select extends UnionBase {
|
|
|
117
215
|
leftJoin(leftJoin, on) {
|
|
118
216
|
return this.#join({ leftJoin, on });
|
|
119
217
|
}
|
|
218
|
+
leftJoinLateral(leftJoinLateral, on) {
|
|
219
|
+
return this.#join({ leftJoinLateral, on });
|
|
220
|
+
}
|
|
120
221
|
rightJoin(rightJoin, on) {
|
|
121
222
|
return this.#join({ rightJoin, on });
|
|
122
223
|
}
|
|
123
224
|
innerJoin(innerJoin, on) {
|
|
124
225
|
return this.#join({ innerJoin, on });
|
|
125
226
|
}
|
|
227
|
+
innerJoinLateral(innerJoinLateral, on) {
|
|
228
|
+
return this.#join({ innerJoinLateral, on });
|
|
229
|
+
}
|
|
126
230
|
fullJoin(fullJoin, on) {
|
|
127
231
|
return this.#join({ fullJoin, on });
|
|
128
232
|
}
|
|
129
|
-
crossJoin(crossJoin
|
|
130
|
-
return this.#join({ crossJoin
|
|
233
|
+
crossJoin(crossJoin) {
|
|
234
|
+
return this.#join({ crossJoin });
|
|
235
|
+
}
|
|
236
|
+
crossJoinLateral(crossJoinLateral) {
|
|
237
|
+
return this.#join({ crossJoinLateral });
|
|
131
238
|
}
|
|
132
239
|
where(...where) {
|
|
133
240
|
return new _Select({ ...getData(this), where: and(...where) });
|
|
@@ -163,17 +270,101 @@ var Select = class _Select extends UnionBase {
|
|
|
163
270
|
return sql`(${getQuery(this)})`;
|
|
164
271
|
}
|
|
165
272
|
};
|
|
273
|
+
function collectReferencedTargets(input, names) {
|
|
274
|
+
if (hasSql(input)) {
|
|
275
|
+
if (hasField(input)) {
|
|
276
|
+
const field = getField(input);
|
|
277
|
+
const source = field.source;
|
|
278
|
+
if (!(source && typeof source === "object" && hasSql(source)))
|
|
279
|
+
names.add(field.targetName);
|
|
280
|
+
}
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (!input || typeof input !== "object") return;
|
|
284
|
+
for (const value of Object.values(input))
|
|
285
|
+
collectReferencedTargets(value, names);
|
|
286
|
+
}
|
|
287
|
+
function collectFromTargets(from, names) {
|
|
288
|
+
if (!from) return;
|
|
289
|
+
const collect = (target) => {
|
|
290
|
+
if (hasTable(target)) {
|
|
291
|
+
names.add(getTable(target).aliased);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (!hasSelection(target)) return;
|
|
295
|
+
collectReferencedTargets(getSelection(target).input, names);
|
|
296
|
+
};
|
|
297
|
+
if (Array.isArray(from)) {
|
|
298
|
+
for (const entry of from) {
|
|
299
|
+
if (hasTarget(entry)) collect(entry);
|
|
300
|
+
else if (!hasSql(entry)) {
|
|
301
|
+
const { target } = joinOp(entry);
|
|
302
|
+
if (hasTarget(target)) collect(target);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (hasTarget(from)) collect(from);
|
|
308
|
+
}
|
|
309
|
+
function hasUnnamedDerivedSource(input) {
|
|
310
|
+
if (hasField(input)) {
|
|
311
|
+
const source = getField(input).source;
|
|
312
|
+
if (source && typeof source === "object" && hasSql(source)) {
|
|
313
|
+
const sourceSql = source;
|
|
314
|
+
if (!hasField(sourceSql) && !getSql(sourceSql).alias) return true;
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
if (hasSql(input)) return false;
|
|
319
|
+
if (!input || typeof input !== "object") return false;
|
|
320
|
+
return Object.values(input).some(
|
|
321
|
+
hasUnnamedDerivedSource
|
|
322
|
+
);
|
|
323
|
+
}
|
|
166
324
|
function querySelection({ select, from }) {
|
|
167
|
-
if (select)
|
|
325
|
+
if (select) {
|
|
326
|
+
if (from) {
|
|
327
|
+
const selectedTargets = /* @__PURE__ */ new Set();
|
|
328
|
+
const fromTargets = /* @__PURE__ */ new Set();
|
|
329
|
+
collectReferencedTargets(select, selectedTargets);
|
|
330
|
+
collectFromTargets(from, fromTargets);
|
|
331
|
+
if (fromTargets.size > 0) {
|
|
332
|
+
for (const targetName of selectedTargets)
|
|
333
|
+
if (!fromTargets.has(targetName))
|
|
334
|
+
throw new Error(`Unknown target in select: ${targetName}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (hasSql(select) && hasSelection(select)) {
|
|
338
|
+
const selected = getSelection(select);
|
|
339
|
+
if (!from || !Array.isArray(from)) return selected;
|
|
340
|
+
const [, ...joins2] = from;
|
|
341
|
+
return applyJoins(selected, joins2);
|
|
342
|
+
}
|
|
343
|
+
if (!from || !Array.isArray(from))
|
|
344
|
+
return selection(select);
|
|
345
|
+
const [, ...joins] = from;
|
|
346
|
+
return applyJoins(selection(select), joins);
|
|
347
|
+
}
|
|
168
348
|
if (!from) throw new Error("No selection defined");
|
|
169
349
|
if (Array.isArray(from)) {
|
|
170
350
|
const [target, ...joins] = from;
|
|
171
|
-
return
|
|
172
|
-
const { target: target2, op } = joinOp(join);
|
|
173
|
-
return result.join(target2, op);
|
|
174
|
-
}, selection(target));
|
|
351
|
+
return applyJoins(selection(target), joins);
|
|
175
352
|
}
|
|
176
|
-
|
|
353
|
+
if (hasSelection(from)) {
|
|
354
|
+
const selected = getSelection(from);
|
|
355
|
+
if (hasUnnamedDerivedSource(selected.input))
|
|
356
|
+
throw new Error("Cannot select all from subquery without alias");
|
|
357
|
+
return selected;
|
|
358
|
+
}
|
|
359
|
+
return selection(sql`*`);
|
|
360
|
+
}
|
|
361
|
+
function applyJoins(base, joins) {
|
|
362
|
+
let current = base;
|
|
363
|
+
for (const join of joins) {
|
|
364
|
+
const { target, op } = joinOp(join);
|
|
365
|
+
current = current.join(target, op);
|
|
366
|
+
}
|
|
367
|
+
return current;
|
|
177
368
|
}
|
|
178
369
|
function joinOp(join) {
|
|
179
370
|
const { on, ...rest } = join;
|
|
@@ -181,22 +372,26 @@ function joinOp(join) {
|
|
|
181
372
|
const target = rest[op];
|
|
182
373
|
return { target, op, on };
|
|
183
374
|
}
|
|
375
|
+
function formatTarget(target) {
|
|
376
|
+
if (hasTable(target)) return getTable(target).target();
|
|
377
|
+
return getTarget(target);
|
|
378
|
+
}
|
|
184
379
|
function formatFrom(from) {
|
|
185
380
|
if (!from) throw new Error("No target defined");
|
|
186
381
|
if (Array.isArray(from)) {
|
|
187
382
|
return sql.join(
|
|
188
383
|
from.map((join) => {
|
|
189
|
-
if (hasTarget(join)) return
|
|
384
|
+
if (hasTarget(join)) return formatTarget(join);
|
|
190
385
|
if (hasSql(join)) return getSql(join);
|
|
191
386
|
const { target, op, on } = joinOp(join);
|
|
192
387
|
return sql.query({
|
|
193
|
-
[op]: hasTarget(target) ?
|
|
388
|
+
[op]: hasTarget(target) ? formatTarget(target) : getSql(target),
|
|
194
389
|
on
|
|
195
390
|
});
|
|
196
391
|
})
|
|
197
392
|
);
|
|
198
393
|
}
|
|
199
|
-
return hasTarget(from) ?
|
|
394
|
+
return hasTarget(from) ? formatTarget(from) : getSql(from);
|
|
200
395
|
}
|
|
201
396
|
function selectQuery(query) {
|
|
202
397
|
const { from, where, groupBy, having, distinct, distinctOn } = query;
|
|
@@ -208,11 +403,12 @@ function selectQuery(query) {
|
|
|
208
403
|
{
|
|
209
404
|
select,
|
|
210
405
|
from: from && formatFrom(from),
|
|
406
|
+
for: query.for,
|
|
211
407
|
where,
|
|
212
408
|
groupBy: groupBy && sql.join(groupBy, sql`, `),
|
|
213
409
|
having: typeof having === "function" ? having(selected.input) : having
|
|
214
410
|
},
|
|
215
|
-
formatModifiers(query)
|
|
411
|
+
formatModifiers(query, selected)
|
|
216
412
|
);
|
|
217
413
|
}
|
|
218
414
|
var Union = class _Union extends UnionBase {
|
|
@@ -281,19 +477,33 @@ function exceptAll(left, right, ...rest) {
|
|
|
281
477
|
function unionQuery(query) {
|
|
282
478
|
const { select } = query;
|
|
283
479
|
let fields;
|
|
480
|
+
const firstSelect = (query2) => isUnionQuery(query2) ? query2.select[0] : query2;
|
|
481
|
+
const segmentQuery = (query2) => {
|
|
482
|
+
if (isUnionQuery(query2)) {
|
|
483
|
+
const nested = unionQuery(query2);
|
|
484
|
+
return sql.universal({
|
|
485
|
+
sqlite: sql`select * from (${nested})`,
|
|
486
|
+
default: sql`(${nested})`
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
const inner = selectQuery(query2);
|
|
490
|
+
return query2.orderBy || query2.limit !== void 0 || query2.offset !== void 0 ? sql`(${inner})` : inner;
|
|
491
|
+
};
|
|
284
492
|
const segments = sql.join(
|
|
285
493
|
select.map((segment, i) => {
|
|
286
494
|
if (i === 0) {
|
|
287
495
|
fields = querySelection(segment).fieldNames();
|
|
288
|
-
return
|
|
496
|
+
return segmentQuery(segment);
|
|
289
497
|
}
|
|
290
498
|
const op = Object.keys(segment)[0];
|
|
291
499
|
const query2 = segment[op];
|
|
292
|
-
const names = querySelection(query2).fieldNames();
|
|
500
|
+
const names = querySelection(firstSelect(query2)).fieldNames();
|
|
501
|
+
if (fields.length !== names.length)
|
|
502
|
+
throw new Error("Union segments must have the same fields");
|
|
293
503
|
for (let i2 = 0; i2 < fields.length; i2++)
|
|
294
504
|
if (fields[i2] !== names[i2])
|
|
295
505
|
throw new Error("Union segments must have the same fields");
|
|
296
|
-
return sql.query({ [op]:
|
|
506
|
+
return sql.query({ [op]: segmentQuery(query2) });
|
|
297
507
|
})
|
|
298
508
|
);
|
|
299
509
|
return sql.query(formatCTE(query), segments, formatModifiers(query));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Selection } from '../Selection.js';
|
|
1
2
|
import { type Sql } from '../Sql.js';
|
|
2
3
|
import type { ResultModifiers } from './Query.js';
|
|
3
|
-
export declare function formatModifiers(modifiers: ResultModifiers): Sql | undefined;
|
|
4
|
+
export declare function formatModifiers(modifiers: ResultModifiers, selected?: Selection): Sql | undefined;
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
// src/core/query/Shared.ts
|
|
2
|
+
import { input } from "../expr/Input.js";
|
|
2
3
|
import { getSql } from "../Internal.js";
|
|
3
4
|
import { sql } from "../Sql.js";
|
|
4
|
-
|
|
5
|
-
function formatModifiers(modifiers) {
|
|
5
|
+
function formatModifiers(modifiers, selected) {
|
|
6
6
|
const { orderBy, limit, offset } = modifiers;
|
|
7
|
-
|
|
7
|
+
const normalizedLimit = typeof limit === "number" && limit < 0 ? void 0 : limit;
|
|
8
|
+
if (!orderBy && normalizedLimit === void 0 && offset === void 0)
|
|
9
|
+
return void 0;
|
|
8
10
|
return sql.query({
|
|
9
11
|
orderBy: orderBy && sql.join(
|
|
10
12
|
orderBy.map((part) => {
|
|
11
|
-
const
|
|
13
|
+
const inner = getSql(part);
|
|
14
|
+
const alias = selected?.aliasOf(part) ?? inner.alias;
|
|
12
15
|
if (alias) return sql.identifier(alias);
|
|
13
16
|
return part;
|
|
14
17
|
}),
|
|
15
18
|
sql`, `
|
|
16
19
|
),
|
|
17
|
-
limit:
|
|
20
|
+
limit: normalizedLimit !== void 0 && input(normalizedLimit),
|
|
18
21
|
offset: offset !== void 0 && input(offset)
|
|
19
22
|
});
|
|
20
23
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
+
import { type Input as UserInput } from '../expr/Input.js';
|
|
1
2
|
import { type HasQuery, type HasSql, internalData, internalQuery, internalSelection } from '../Internal.js';
|
|
2
3
|
import type { IsPostgres, IsSqlite, QueryMeta } from '../MetaData.js';
|
|
3
4
|
import { type QueryData, SingleQuery } from '../Queries.js';
|
|
4
5
|
import { type Selection, type SelectionInput, type SelectionRow } from '../Selection.js';
|
|
5
6
|
import { type Sql } from '../Sql.js';
|
|
6
|
-
import type { TableDefinition,
|
|
7
|
-
import { type Input } from '../expr/Input.js';
|
|
7
|
+
import type { TableDefinition, TableFields, TableUpdate } from '../Table.js';
|
|
8
8
|
import type { UpdateQuery } from './Query.js';
|
|
9
|
-
export declare class Update<
|
|
9
|
+
export declare class Update<Input, Meta extends QueryMeta = QueryMeta> extends SingleQuery<Array<SelectionRow<Input>>, Meta> implements HasQuery<Array<SelectionRow<Input>>> {
|
|
10
10
|
readonly [internalData]: QueryData<Meta> & UpdateQuery;
|
|
11
11
|
readonly [internalSelection]?: Selection;
|
|
12
12
|
constructor(data: QueryData<Meta> & UpdateQuery);
|
|
13
|
-
get [internalQuery](): Sql<
|
|
14
|
-
limit(limit:
|
|
15
|
-
offset(offset:
|
|
16
|
-
orderBy(...orderBy: Array<HasSql>): Update<
|
|
13
|
+
get [internalQuery](): Sql<Array<SelectionRow<Input>>>;
|
|
14
|
+
limit(limit: UserInput<number>): Update<Input, Meta>;
|
|
15
|
+
offset(offset: UserInput<number>): Update<Input, Meta>;
|
|
16
|
+
orderBy(...orderBy: Array<HasSql>): Update<Input, Meta>;
|
|
17
17
|
}
|
|
18
18
|
export declare class UpdateTable<Definition extends TableDefinition, Meta extends QueryMeta> extends Update<void, Meta> {
|
|
19
19
|
set(set: TableUpdate<Definition>): UpdateTable<Definition, Meta>;
|
|
20
20
|
where(...where: Array<HasSql<boolean> | undefined>): UpdateTable<Definition, Meta>;
|
|
21
|
-
returning(this: UpdateTable<Definition, IsPostgres | IsSqlite>): Update<
|
|
22
|
-
returning<Input extends SelectionInput>(this: UpdateTable<Definition, IsPostgres | IsSqlite>, returning?: Input): Update<
|
|
21
|
+
returning(this: UpdateTable<Definition, IsPostgres | IsSqlite>): Update<TableFields<Definition>, Meta>;
|
|
22
|
+
returning<Input extends SelectionInput>(this: UpdateTable<Definition, IsPostgres | IsSqlite>, returning?: Input): Update<Input, Meta>;
|
|
23
23
|
}
|
|
24
24
|
export declare function updateQuery(query: UpdateQuery): Sql;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// src/core/query/Update.ts
|
|
2
|
+
import { and } from "../expr/Conditions.js";
|
|
3
|
+
import { mapToColumn } from "../expr/Input.js";
|
|
2
4
|
import {
|
|
3
5
|
getData,
|
|
4
6
|
getTable,
|
|
@@ -11,8 +13,6 @@ import {
|
|
|
11
13
|
selection
|
|
12
14
|
} from "../Selection.js";
|
|
13
15
|
import { sql } from "../Sql.js";
|
|
14
|
-
import { and } from "../expr/Conditions.js";
|
|
15
|
-
import { mapToColumn } from "../expr/Input.js";
|
|
16
16
|
import { formatCTE } from "./CTE.js";
|
|
17
17
|
import { formatModifiers } from "./Shared.js";
|
|
18
18
|
var Update = class _Update extends SingleQuery {
|
|
@@ -37,7 +37,17 @@ var Update = class _Update extends SingleQuery {
|
|
|
37
37
|
};
|
|
38
38
|
var UpdateTable = class _UpdateTable extends Update {
|
|
39
39
|
set(set) {
|
|
40
|
-
|
|
40
|
+
const data = getData(this);
|
|
41
|
+
const hasDefinedValue = Object.values(set).some(
|
|
42
|
+
(value) => value !== void 0
|
|
43
|
+
);
|
|
44
|
+
if (!hasDefinedValue) {
|
|
45
|
+
const hasOnUpdate = Object.values(getTable(data.update).columns).some(
|
|
46
|
+
(column) => !!getData(column).$onUpdate
|
|
47
|
+
);
|
|
48
|
+
if (!hasOnUpdate) throw new Error("No values to set");
|
|
49
|
+
}
|
|
50
|
+
return new _UpdateTable({ ...data, set });
|
|
41
51
|
}
|
|
42
52
|
where(...where) {
|
|
43
53
|
return new _UpdateTable({
|
|
@@ -54,26 +64,28 @@ function updateQuery(query) {
|
|
|
54
64
|
const { update: table, set: values, where, returning } = query;
|
|
55
65
|
const tableApi = getTable(table);
|
|
56
66
|
if (!values) throw new Error("Update values are required");
|
|
57
|
-
const
|
|
58
|
-
|
|
67
|
+
const assignments = Object.entries(tableApi.columns).flatMap(
|
|
68
|
+
([key, column]) => {
|
|
59
69
|
const columnApi = getData(column);
|
|
60
70
|
const { name, $onUpdate } = columnApi;
|
|
71
|
+
const value = values[key];
|
|
61
72
|
let expr;
|
|
62
|
-
if (
|
|
73
|
+
if (value === void 0) {
|
|
63
74
|
if ($onUpdate) expr = $onUpdate();
|
|
64
|
-
else return;
|
|
75
|
+
else return [];
|
|
65
76
|
} else {
|
|
66
|
-
expr = mapToColumn(columnApi,
|
|
77
|
+
expr = mapToColumn(columnApi, value);
|
|
67
78
|
}
|
|
68
79
|
const fieldName = name ?? key;
|
|
69
|
-
return sql`${sql.identifier(fieldName)} = ${expr}
|
|
70
|
-
}
|
|
71
|
-
sql`, `
|
|
80
|
+
return [sql`${sql.identifier(fieldName)} = ${expr}`];
|
|
81
|
+
}
|
|
72
82
|
);
|
|
83
|
+
if (assignments.length === 0) throw new Error("No values to set");
|
|
84
|
+
const set = sql.join(assignments, sql`, `);
|
|
73
85
|
return sql.query(
|
|
74
86
|
formatCTE(query),
|
|
75
87
|
{
|
|
76
|
-
update:
|
|
88
|
+
update: tableApi.identifier(),
|
|
77
89
|
set,
|
|
78
90
|
where,
|
|
79
91
|
returning: returning && selection(returning)
|
|
@@ -8,6 +8,8 @@ var PreparedStatement = class {
|
|
|
8
8
|
this.stmt = stmt;
|
|
9
9
|
this.isSelection = isSelection;
|
|
10
10
|
}
|
|
11
|
+
stmt;
|
|
12
|
+
isSelection;
|
|
11
13
|
all(params) {
|
|
12
14
|
return this.stmt.all(...params);
|
|
13
15
|
}
|
|
@@ -31,6 +33,8 @@ var BetterSqlite3Driver = class _BetterSqlite3Driver {
|
|
|
31
33
|
this.client = client;
|
|
32
34
|
this.depth = depth;
|
|
33
35
|
}
|
|
36
|
+
client;
|
|
37
|
+
depth;
|
|
34
38
|
parsesJson = false;
|
|
35
39
|
supportsTransactions = true;
|
|
36
40
|
exec(query) {
|
|
@@ -7,6 +7,7 @@ var PreparedStatement = class {
|
|
|
7
7
|
constructor(stmt) {
|
|
8
8
|
this.stmt = stmt;
|
|
9
9
|
}
|
|
10
|
+
stmt;
|
|
10
11
|
all(params) {
|
|
11
12
|
return this.stmt.all(...params);
|
|
12
13
|
}
|
|
@@ -28,6 +29,8 @@ var BunSqliteDriver = class _BunSqliteDriver {
|
|
|
28
29
|
this.client = client;
|
|
29
30
|
this.depth = depth;
|
|
30
31
|
}
|
|
32
|
+
client;
|
|
33
|
+
depth;
|
|
31
34
|
parsesJson = false;
|
|
32
35
|
supportsTransactions = true;
|
|
33
36
|
exec(query) {
|
package/dist/driver/d1.js
CHANGED
|
@@ -7,6 +7,8 @@ var PreparedStatement = class {
|
|
|
7
7
|
this.stmt = stmt;
|
|
8
8
|
this.isSelection = isSelection;
|
|
9
9
|
}
|
|
10
|
+
stmt;
|
|
11
|
+
isSelection;
|
|
10
12
|
async all(params) {
|
|
11
13
|
return this.stmt.bind(...params).all().then(({ results }) => results);
|
|
12
14
|
}
|
|
@@ -28,6 +30,7 @@ var D1Driver = class {
|
|
|
28
30
|
constructor(client) {
|
|
29
31
|
this.client = client;
|
|
30
32
|
}
|
|
33
|
+
client;
|
|
31
34
|
parsesJson = false;
|
|
32
35
|
supportsTransactions = false;
|
|
33
36
|
async exec(query) {
|
package/dist/driver/libsql.js
CHANGED
|
@@ -7,6 +7,8 @@ var PreparedStatement = class {
|
|
|
7
7
|
this.client = client;
|
|
8
8
|
this.sql = sql;
|
|
9
9
|
}
|
|
10
|
+
client;
|
|
11
|
+
sql;
|
|
10
12
|
async all(params) {
|
|
11
13
|
const result = await this.client.execute({ sql: this.sql, args: params });
|
|
12
14
|
return result.rows;
|
|
@@ -29,6 +31,8 @@ var LibSQLClient = class _LibSQLClient {
|
|
|
29
31
|
this.client = client;
|
|
30
32
|
this.depth = depth;
|
|
31
33
|
}
|
|
34
|
+
client;
|
|
35
|
+
depth;
|
|
32
36
|
parsesJson = false;
|
|
33
37
|
supportsTransactions = true;
|
|
34
38
|
async exec(query) {
|
package/dist/driver/mysql2.js
CHANGED
|
@@ -9,6 +9,9 @@ var PreparedStatement = class {
|
|
|
9
9
|
this.sql = sql;
|
|
10
10
|
this.name = name;
|
|
11
11
|
}
|
|
12
|
+
client;
|
|
13
|
+
sql;
|
|
14
|
+
name;
|
|
12
15
|
#transformParam = (param) => {
|
|
13
16
|
if (param instanceof Uint8Array) return Buffer.from(param);
|
|
14
17
|
return param;
|
|
@@ -37,6 +40,8 @@ var Mysql2Driver = class _Mysql2Driver {
|
|
|
37
40
|
this.client = client;
|
|
38
41
|
this.depth = depth;
|
|
39
42
|
}
|
|
43
|
+
client;
|
|
44
|
+
depth;
|
|
40
45
|
parsesJson = true;
|
|
41
46
|
supportsTransactions = true;
|
|
42
47
|
async exec(query) {
|
package/dist/driver/pg.d.ts
CHANGED
|
@@ -2,6 +2,22 @@ import type { Client, Pool, PoolClient } from 'pg';
|
|
|
2
2
|
import { AsyncDatabase, type TransactionOptions } from '../core/Database.js';
|
|
3
3
|
import type { AsyncDriver, AsyncStatement, BatchedQuery, PrepareOptions } from '../core/Driver.js';
|
|
4
4
|
type Queryable = Client | Pool | PoolClient;
|
|
5
|
+
/**
|
|
6
|
+
* The query interface used by the driver. Packages providing a pg-compatible
|
|
7
|
+
* client, such as @vercel/postgres and @neondatabase/serverless, ship their
|
|
8
|
+
* own copy of the pg types which are not directly assignable to pg's. They
|
|
9
|
+
* are accepted through this minimal structural interface instead.
|
|
10
|
+
*/
|
|
11
|
+
export interface PgCompatible {
|
|
12
|
+
query(queryConfig: {
|
|
13
|
+
name?: string;
|
|
14
|
+
text: string;
|
|
15
|
+
values?: Array<unknown>;
|
|
16
|
+
rowMode?: string;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
rows: Array<any>;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
5
21
|
declare class PreparedStatement implements AsyncStatement {
|
|
6
22
|
private client;
|
|
7
23
|
private sql;
|
|
@@ -25,5 +41,5 @@ export declare class PgDriver implements AsyncDriver {
|
|
|
25
41
|
batch(queries: Array<BatchedQuery>): Promise<Array<Array<unknown>>>;
|
|
26
42
|
transaction<T>(run: (inner: AsyncDriver) => Promise<T>, options: TransactionOptions['postgres']): Promise<T>;
|
|
27
43
|
}
|
|
28
|
-
export declare function connect(client:
|
|
44
|
+
export declare function connect(client: PgCompatible): AsyncDatabase<'postgres'>;
|
|
29
45
|
export {};
|