rado 0.2.23 → 0.2.24
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/define/CTE.d.ts +2 -0
- package/dist/define/CTE.js +51 -0
- package/dist/define/Functions.js +4 -2
- package/dist/define/Query.d.ts +33 -4
- package/dist/define/Query.js +173 -75
- package/dist/define/Table.d.ts +3 -1
- package/dist/define/Table.js +39 -1
- package/dist/define/Target.d.ts +8 -1
- package/dist/define/Target.js +9 -0
- package/dist/lib/Driver.js +2 -2
- package/dist/lib/Formatter.d.ts +1 -0
- package/dist/lib/Formatter.js +42 -14
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/define/CTE.ts
|
|
2
|
+
import { Expr, ExprData, ExprType } from "./Expr.js";
|
|
3
|
+
import { Query, QueryData } from "./Query.js";
|
|
4
|
+
import { virtualTable } from "./Table.js";
|
|
5
|
+
import { Target, TargetType } from "./Target.js";
|
|
6
|
+
var { keys, create, fromEntries } = Object;
|
|
7
|
+
function columnsOf(expr) {
|
|
8
|
+
switch (expr.type) {
|
|
9
|
+
case ExprType.Record:
|
|
10
|
+
return keys(expr.fields);
|
|
11
|
+
case ExprType.Row:
|
|
12
|
+
switch (expr.target.type) {
|
|
13
|
+
case TargetType.Table:
|
|
14
|
+
return keys(expr.target.table.columns);
|
|
15
|
+
default:
|
|
16
|
+
throw new Error("Could not retrieve CTE columns");
|
|
17
|
+
}
|
|
18
|
+
default:
|
|
19
|
+
throw new Error("Could not retrieve CTE columns");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function makeRecursiveUnion(initial, createUnion, operator) {
|
|
23
|
+
let name;
|
|
24
|
+
const alias = new Proxy(create(null), {
|
|
25
|
+
get(_, key) {
|
|
26
|
+
name = key;
|
|
27
|
+
return virtualTable(name);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const right = createUnion(alias)[Query.Data];
|
|
31
|
+
if (!name)
|
|
32
|
+
throw new TypeError("No CTE name provided");
|
|
33
|
+
const cte = alias[name];
|
|
34
|
+
const cols = columnsOf(initial.selection);
|
|
35
|
+
const selection = new ExprData.Record(
|
|
36
|
+
fromEntries(cols.map((col) => [col, cte[col][Expr.Data]]))
|
|
37
|
+
);
|
|
38
|
+
const union = new QueryData.Union({
|
|
39
|
+
a: initial,
|
|
40
|
+
operator,
|
|
41
|
+
b: right
|
|
42
|
+
});
|
|
43
|
+
const from = new Target.CTE(name, union);
|
|
44
|
+
return new QueryData.Select({
|
|
45
|
+
selection,
|
|
46
|
+
from
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
makeRecursiveUnion
|
|
51
|
+
};
|
package/dist/define/Functions.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// src/define/Functions.ts
|
|
2
2
|
import { Expr, ExprData } from "./Expr.js";
|
|
3
|
-
function get(
|
|
4
|
-
|
|
3
|
+
function get(target, method) {
|
|
4
|
+
if (method in target)
|
|
5
|
+
return target[method];
|
|
6
|
+
return target[method] = (...args) => {
|
|
5
7
|
return new Expr(new ExprData.Call(method, args.map(ExprData.create)));
|
|
6
8
|
};
|
|
7
9
|
}
|
package/dist/define/Query.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ declare const DATA: unique symbol;
|
|
|
11
11
|
export declare enum QueryType {
|
|
12
12
|
Insert = "QueryData.Insert",
|
|
13
13
|
Select = "QueryData.Select",
|
|
14
|
+
Union = "QueryData.Union",
|
|
14
15
|
Update = "QueryData.Update",
|
|
15
16
|
Delete = "QueryData.Delete",
|
|
16
17
|
CreateTable = "QueryData.CreateTable",
|
|
@@ -22,7 +23,7 @@ export declare enum QueryType {
|
|
|
22
23
|
Transaction = "QueryData.Transaction",
|
|
23
24
|
Raw = "QueryData.Raw"
|
|
24
25
|
}
|
|
25
|
-
export type QueryData = QueryData.Insert | QueryData.Select | QueryData.Update | QueryData.Delete | QueryData.CreateTable | QueryData.AlterTable | QueryData.DropTable | QueryData.CreateIndex | QueryData.DropIndex | QueryData.Batch | QueryData.Transaction | QueryData.Raw;
|
|
26
|
+
export type QueryData = QueryData.Insert | QueryData.Select | QueryData.Union | QueryData.Update | QueryData.Delete | QueryData.CreateTable | QueryData.AlterTable | QueryData.DropTable | QueryData.CreateIndex | QueryData.DropIndex | QueryData.Batch | QueryData.Transaction | QueryData.Raw;
|
|
26
27
|
export declare namespace QueryData {
|
|
27
28
|
abstract class Data<T> {
|
|
28
29
|
abstract type: QueryType;
|
|
@@ -35,12 +36,29 @@ export declare namespace QueryData {
|
|
|
35
36
|
selection?: ExprData;
|
|
36
37
|
singleResult?: boolean;
|
|
37
38
|
validate?: boolean;
|
|
38
|
-
constructor(data: Omit<T, 'type'>);
|
|
39
|
+
constructor(data: Omit<T, 'type' | 'with'>);
|
|
40
|
+
with(data: Partial<T>): any;
|
|
41
|
+
}
|
|
42
|
+
export enum UnionOperation {
|
|
43
|
+
Union = "Union",
|
|
44
|
+
UnionAll = "UnionAll",
|
|
45
|
+
Intersect = "Intersect",
|
|
46
|
+
Except = "Except"
|
|
47
|
+
}
|
|
48
|
+
export class Union extends Data<Union> {
|
|
49
|
+
type: QueryType.Union;
|
|
50
|
+
a: Select | Union;
|
|
51
|
+
operator: UnionOperation;
|
|
52
|
+
b: Select | Union;
|
|
39
53
|
}
|
|
40
54
|
export class Select extends Data<Select> {
|
|
41
55
|
type: QueryType.Select;
|
|
42
56
|
selection: ExprData;
|
|
43
57
|
from?: Target;
|
|
58
|
+
union?: Select;
|
|
59
|
+
unionAll?: Select;
|
|
60
|
+
intersect?: Select;
|
|
61
|
+
except?: Select;
|
|
44
62
|
}
|
|
45
63
|
export class Insert extends Data<Insert> {
|
|
46
64
|
type: QueryType.Insert;
|
|
@@ -113,7 +131,7 @@ export declare namespace QueryData {
|
|
|
113
131
|
expectedReturn?: 'row' | 'rows';
|
|
114
132
|
strings: ReadonlyArray<string>;
|
|
115
133
|
params: Array<any>;
|
|
116
|
-
constructor(data: Omit<Raw, 'type'>);
|
|
134
|
+
constructor(data: Omit<Raw, 'type' | 'with'>);
|
|
117
135
|
}
|
|
118
136
|
export {};
|
|
119
137
|
}
|
|
@@ -171,9 +189,17 @@ export declare namespace Query {
|
|
|
171
189
|
constructor(queries: Array<QueryData>);
|
|
172
190
|
next<T>(cursor: Query<T>): Query<T>;
|
|
173
191
|
}
|
|
174
|
-
class
|
|
192
|
+
class Union<Row> extends Query<Array<Row>> {
|
|
193
|
+
[DATA]: QueryData.Union | QueryData.Select;
|
|
194
|
+
union(query: SelectMultiple<Row> | Union<Row>): Union<Row>;
|
|
195
|
+
unionAll(query: SelectMultiple<Row> | Union<Row>): Union<Row>;
|
|
196
|
+
except(query: SelectMultiple<Row> | Union<Row>): Union<Row>;
|
|
197
|
+
intersect(query: SelectMultiple<Row> | Union<Row>): Union<Row>;
|
|
198
|
+
}
|
|
199
|
+
class SelectMultiple<Row> extends Union<Row> {
|
|
175
200
|
[DATA]: QueryData.Select;
|
|
176
201
|
constructor(query: QueryData.Select);
|
|
202
|
+
from(table: Table<any>): SelectMultiple<Row>;
|
|
177
203
|
leftJoin<C>(that: Table<C> | TableSelect<C>, ...on: Array<EV<boolean>>): SelectMultiple<Row>;
|
|
178
204
|
innerJoin<C>(that: Table<C> | TableSelect<C>, ...on: Array<EV<boolean>>): SelectMultiple<Row>;
|
|
179
205
|
select<X extends Selection>(selection: X): SelectMultiple<Selection.Infer<X>>;
|
|
@@ -185,6 +211,8 @@ export declare namespace Query {
|
|
|
185
211
|
where(...where: Array<EV<boolean>>): SelectMultiple<Row>;
|
|
186
212
|
take(limit: number | undefined): SelectMultiple<Row>;
|
|
187
213
|
skip(offset: number | undefined): SelectMultiple<Row>;
|
|
214
|
+
recursiveUnion<T extends {}>(this: SelectMultiple<T>, create: (fields: Record<string, Table.Of<T>>) => SelectMultiple<T> | Union<T>): SelectMultiple<T>;
|
|
215
|
+
recursiveUnionAll<T extends {}>(this: SelectMultiple<T>, create: (fields: Record<string, Table.Of<T>>) => SelectMultiple<T> | Union<T>): SelectMultiple<T>;
|
|
188
216
|
[Expr.ToExpr](): Expr<Row>;
|
|
189
217
|
}
|
|
190
218
|
class TableSelect<Definition> extends SelectMultiple<Table.Select<Definition>> {
|
|
@@ -203,6 +231,7 @@ export declare namespace Query {
|
|
|
203
231
|
class SelectSingle<Row> extends Query<Row> {
|
|
204
232
|
[DATA]: QueryData.Select;
|
|
205
233
|
constructor(query: QueryData.Select);
|
|
234
|
+
from(table: Table<any>): SelectMultiple<Row>;
|
|
206
235
|
leftJoin<C>(that: Table<C> | TableSelect<C>, ...on: Array<EV<boolean>>): SelectSingle<Row>;
|
|
207
236
|
innerJoin<C>(that: Table<C> | TableSelect<C>, ...on: Array<EV<boolean>>): SelectSingle<Row>;
|
|
208
237
|
select<X extends Selection>(selection: X): SelectSingle<Selection.Infer<X>>;
|
package/dist/define/Query.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
// src/define/Query.ts
|
|
2
|
+
import { makeRecursiveUnion } from "./CTE.js";
|
|
2
3
|
import { Expr, ExprData } from "./Expr.js";
|
|
3
4
|
import { Functions } from "./Functions.js";
|
|
4
5
|
import { Schema } from "./Schema.js";
|
|
5
|
-
import {
|
|
6
|
+
import { createTable, Table } from "./Table.js";
|
|
6
7
|
import { Target } from "./Target.js";
|
|
7
8
|
var { assign } = Object;
|
|
8
9
|
var DATA = Symbol("Query.Data");
|
|
9
10
|
var QueryType = /* @__PURE__ */ ((QueryType2) => {
|
|
10
11
|
QueryType2["Insert"] = "QueryData.Insert";
|
|
11
12
|
QueryType2["Select"] = "QueryData.Select";
|
|
13
|
+
QueryType2["Union"] = "QueryData.Union";
|
|
12
14
|
QueryType2["Update"] = "QueryData.Update";
|
|
13
15
|
QueryType2["Delete"] = "QueryData.Delete";
|
|
14
16
|
QueryType2["CreateTable"] = "QueryData.CreateTable";
|
|
@@ -27,7 +29,21 @@ var QueryData;
|
|
|
27
29
|
constructor(data) {
|
|
28
30
|
assign(this, data);
|
|
29
31
|
}
|
|
32
|
+
with(data) {
|
|
33
|
+
return new this.constructor({ ...this, ...data });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
let UnionOperation;
|
|
37
|
+
((UnionOperation2) => {
|
|
38
|
+
UnionOperation2["Union"] = "Union";
|
|
39
|
+
UnionOperation2["UnionAll"] = "UnionAll";
|
|
40
|
+
UnionOperation2["Intersect"] = "Intersect";
|
|
41
|
+
UnionOperation2["Except"] = "Except";
|
|
42
|
+
})(UnionOperation = QueryData2.UnionOperation || (QueryData2.UnionOperation = {}));
|
|
43
|
+
class Union extends Data {
|
|
44
|
+
type = "QueryData.Union" /* Union */;
|
|
30
45
|
}
|
|
46
|
+
QueryData2.Union = Union;
|
|
31
47
|
class Select extends Data {
|
|
32
48
|
type = "QueryData.Select" /* Select */;
|
|
33
49
|
}
|
|
@@ -100,9 +116,11 @@ var Query = class {
|
|
|
100
116
|
}
|
|
101
117
|
next(cursor) {
|
|
102
118
|
return new Query(
|
|
103
|
-
new QueryData.Batch(
|
|
104
|
-
|
|
105
|
-
|
|
119
|
+
new QueryData.Batch(
|
|
120
|
+
this[DATA].with({
|
|
121
|
+
queries: [this[DATA], cursor[DATA]]
|
|
122
|
+
})
|
|
123
|
+
)
|
|
106
124
|
);
|
|
107
125
|
}
|
|
108
126
|
on(driver) {
|
|
@@ -119,36 +137,33 @@ function addWhere(query, where) {
|
|
|
119
137
|
const conditions = where.slice();
|
|
120
138
|
if (query.where)
|
|
121
139
|
conditions.push(new Expr(query.where));
|
|
122
|
-
return
|
|
123
|
-
...query,
|
|
124
|
-
where: Expr.and(...conditions)[Expr.Data]
|
|
125
|
-
};
|
|
140
|
+
return Expr.and(...conditions)[Expr.Data];
|
|
126
141
|
}
|
|
127
142
|
((Query2) => {
|
|
128
143
|
class Delete extends Query2 {
|
|
129
144
|
where(...where) {
|
|
130
|
-
return new Delete(addWhere(this[DATA], where));
|
|
145
|
+
return new Delete(this[DATA].with({ where: addWhere(this[DATA], where) }));
|
|
131
146
|
}
|
|
132
147
|
take(limit) {
|
|
133
|
-
return new Delete(
|
|
148
|
+
return new Delete(this[DATA].with({ limit }));
|
|
134
149
|
}
|
|
135
150
|
skip(offset) {
|
|
136
|
-
return new Delete(
|
|
151
|
+
return new Delete(this[DATA].with({ offset }));
|
|
137
152
|
}
|
|
138
153
|
}
|
|
139
154
|
Query2.Delete = Delete;
|
|
140
155
|
class Update extends Query2 {
|
|
141
156
|
set(set) {
|
|
142
|
-
return new Update(
|
|
157
|
+
return new Update(this[DATA].with({ set }));
|
|
143
158
|
}
|
|
144
159
|
where(...where) {
|
|
145
|
-
return new Update(addWhere(this[DATA], where));
|
|
160
|
+
return new Update(this[DATA].with({ where: addWhere(this[DATA], where) }));
|
|
146
161
|
}
|
|
147
162
|
take(limit) {
|
|
148
|
-
return new Update(
|
|
163
|
+
return new Update(this[DATA].with({ limit }));
|
|
149
164
|
}
|
|
150
165
|
skip(offset) {
|
|
151
|
-
return new Update(
|
|
166
|
+
return new Update(this[DATA].with({ offset }));
|
|
152
167
|
}
|
|
153
168
|
}
|
|
154
169
|
Query2.Update = Update;
|
|
@@ -204,6 +219,45 @@ function addWhere(query, where) {
|
|
|
204
219
|
}
|
|
205
220
|
}
|
|
206
221
|
Query2.Batch = Batch;
|
|
222
|
+
class Union extends Query2 {
|
|
223
|
+
union(query) {
|
|
224
|
+
return new Union(
|
|
225
|
+
new QueryData.Union({
|
|
226
|
+
a: this[DATA],
|
|
227
|
+
operator: "Union" /* Union */,
|
|
228
|
+
b: query[DATA]
|
|
229
|
+
})
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
unionAll(query) {
|
|
233
|
+
return new Union(
|
|
234
|
+
new QueryData.Union({
|
|
235
|
+
a: this[DATA],
|
|
236
|
+
operator: "UnionAll" /* UnionAll */,
|
|
237
|
+
b: query[DATA]
|
|
238
|
+
})
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
except(query) {
|
|
242
|
+
return new Union(
|
|
243
|
+
new QueryData.Union({
|
|
244
|
+
a: this[DATA],
|
|
245
|
+
operator: "Except" /* Except */,
|
|
246
|
+
b: query[DATA]
|
|
247
|
+
})
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
intersect(query) {
|
|
251
|
+
return new Union(
|
|
252
|
+
new QueryData.Union({
|
|
253
|
+
a: this[DATA],
|
|
254
|
+
operator: "Intersect" /* Intersect */,
|
|
255
|
+
b: query[DATA]
|
|
256
|
+
})
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
Query2.Union = Union;
|
|
207
261
|
function joinTarget(joinType, query, to, on) {
|
|
208
262
|
const toQuery = Query2.isQuery(to) ? to[DATA] : void 0;
|
|
209
263
|
const target = toQuery ? toQuery.from : new Target.Table(to[Table.Data]);
|
|
@@ -222,69 +276,99 @@ function addWhere(query, where) {
|
|
|
222
276
|
Expr.and(...conditions)[Expr.Data]
|
|
223
277
|
);
|
|
224
278
|
}
|
|
225
|
-
class SelectMultiple extends
|
|
279
|
+
class SelectMultiple extends Union {
|
|
226
280
|
constructor(query) {
|
|
227
281
|
super(query);
|
|
228
282
|
}
|
|
283
|
+
from(table) {
|
|
284
|
+
return new SelectMultiple(
|
|
285
|
+
this[DATA].with({ from: new Target.Table(table) })
|
|
286
|
+
);
|
|
287
|
+
}
|
|
229
288
|
leftJoin(that, ...on) {
|
|
230
289
|
const query = this[DATA];
|
|
231
|
-
return new SelectMultiple(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
290
|
+
return new SelectMultiple(
|
|
291
|
+
this[DATA].with({
|
|
292
|
+
from: joinTarget("left", query, that, on)
|
|
293
|
+
})
|
|
294
|
+
);
|
|
235
295
|
}
|
|
236
296
|
innerJoin(that, ...on) {
|
|
237
297
|
const query = this[DATA];
|
|
238
|
-
return new SelectMultiple(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
298
|
+
return new SelectMultiple(
|
|
299
|
+
this[DATA].with({
|
|
300
|
+
from: joinTarget("inner", query, that, on)
|
|
301
|
+
})
|
|
302
|
+
);
|
|
242
303
|
}
|
|
243
304
|
select(selection) {
|
|
244
|
-
return new SelectMultiple(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
305
|
+
return new SelectMultiple(
|
|
306
|
+
this[DATA].with({
|
|
307
|
+
selection: ExprData.create(selection)
|
|
308
|
+
})
|
|
309
|
+
);
|
|
248
310
|
}
|
|
249
311
|
count() {
|
|
250
|
-
return new SelectSingle(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
312
|
+
return new SelectSingle(
|
|
313
|
+
this[DATA].with({
|
|
314
|
+
selection: Functions.count()[Expr.Data],
|
|
315
|
+
singleResult: true
|
|
316
|
+
})
|
|
317
|
+
);
|
|
255
318
|
}
|
|
256
319
|
orderBy(...orderBy) {
|
|
257
|
-
return new SelectMultiple(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
320
|
+
return new SelectMultiple(
|
|
321
|
+
this[DATA].with({
|
|
322
|
+
orderBy: orderBy.map((e) => {
|
|
323
|
+
return Expr.isExpr(e) ? e.asc() : e;
|
|
324
|
+
})
|
|
261
325
|
})
|
|
262
|
-
|
|
326
|
+
);
|
|
263
327
|
}
|
|
264
328
|
groupBy(...groupBy) {
|
|
265
|
-
return new SelectMultiple(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
329
|
+
return new SelectMultiple(
|
|
330
|
+
this[DATA].with({
|
|
331
|
+
groupBy: groupBy.map(ExprData.create)
|
|
332
|
+
})
|
|
333
|
+
);
|
|
269
334
|
}
|
|
270
335
|
maybeFirst() {
|
|
271
|
-
return new SelectSingle(
|
|
336
|
+
return new SelectSingle(this[DATA].with({ singleResult: true }));
|
|
272
337
|
}
|
|
273
338
|
first() {
|
|
274
|
-
return new SelectSingle(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
339
|
+
return new SelectSingle(
|
|
340
|
+
this[DATA].with({
|
|
341
|
+
singleResult: true,
|
|
342
|
+
validate: true
|
|
343
|
+
})
|
|
344
|
+
);
|
|
279
345
|
}
|
|
280
346
|
where(...where) {
|
|
281
|
-
return new SelectMultiple(
|
|
347
|
+
return new SelectMultiple(
|
|
348
|
+
this[DATA].with({
|
|
349
|
+
where: addWhere(this[DATA], where)
|
|
350
|
+
})
|
|
351
|
+
);
|
|
282
352
|
}
|
|
283
353
|
take(limit) {
|
|
284
|
-
return new SelectMultiple(
|
|
354
|
+
return new SelectMultiple(this[DATA].with({ limit }));
|
|
285
355
|
}
|
|
286
356
|
skip(offset) {
|
|
287
|
-
return new SelectMultiple(
|
|
357
|
+
return new SelectMultiple(this[DATA].with({ offset }));
|
|
358
|
+
}
|
|
359
|
+
recursiveUnion(create) {
|
|
360
|
+
return new SelectMultiple(
|
|
361
|
+
makeRecursiveUnion(this[DATA], create, "Union" /* Union */)
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
recursiveUnionAll(create) {
|
|
365
|
+
return new SelectMultiple(
|
|
366
|
+
makeRecursiveUnion(
|
|
367
|
+
this[DATA],
|
|
368
|
+
create,
|
|
369
|
+
"UnionAll" /* UnionAll */
|
|
370
|
+
)
|
|
371
|
+
);
|
|
288
372
|
}
|
|
289
373
|
[Expr.ToExpr]() {
|
|
290
374
|
return new Expr(new ExprData.Query(this[DATA]));
|
|
@@ -354,49 +438,63 @@ function addWhere(query, where) {
|
|
|
354
438
|
constructor(query) {
|
|
355
439
|
super(query);
|
|
356
440
|
}
|
|
441
|
+
from(table) {
|
|
442
|
+
return new SelectMultiple(
|
|
443
|
+
this[DATA].with({ from: new Target.Table(table) })
|
|
444
|
+
);
|
|
445
|
+
}
|
|
357
446
|
leftJoin(that, ...on) {
|
|
358
447
|
const query = this[DATA];
|
|
359
|
-
return new SelectSingle(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
448
|
+
return new SelectSingle(
|
|
449
|
+
this[DATA].with({
|
|
450
|
+
from: joinTarget("left", query, that, on)
|
|
451
|
+
})
|
|
452
|
+
);
|
|
363
453
|
}
|
|
364
454
|
innerJoin(that, ...on) {
|
|
365
455
|
const query = this[DATA];
|
|
366
|
-
return new SelectSingle(
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
456
|
+
return new SelectSingle(
|
|
457
|
+
this[DATA].with({
|
|
458
|
+
from: joinTarget("inner", query, that, on)
|
|
459
|
+
})
|
|
460
|
+
);
|
|
370
461
|
}
|
|
371
462
|
select(selection) {
|
|
372
|
-
return new SelectSingle(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
463
|
+
return new SelectSingle(
|
|
464
|
+
this[DATA].with({
|
|
465
|
+
selection: ExprData.create(selection)
|
|
466
|
+
})
|
|
467
|
+
);
|
|
376
468
|
}
|
|
377
469
|
orderBy(...orderBy) {
|
|
378
|
-
return new SelectSingle(
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
470
|
+
return new SelectSingle(
|
|
471
|
+
this[DATA].with({
|
|
472
|
+
orderBy
|
|
473
|
+
})
|
|
474
|
+
);
|
|
382
475
|
}
|
|
383
476
|
groupBy(...groupBy) {
|
|
384
|
-
return new SelectSingle(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
477
|
+
return new SelectSingle(
|
|
478
|
+
this[DATA].with({
|
|
479
|
+
groupBy: groupBy.map(ExprData.create)
|
|
480
|
+
})
|
|
481
|
+
);
|
|
388
482
|
}
|
|
389
483
|
where(...where) {
|
|
390
|
-
return new SelectSingle(
|
|
484
|
+
return new SelectSingle(
|
|
485
|
+
this[DATA].with({
|
|
486
|
+
where: addWhere(this[DATA], where)
|
|
487
|
+
})
|
|
488
|
+
);
|
|
391
489
|
}
|
|
392
490
|
take(limit) {
|
|
393
|
-
return new SelectSingle(
|
|
491
|
+
return new SelectSingle(this[DATA].with({ limit }));
|
|
394
492
|
}
|
|
395
493
|
skip(offset) {
|
|
396
|
-
return new SelectSingle(
|
|
494
|
+
return new SelectSingle(this[DATA].with({ offset }));
|
|
397
495
|
}
|
|
398
496
|
all() {
|
|
399
|
-
return new SelectMultiple(
|
|
497
|
+
return new SelectMultiple(this[DATA].with({ singleResult: false }));
|
|
400
498
|
}
|
|
401
499
|
[Expr.ToExpr]() {
|
|
402
500
|
return new Expr(new ExprData.Query(this[DATA]));
|
package/dist/define/Table.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Column, ColumnData, OptionalColumn, PrimaryColumn } from './Column';
|
|
2
2
|
import { EV } from './Expr';
|
|
3
|
+
import { Fields } from './Fields';
|
|
3
4
|
import { Index, IndexData } from './Index';
|
|
4
5
|
import { Query } from './Query';
|
|
5
6
|
import { Selection } from './Selection';
|
|
@@ -38,7 +39,7 @@ export declare namespace Table {
|
|
|
38
39
|
export const Data: typeof DATA;
|
|
39
40
|
export const Meta: typeof META;
|
|
40
41
|
export type Of<Row> = Table<{
|
|
41
|
-
[K in keyof Row as K extends string ? K : never]:
|
|
42
|
+
[K in keyof Row as K extends string ? K : never]: Fields<Row[K]>;
|
|
42
43
|
}>;
|
|
43
44
|
export type Select<Definition> = {
|
|
44
45
|
[K in keyof Definition as Definition[K] extends Column<any> ? K : never]: Definition[K] extends Column<infer T> ? T : never;
|
|
@@ -61,6 +62,7 @@ interface Define<T> {
|
|
|
61
62
|
new (): T;
|
|
62
63
|
}
|
|
63
64
|
export type table<T> = T extends Table<infer D> ? Table.Select<D> : never;
|
|
65
|
+
export declare function virtualTable<Definition>(name: string): Table<Definition>;
|
|
64
66
|
export declare function createTable<Definition>(data: TableData): Table<Definition>;
|
|
65
67
|
export declare function table<T extends {}>(define: Record<string, T | Define<T>>): Table<T>;
|
|
66
68
|
export declare namespace table {
|
package/dist/define/Table.js
CHANGED
|
@@ -8,6 +8,7 @@ import { Query } from "./Query.js";
|
|
|
8
8
|
import { Target } from "./Target.js";
|
|
9
9
|
var {
|
|
10
10
|
assign,
|
|
11
|
+
create,
|
|
11
12
|
keys,
|
|
12
13
|
entries,
|
|
13
14
|
fromEntries,
|
|
@@ -28,6 +29,42 @@ var Table;
|
|
|
28
29
|
Table2.Data = DATA;
|
|
29
30
|
Table2.Meta = META;
|
|
30
31
|
})(Table || (Table = {}));
|
|
32
|
+
function virtualTable(name) {
|
|
33
|
+
const data = new TableData({
|
|
34
|
+
name,
|
|
35
|
+
columns: {},
|
|
36
|
+
definition: create(null),
|
|
37
|
+
meta: () => ({ indexes: {} })
|
|
38
|
+
});
|
|
39
|
+
const target = new Target.Table(data);
|
|
40
|
+
const cache = create(null);
|
|
41
|
+
function call(...args) {
|
|
42
|
+
const isConditionalRecord = args.length === 1 && !Expr.isExpr(args[0]);
|
|
43
|
+
const conditions = isConditionalRecord ? entries(args[0]).map(([key, value]) => {
|
|
44
|
+
return new Expr(
|
|
45
|
+
new ExprData.BinOp(
|
|
46
|
+
BinOpType.Equals,
|
|
47
|
+
new ExprData.Field(new ExprData.Row(target), key),
|
|
48
|
+
ExprData.create(value)
|
|
49
|
+
)
|
|
50
|
+
);
|
|
51
|
+
}) : args;
|
|
52
|
+
return new Query.TableSelect(data, conditions);
|
|
53
|
+
}
|
|
54
|
+
return new Proxy(call, {
|
|
55
|
+
get(_, column) {
|
|
56
|
+
if (column === DATA)
|
|
57
|
+
return data;
|
|
58
|
+
if (column === Expr.ToExpr)
|
|
59
|
+
return new Expr(new ExprData.Row(target));
|
|
60
|
+
if (column in cache)
|
|
61
|
+
return cache[column];
|
|
62
|
+
return (cache[column] = new Expr(
|
|
63
|
+
new ExprData.Field(new ExprData.Row(target), column)
|
|
64
|
+
)).dynamic();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
31
68
|
function createTable(data) {
|
|
32
69
|
const target = new Target.Table(data);
|
|
33
70
|
const call = {
|
|
@@ -123,5 +160,6 @@ export {
|
|
|
123
160
|
Table,
|
|
124
161
|
TableData,
|
|
125
162
|
createTable,
|
|
126
|
-
table
|
|
163
|
+
table,
|
|
164
|
+
virtualTable
|
|
127
165
|
};
|
package/dist/define/Target.d.ts
CHANGED
|
@@ -3,12 +3,19 @@ import type { QueryData } from './Query';
|
|
|
3
3
|
import type { TableData } from './Table';
|
|
4
4
|
export declare enum TargetType {
|
|
5
5
|
Expr = "Target.Expr",
|
|
6
|
+
CTE = "Target.CTE",
|
|
6
7
|
Query = "Target.Query",
|
|
7
8
|
Table = "Target.Table",
|
|
8
9
|
Join = "Target.Join"
|
|
9
10
|
}
|
|
10
|
-
export type Target = Target.Expr | Target.Query | Target.Table | Target.Join;
|
|
11
|
+
export type Target = Target.Expr | Target.CTE | Target.Query | Target.Table | Target.Join;
|
|
11
12
|
export declare namespace Target {
|
|
13
|
+
class CTE {
|
|
14
|
+
name: string;
|
|
15
|
+
union: QueryData.Union;
|
|
16
|
+
type: TargetType.CTE;
|
|
17
|
+
constructor(name: string, union: QueryData.Union);
|
|
18
|
+
}
|
|
12
19
|
class Expr {
|
|
13
20
|
expr: ExprData;
|
|
14
21
|
alias?: string | undefined;
|
package/dist/define/Target.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/define/Target.ts
|
|
2
2
|
var TargetType = /* @__PURE__ */ ((TargetType2) => {
|
|
3
3
|
TargetType2["Expr"] = "Target.Expr";
|
|
4
|
+
TargetType2["CTE"] = "Target.CTE";
|
|
4
5
|
TargetType2["Query"] = "Target.Query";
|
|
5
6
|
TargetType2["Table"] = "Target.Table";
|
|
6
7
|
TargetType2["Join"] = "Target.Join";
|
|
@@ -8,6 +9,14 @@ var TargetType = /* @__PURE__ */ ((TargetType2) => {
|
|
|
8
9
|
})(TargetType || {});
|
|
9
10
|
var Target;
|
|
10
11
|
((Target2) => {
|
|
12
|
+
class CTE {
|
|
13
|
+
constructor(name, union) {
|
|
14
|
+
this.name = name;
|
|
15
|
+
this.union = union;
|
|
16
|
+
}
|
|
17
|
+
type = "Target.CTE" /* CTE */;
|
|
18
|
+
}
|
|
19
|
+
Target2.CTE = CTE;
|
|
11
20
|
class Expr {
|
|
12
21
|
constructor(expr, alias) {
|
|
13
22
|
this.expr = expr;
|
package/dist/lib/Driver.js
CHANGED
|
@@ -109,7 +109,7 @@ var SyncDriver = class extends DriverBase {
|
|
|
109
109
|
const compiled = stmt ? void 0 : this.formatter.compile(query);
|
|
110
110
|
stmt = stmt || this.prepareStatement(compiled, true);
|
|
111
111
|
params = params || compiled.params();
|
|
112
|
-
if ("selection" in query) {
|
|
112
|
+
if ("selection" in query || query.type === QueryType.Union) {
|
|
113
113
|
const res = stmt.all(params).map((row) => JSON.parse(row.result).result);
|
|
114
114
|
if (query.singleResult) {
|
|
115
115
|
const row = res[0];
|
|
@@ -229,7 +229,7 @@ var AsyncDriver = class extends DriverBase {
|
|
|
229
229
|
const compiled = stmt ? void 0 : this.formatter.compile(query);
|
|
230
230
|
stmt = stmt || this.prepareStatement(compiled, true);
|
|
231
231
|
params = params || compiled.params();
|
|
232
|
-
if ("selection" in query) {
|
|
232
|
+
if ("selection" in query || query.type === QueryType.Union) {
|
|
233
233
|
const res = (await stmt.all(params)).map(
|
|
234
234
|
(item) => JSON.parse(item.result).result
|
|
235
235
|
);
|
package/dist/lib/Formatter.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export declare abstract class Formatter implements Sanitizer {
|
|
|
49
49
|
};
|
|
50
50
|
format(ctx: FormatContext, query: QueryData): Statement;
|
|
51
51
|
formatSelect({ topLevel, ...ctx }: FormatContext, query: QueryData.Select): Statement;
|
|
52
|
+
formatUnion(ctx: FormatContext, { a, operator, b }: QueryData.Union): Statement;
|
|
52
53
|
formatInsert(ctx: FormatContext, query: QueryData.Insert): Statement;
|
|
53
54
|
formatUpdate(ctx: FormatContext, query: QueryData.Update): Statement;
|
|
54
55
|
formatDelete(ctx: FormatContext, query: QueryData.Delete): Statement;
|
package/dist/lib/Formatter.js
CHANGED
|
@@ -31,6 +31,12 @@ var joins = {
|
|
|
31
31
|
left: "LEFT",
|
|
32
32
|
inner: "INNER"
|
|
33
33
|
};
|
|
34
|
+
var unions = {
|
|
35
|
+
[QueryData.UnionOperation.Union]: "UNION",
|
|
36
|
+
[QueryData.UnionOperation.UnionAll]: "UNION ALL",
|
|
37
|
+
[QueryData.UnionOperation.Intersect]: "INTERSECT",
|
|
38
|
+
[QueryData.UnionOperation.Except]: "EXCEPT"
|
|
39
|
+
};
|
|
34
40
|
function formatAsResultObject(stmt, mkSubject) {
|
|
35
41
|
stmt.raw("json_object('result', ");
|
|
36
42
|
mkSubject();
|
|
@@ -53,6 +59,8 @@ var Formatter = class {
|
|
|
53
59
|
switch (query.type) {
|
|
54
60
|
case QueryType.Select:
|
|
55
61
|
return this.formatSelect(ctx, query);
|
|
62
|
+
case QueryType.Union:
|
|
63
|
+
return this.formatUnion(ctx, query);
|
|
56
64
|
case QueryType.Insert:
|
|
57
65
|
return this.formatInsert(ctx, query);
|
|
58
66
|
case QueryType.Update:
|
|
@@ -79,21 +87,38 @@ var Formatter = class {
|
|
|
79
87
|
}
|
|
80
88
|
formatSelect({ topLevel, ...ctx }, query) {
|
|
81
89
|
const { stmt } = ctx;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
switch (query.from?.type) {
|
|
91
|
+
case TargetType.CTE:
|
|
92
|
+
stmt.add("WITH RECURSIVE").addIdentifier(query.from.name).add("AS").space().openParenthesis();
|
|
93
|
+
this.formatUnion(
|
|
94
|
+
{ ...ctx, topLevel: false, selectAsColumns: true },
|
|
95
|
+
query.from.union
|
|
96
|
+
);
|
|
97
|
+
stmt.closeParenthesis().space();
|
|
98
|
+
default:
|
|
99
|
+
stmt.raw("SELECT").space();
|
|
100
|
+
this.formatSelection(
|
|
101
|
+
ctx,
|
|
102
|
+
query.selection,
|
|
103
|
+
topLevel ? formatAsResultObject : void 0
|
|
104
|
+
);
|
|
105
|
+
if (query.from) {
|
|
106
|
+
stmt.addLine("FROM").space();
|
|
107
|
+
this.formatTarget(ctx, query.from);
|
|
108
|
+
}
|
|
109
|
+
this.formatWhere(ctx, query.where);
|
|
110
|
+
this.formatGroupBy(ctx, query.groupBy);
|
|
111
|
+
this.formatHaving(ctx, query.having);
|
|
112
|
+
this.formatOrderBy(ctx, query.orderBy);
|
|
113
|
+
this.formatLimit(ctx, query);
|
|
114
|
+
return stmt;
|
|
91
115
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.
|
|
96
|
-
|
|
116
|
+
}
|
|
117
|
+
formatUnion(ctx, { a, operator, b }) {
|
|
118
|
+
const { stmt } = ctx;
|
|
119
|
+
this.format(ctx, a);
|
|
120
|
+
stmt.add(unions[operator]).space();
|
|
121
|
+
this.format(ctx, b);
|
|
97
122
|
return stmt;
|
|
98
123
|
}
|
|
99
124
|
formatInsert(ctx, query) {
|
|
@@ -377,6 +402,8 @@ var Formatter = class {
|
|
|
377
402
|
if (target.alias)
|
|
378
403
|
stmt.add("AS").addIdentifier(target.alias);
|
|
379
404
|
return stmt;
|
|
405
|
+
case TargetType.CTE:
|
|
406
|
+
return stmt.addIdentifier(target.name);
|
|
380
407
|
case TargetType.Expr:
|
|
381
408
|
throw new Error("Cannot format expression as target");
|
|
382
409
|
}
|
|
@@ -685,6 +712,7 @@ var Formatter = class {
|
|
|
685
712
|
const inner = { ...ctx, selectAsColumns: false };
|
|
686
713
|
for (const [key, value] of stmt.separate(Object.entries(expr.fields))) {
|
|
687
714
|
this.formatExprJson(inner, value);
|
|
715
|
+
stmt.add("AS").addIdentifier(key);
|
|
688
716
|
}
|
|
689
717
|
return stmt;
|
|
690
718
|
}
|