@grest-ts/sql 0.0.5
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/LICENSE +21 -0
- package/README.md +498 -0
- package/dist/src/MysqlTable.d.ts +35 -0
- package/dist/src/MysqlTable.d.ts.map +1 -0
- package/dist/src/MysqlTable.js +70 -0
- package/dist/src/MysqlTable.js.map +1 -0
- package/dist/src/MysqlTableStructureParser.d.ts +106 -0
- package/dist/src/MysqlTableStructureParser.d.ts.map +1 -0
- package/dist/src/MysqlTableStructureParser.js +189 -0
- package/dist/src/MysqlTableStructureParser.js.map +1 -0
- package/dist/src/SQL.d.ts +72 -0
- package/dist/src/SQL.d.ts.map +1 -0
- package/dist/src/SQL.js +94 -0
- package/dist/src/SQL.js.map +1 -0
- package/dist/src/SqlExpression.d.ts +49 -0
- package/dist/src/SqlExpression.d.ts.map +1 -0
- package/dist/src/SqlExpression.js +117 -0
- package/dist/src/SqlExpression.js.map +1 -0
- package/dist/src/SqlFunctions.d.ts +118 -0
- package/dist/src/SqlFunctions.d.ts.map +1 -0
- package/dist/src/SqlFunctions.js +331 -0
- package/dist/src/SqlFunctions.js.map +1 -0
- package/dist/src/Symbols.d.ts +11 -0
- package/dist/src/Symbols.d.ts.map +1 -0
- package/dist/src/Symbols.js +11 -0
- package/dist/src/Symbols.js.map +1 -0
- package/dist/src/Types.d.ts +110 -0
- package/dist/src/Types.d.ts.map +1 -0
- package/dist/src/Types.js +34 -0
- package/dist/src/Types.js.map +1 -0
- package/dist/src/delete/DeleteBuilder.d.ts +19 -0
- package/dist/src/delete/DeleteBuilder.d.ts.map +1 -0
- package/dist/src/delete/DeleteBuilder.js +50 -0
- package/dist/src/delete/DeleteBuilder.js.map +1 -0
- package/dist/src/delete/DeleteInterfaces.d.ts +27 -0
- package/dist/src/delete/DeleteInterfaces.d.ts.map +1 -0
- package/dist/src/delete/DeleteInterfaces.js +2 -0
- package/dist/src/delete/DeleteInterfaces.js.map +1 -0
- package/dist/src/escape.d.ts +4 -0
- package/dist/src/escape.d.ts.map +1 -0
- package/dist/src/escape.js +50 -0
- package/dist/src/escape.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/insert/InsertBuilder.d.ts +19 -0
- package/dist/src/insert/InsertBuilder.d.ts.map +1 -0
- package/dist/src/insert/InsertBuilder.js +62 -0
- package/dist/src/insert/InsertBuilder.js.map +1 -0
- package/dist/src/insert/InsertInterfaces.d.ts +11 -0
- package/dist/src/insert/InsertInterfaces.d.ts.map +1 -0
- package/dist/src/insert/InsertInterfaces.js +2 -0
- package/dist/src/insert/InsertInterfaces.js.map +1 -0
- package/dist/src/select/SelectBuilder.d.ts +72 -0
- package/dist/src/select/SelectBuilder.d.ts.map +1 -0
- package/dist/src/select/SelectBuilder.js +315 -0
- package/dist/src/select/SelectBuilder.js.map +1 -0
- package/dist/src/select/parts/GatewayWhere.d.ts +17 -0
- package/dist/src/select/parts/GatewayWhere.d.ts.map +1 -0
- package/dist/src/select/parts/GatewayWhere.js +2 -0
- package/dist/src/select/parts/GatewayWhere.js.map +1 -0
- package/dist/src/select/parts/S0Union.d.ts +20 -0
- package/dist/src/select/parts/S0Union.d.ts.map +1 -0
- package/dist/src/select/parts/S0Union.js +2 -0
- package/dist/src/select/parts/S0Union.js.map +1 -0
- package/dist/src/select/parts/S0Uses.d.ts +6 -0
- package/dist/src/select/parts/S0Uses.d.ts.map +1 -0
- package/dist/src/select/parts/S0Uses.js +2 -0
- package/dist/src/select/parts/S0Uses.js.map +1 -0
- package/dist/src/select/parts/S0With.d.ts +6 -0
- package/dist/src/select/parts/S0With.d.ts.map +1 -0
- package/dist/src/select/parts/S0With.js +2 -0
- package/dist/src/select/parts/S0With.js.map +1 -0
- package/dist/src/select/parts/S1Join.d.ts +12 -0
- package/dist/src/select/parts/S1Join.d.ts.map +1 -0
- package/dist/src/select/parts/S1Join.js +2 -0
- package/dist/src/select/parts/S1Join.js.map +1 -0
- package/dist/src/select/parts/S2Columns.d.ts +35 -0
- package/dist/src/select/parts/S2Columns.d.ts.map +1 -0
- package/dist/src/select/parts/S2Columns.js +3 -0
- package/dist/src/select/parts/S2Columns.js.map +1 -0
- package/dist/src/select/parts/S2Where.d.ts +13 -0
- package/dist/src/select/parts/S2Where.d.ts.map +1 -0
- package/dist/src/select/parts/S2Where.js +2 -0
- package/dist/src/select/parts/S2Where.js.map +1 -0
- package/dist/src/select/parts/S3GroupBy.d.ts +10 -0
- package/dist/src/select/parts/S3GroupBy.d.ts.map +1 -0
- package/dist/src/select/parts/S3GroupBy.js +2 -0
- package/dist/src/select/parts/S3GroupBy.js.map +1 -0
- package/dist/src/select/parts/S4Having.d.ts +10 -0
- package/dist/src/select/parts/S4Having.d.ts.map +1 -0
- package/dist/src/select/parts/S4Having.js +2 -0
- package/dist/src/select/parts/S4Having.js.map +1 -0
- package/dist/src/select/parts/S5OrderBy.d.ts +9 -0
- package/dist/src/select/parts/S5OrderBy.d.ts.map +1 -0
- package/dist/src/select/parts/S5OrderBy.js +2 -0
- package/dist/src/select/parts/S5OrderBy.js.map +1 -0
- package/dist/src/select/parts/S6Limit.d.ts +7 -0
- package/dist/src/select/parts/S6Limit.d.ts.map +1 -0
- package/dist/src/select/parts/S6Limit.js +2 -0
- package/dist/src/select/parts/S6Limit.js.map +1 -0
- package/dist/src/select/parts/S7Exec.d.ts +26 -0
- package/dist/src/select/parts/S7Exec.d.ts.map +1 -0
- package/dist/src/select/parts/S7Exec.js +2 -0
- package/dist/src/select/parts/S7Exec.js.map +1 -0
- package/dist/src/tsconfig.json +16 -0
- package/dist/src/update/UpdateBuilder.d.ts +28 -0
- package/dist/src/update/UpdateBuilder.d.ts.map +1 -0
- package/dist/src/update/UpdateBuilder.js +77 -0
- package/dist/src/update/UpdateBuilder.js.map +1 -0
- package/dist/src/update/UpdateInterfaces.d.ts +34 -0
- package/dist/src/update/UpdateInterfaces.d.ts.map +1 -0
- package/dist/src/update/UpdateInterfaces.js +2 -0
- package/dist/src/update/UpdateInterfaces.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -0
- package/package.json +54 -0
- package/src/MysqlTable.ts +102 -0
- package/src/MysqlTableStructureParser.ts +283 -0
- package/src/SQL.ts +244 -0
- package/src/SqlExpression.ts +172 -0
- package/src/SqlFunctions.ts +471 -0
- package/src/Symbols.ts +11 -0
- package/src/Types.ts +244 -0
- package/src/delete/DeleteBuilder.ts +65 -0
- package/src/delete/DeleteInterfaces.ts +70 -0
- package/src/escape.ts +52 -0
- package/src/index.ts +6 -0
- package/src/insert/InsertBuilder.ts +76 -0
- package/src/insert/InsertInterfaces.ts +16 -0
- package/src/select/SelectBuilder.ts +372 -0
- package/src/select/parts/GatewayWhere.ts +31 -0
- package/src/select/parts/S0Union.ts +43 -0
- package/src/select/parts/S0Uses.ts +21 -0
- package/src/select/parts/S0With.ts +21 -0
- package/src/select/parts/S1Join.ts +39 -0
- package/src/select/parts/S2Columns.ts +68 -0
- package/src/select/parts/S2Where.ts +51 -0
- package/src/select/parts/S3GroupBy.ts +23 -0
- package/src/select/parts/S4Having.ts +24 -0
- package/src/select/parts/S5OrderBy.ts +21 -0
- package/src/select/parts/S6Limit.ts +9 -0
- package/src/select/parts/S7Exec.ts +41 -0
- package/src/tsconfig.json +16 -0
- package/src/update/UpdateBuilder.ts +96 -0
- package/src/update/UpdateInterfaces.ts +87 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import {Over, SqlExpression, Transformer} from "../SqlExpression";
|
|
2
|
+
import {WhereMethods} from "./parts/S2Where";
|
|
3
|
+
import {ColumnsMethods} from "./parts/S2Columns";
|
|
4
|
+
import {JoinMethods} from "./parts/S1Join";
|
|
5
|
+
import {WithMethods} from "./parts/S0With";
|
|
6
|
+
import {UsesMethods} from "./parts/S0Uses";
|
|
7
|
+
import {UnionMethods} from "./parts/S0Union";
|
|
8
|
+
import {GroupByMethods} from "./parts/S3GroupBy";
|
|
9
|
+
import {HavingMethods} from "./parts/S4Having";
|
|
10
|
+
import {OrderByMethods} from "./parts/S5OrderBy";
|
|
11
|
+
import {LimitMethods} from "./parts/S6Limit";
|
|
12
|
+
import {ExecMethods} from "./parts/S7Exec";
|
|
13
|
+
import {MysqlTable} from "../MysqlTable";
|
|
14
|
+
import {SQL_ALIAS, SQL_ENTITY, SQL_EXPRESSION} from "../Symbols";
|
|
15
|
+
import {AliasedTable, AnyAliasedTableDef, DbTableDefinition, SelectExecutor} from "../Types";
|
|
16
|
+
import {escape, escapeId} from "../escape";
|
|
17
|
+
import {ONE, orderByStructureToSqlString} from "../SqlFunctions";
|
|
18
|
+
import {GatewaySelectGroupByMethods, GatewaySelectLimitMethods, GatewaySelectOrderByMethods, GatewayWhereMethods} from "./parts/GatewayWhere";
|
|
19
|
+
|
|
20
|
+
const TAB = " ";
|
|
21
|
+
|
|
22
|
+
export class SelectBuilder<Result, Aliases, AliasesFromWith, Tables> implements UnionMethods<Result>,
|
|
23
|
+
WithMethods<AliasesFromWith>,
|
|
24
|
+
UsesMethods<Aliases, Tables>,
|
|
25
|
+
JoinMethods<Aliases, AliasesFromWith, Tables>,
|
|
26
|
+
ColumnsMethods<Result, Tables>,
|
|
27
|
+
WhereMethods<Result, Tables>,
|
|
28
|
+
GroupByMethods<Result, Tables>,
|
|
29
|
+
HavingMethods<Result, Tables>,
|
|
30
|
+
OrderByMethods<Result, Tables>,
|
|
31
|
+
LimitMethods<Result>,
|
|
32
|
+
ExecMethods<Result>,
|
|
33
|
+
GatewayWhereMethods<Result, Tables>,
|
|
34
|
+
GatewaySelectGroupByMethods<Result, Tables>,
|
|
35
|
+
GatewaySelectOrderByMethods<Result, Tables>,
|
|
36
|
+
GatewaySelectOrderByMethods<Result, Tables>,
|
|
37
|
+
GatewaySelectLimitMethods<Result> {
|
|
38
|
+
|
|
39
|
+
public readonly [SQL_ENTITY]: undefined; // never used
|
|
40
|
+
|
|
41
|
+
private _withQueries: Map<string, string> = new Map()
|
|
42
|
+
private _from: string;
|
|
43
|
+
private readonly _columns: string[] = [];
|
|
44
|
+
private _columnStruct: DbTableDefinition<any> = {} as any;
|
|
45
|
+
|
|
46
|
+
private readonly _joins: string[] = []
|
|
47
|
+
private readonly _windows: string[] = []
|
|
48
|
+
private readonly _where: string[] = []
|
|
49
|
+
private readonly _having: string[] = []
|
|
50
|
+
private readonly _groupBy: string[] = []
|
|
51
|
+
private _orderBy: string[] = []
|
|
52
|
+
private _limit: string = undefined
|
|
53
|
+
|
|
54
|
+
private readonly unions: string[] = []
|
|
55
|
+
private _unionColumnOrder: string[] = []
|
|
56
|
+
|
|
57
|
+
private _distinct: boolean = false;
|
|
58
|
+
private _forUpdate: boolean = false;
|
|
59
|
+
|
|
60
|
+
public readonly transformers: { property: string, transformer: Transformer<any, any> }[] = []
|
|
61
|
+
|
|
62
|
+
public union(table: any | SelectBuilder<any, any, any, any>): SelectBuilder<any, any, any, any> {
|
|
63
|
+
return this._union(table, "DISTINCT") as any
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public unionAll(table: any | SelectBuilder<any, any, any, any>): SelectBuilder<any, any, any, any> {
|
|
67
|
+
return this._union(table, "ALL")
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private _union(table: SelectBuilder<any, any, any, any>, type: "ALL" | "DISTINCT" = "DISTINCT"): SelectBuilder<any, any, any, any> {
|
|
71
|
+
if (this.unions.length === 0) {
|
|
72
|
+
const builder = new SelectBuilder()
|
|
73
|
+
builder.unions.push("(\n" + this.toString(1) + ") ")
|
|
74
|
+
builder._columnStruct = this._columnStruct;
|
|
75
|
+
for (const k in this._columnStruct) {
|
|
76
|
+
builder._unionColumnOrder.push(k);
|
|
77
|
+
}
|
|
78
|
+
builder._union(table, type);
|
|
79
|
+
return builder;
|
|
80
|
+
} else {
|
|
81
|
+
const struct = table._columnStruct;
|
|
82
|
+
let i = 0;
|
|
83
|
+
for (const k in struct) {
|
|
84
|
+
if (this._unionColumnOrder[i] !== k) {
|
|
85
|
+
const order: string[] = []
|
|
86
|
+
for (const k in struct) {
|
|
87
|
+
order.push(k);
|
|
88
|
+
}
|
|
89
|
+
throw new Error("Union columns from pos " + i + " do not match! \nFirst call columns: '" + this._unionColumnOrder.join(", ") + "'. \nCurrent call columns: '" + order.join(", ") + "'")
|
|
90
|
+
}
|
|
91
|
+
i++;
|
|
92
|
+
}
|
|
93
|
+
if (i !== this._unionColumnOrder.length) {
|
|
94
|
+
throw new Error("Union columns count do not match! " + this._unionColumnOrder.length + " != " + i + " (Why didn't compiler warn you about this?)");
|
|
95
|
+
}
|
|
96
|
+
this.unions.push("UNION " + (type === "DISTINCT" ? "DISTINCT " : "ALL ") + "(\n" + table.toString(1) + ") ")
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public with(...tables: (any | AnyAliasedTableDef)[]) {
|
|
102
|
+
console.log(tables)
|
|
103
|
+
for (let i = 0; i < tables.length; i++) {
|
|
104
|
+
const table = tables[i];
|
|
105
|
+
const alias = table[SQL_ALIAS]
|
|
106
|
+
this._withQueries.set(alias, escapeId(alias) + " AS " + table[SQL_EXPRESSION])
|
|
107
|
+
}
|
|
108
|
+
return this
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public uses(table: any | AnyAliasedTableDef) {
|
|
112
|
+
return this
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public selectFrom(table: any | AnyAliasedTableDef) {
|
|
116
|
+
if (typeof table === "string") {
|
|
117
|
+
this._from = escapeId(table);
|
|
118
|
+
} else {
|
|
119
|
+
this._from = table[SQL_EXPRESSION] + " as " + escapeId(table[SQL_ALIAS]);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return this
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public join(table: any | AnyAliasedTableDef, condition: any) {
|
|
126
|
+
return this._join(table, condition, "JOIN")
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public leftJoin(table: any | AnyAliasedTableDef, condition: any) {
|
|
130
|
+
return this._join(table, condition, "LEFT JOIN")
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private _join(table: AnyAliasedTableDef, condition: any, type: "JOIN" | "LEFT JOIN" = "JOIN") {
|
|
134
|
+
const sql = this._withQueries.has(table[SQL_ALIAS]) ? escapeId(table[SQL_ALIAS]) : table[SQL_EXPRESSION] + " as " + escapeId(table[SQL_ALIAS])
|
|
135
|
+
this._joins.push(type + " " + sql + " ON (" + condition.expression + ")")
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public window(name: string, func: (builder: Over<any>) => Over<any>) {
|
|
140
|
+
const builder2 = new Over()
|
|
141
|
+
func(builder2)
|
|
142
|
+
this._windows.push(name + " AS (" + builder2.toString() + ")")
|
|
143
|
+
return this
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public distinct() {
|
|
147
|
+
this._distinct = true;
|
|
148
|
+
return this
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public columns(...cols: (any | string | SqlExpression<string, string, any>)[]) {
|
|
152
|
+
for (let i = 0; i < cols.length; i++) {
|
|
153
|
+
const col = cols[i];
|
|
154
|
+
if (col instanceof SqlExpression) {
|
|
155
|
+
this._columns.push(col.expression + (col.nameAs ? " as " + escapeId(col.nameAs) : ""));
|
|
156
|
+
(this._columnStruct as any)[col.nameAs] = true;
|
|
157
|
+
if (col.transformer) {
|
|
158
|
+
this.transformers.push({property: col.nameAs, transformer: col.transformer});
|
|
159
|
+
}
|
|
160
|
+
} else if (typeof col === "string") {
|
|
161
|
+
this._columns.push(escapeId(col));
|
|
162
|
+
(this._columnStruct as any)[col] = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return this
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public one() {
|
|
169
|
+
this.columns(ONE())
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public allColumnsFrom(table: any | AnyAliasedTableDef) {
|
|
174
|
+
for (const k in table) {
|
|
175
|
+
this.columns(table[k])
|
|
176
|
+
}
|
|
177
|
+
return this
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public noWhere() {
|
|
181
|
+
return this as any
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public where(...cols: (any | undefined | null | "" | object | SqlExpression<string, string, any>)[]) {
|
|
185
|
+
for (let i = 0; i < cols.length; i++) {
|
|
186
|
+
const col = cols[i];
|
|
187
|
+
if (col instanceof SqlExpression) {
|
|
188
|
+
this._where.push(col.expression);
|
|
189
|
+
} else if (typeof col === "object") {
|
|
190
|
+
for (const prop in col) {
|
|
191
|
+
this._where.push(escapeId(prop) + " = " + escape(col[prop]));
|
|
192
|
+
}
|
|
193
|
+
} else if (col === undefined || col === null || col === "" || col === false) {
|
|
194
|
+
// skip
|
|
195
|
+
} else {
|
|
196
|
+
throw new Error("Invalid argument to where! Type: '" + (typeof col) + "' String: '" + String(col) + "'")
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return this as any
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public groupBy(...items: (any | SqlExpression<string, string, any>)[]) {
|
|
203
|
+
for (let i = 0; i < items.length; i++) {
|
|
204
|
+
const item = items[i];
|
|
205
|
+
if (item instanceof SqlExpression) {
|
|
206
|
+
this._groupBy.push(item.expression);
|
|
207
|
+
} else if (typeof item === "string") {
|
|
208
|
+
this._groupBy.push(escapeId(item));
|
|
209
|
+
} else if (item === undefined || item === null || item === "") {
|
|
210
|
+
// skip
|
|
211
|
+
} else {
|
|
212
|
+
throw new Error("Invalid argument to groupBy! Type: '" + (typeof item) + "' String: '" + String(item) + "'")
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return this as any
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public groupByF(func: (res: any | AliasedTable<string, string, Result, unknown, any>) => (any | SqlExpression<string, string, any>)[]) {
|
|
219
|
+
const proxy: any = new Proxy({}, {
|
|
220
|
+
get(target: {}, p: string, receiver: any): any {
|
|
221
|
+
if (p === "" || p === "undefined") {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
return new SqlExpression(p, p)
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
this.groupBy(...(func(proxy) as any));
|
|
228
|
+
return this as any
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public having(...items: (any | SqlExpression<string, string, any>)[]) {
|
|
232
|
+
for (let i = 0; i < items.length; i++) {
|
|
233
|
+
const item = items[i];
|
|
234
|
+
if (item instanceof SqlExpression) {
|
|
235
|
+
this._having.push(item.expression);
|
|
236
|
+
} else if (typeof item === "string") {
|
|
237
|
+
this._having.push(escapeId(item));
|
|
238
|
+
} else if (item === undefined || item === null || item === "") {
|
|
239
|
+
// skip
|
|
240
|
+
} else {
|
|
241
|
+
throw new Error("Invalid argument to having! Type: '" + (typeof item) + "' String: '" + String(item) + "'")
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return this as any
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
public havingF(func: (res: any | AliasedTable<string, string, Result, unknown, any>) => (any | SqlExpression<string, string, any>)[]) {
|
|
248
|
+
const proxy: any = new Proxy({}, {
|
|
249
|
+
get(target: {}, p: string, receiver: any): any {
|
|
250
|
+
if (p === "" || p === "undefined") {
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
return new SqlExpression(p, p)
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
this.having(...(func(proxy) as any));
|
|
257
|
+
return this
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public orderBy(...items: (any | SqlExpression<string, string, any>)[]) {
|
|
261
|
+
this._orderBy = orderByStructureToSqlString(items as any)
|
|
262
|
+
return this as any
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
public orderByF(func: (res: any | AliasedTable<string, string, Result, unknown, any>) => (any | SqlExpression<string, string, any>)[]) {
|
|
266
|
+
const proxy: any = new Proxy({}, {
|
|
267
|
+
get(target: {}, p: string, receiver: any): any {
|
|
268
|
+
if (p === "" || p === "undefined") {
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
271
|
+
return new SqlExpression(p, p)
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
this.orderBy(...(func(proxy) as any));
|
|
275
|
+
return this
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
public noLimit() {
|
|
279
|
+
return this as any
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
public limit(limit: number | [number, number]) {
|
|
283
|
+
if (Array.isArray(limit)) {
|
|
284
|
+
this._limit = Number(limit[0]) + "," + Number(limit[1]);
|
|
285
|
+
} else if (limit !== undefined && limit !== null && String(limit) !== "") {
|
|
286
|
+
this._limit = String(Number(limit));
|
|
287
|
+
}
|
|
288
|
+
return this as any
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
public limit1() {
|
|
292
|
+
return this.limit(1) as any
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
public forUpdate() {
|
|
296
|
+
this._forUpdate = true;
|
|
297
|
+
return this as any
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public asScalar(alias: any): any {
|
|
301
|
+
return SqlExpression.create("(\n" + this.toString(2) + TAB + ")", alias);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
public as(alias: any): any {
|
|
305
|
+
return MysqlTable.defineDbTable("(\n" + this.toString(2) + ")" as "(SUBQUERY)", alias, this._columnStruct)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public async transformResult<T>(rows: T[]): Promise<T[]> {
|
|
309
|
+
for (let r = 0; r < rows.length; r++) {
|
|
310
|
+
const row: any = rows[r];
|
|
311
|
+
for (let i = 0; i < this.transformers.length; i++) {
|
|
312
|
+
const parser = this.transformers[i]
|
|
313
|
+
const res = parser.transformer(row[parser.property]);
|
|
314
|
+
if (res instanceof Promise) {
|
|
315
|
+
row[parser.property] = await res;
|
|
316
|
+
} else {
|
|
317
|
+
row[parser.property] = res;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return rows;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
public toString(lvl: number = 0) {
|
|
325
|
+
if (this.transformers.length > 0) {
|
|
326
|
+
throw new Error("Select.toString() call might be accidental! This query uses transforms and it may cause errors in the application! " +
|
|
327
|
+
"This is safety measure to avoid executing queries that have transforms that would not get executed! " +
|
|
328
|
+
"You can call toSqlQuery() method to still get a sql string!")
|
|
329
|
+
}
|
|
330
|
+
return this._toString(lvl);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
public toSqlString() {
|
|
334
|
+
return this._toString();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private _toString(lvl: number = 0) {
|
|
338
|
+
const tabs = TAB.repeat(lvl);
|
|
339
|
+
let base: string;
|
|
340
|
+
if (this.unions.length > 0) {
|
|
341
|
+
base = this.unions.join("") + "\n";
|
|
342
|
+
} else {
|
|
343
|
+
base = (this._withQueries.size > 0 ? tabs + "WITH\n" + TAB + Array.from(this._withQueries.values()).join(",\n\n" + TAB) + "\n\n" : "") +
|
|
344
|
+
tabs + "SELECT " + (this._distinct ? "DISTINCT " : "") + "\n" +
|
|
345
|
+
tabs + TAB + this._columns.join(",\n" + tabs + TAB) + "\n" +
|
|
346
|
+
tabs + "FROM " + this._from + "\n" +
|
|
347
|
+
(this._joins.length > 0 ? tabs + this._joins.join("\n") + "\n" : "") +
|
|
348
|
+
(this._where.length > 0 ? tabs + "WHERE " + this._where.join("\n" + TAB + " AND ") + "\n" : "")
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return base +
|
|
352
|
+
(this._groupBy.length > 0 ? tabs + "GROUP BY " + this._groupBy.join(", ") + "\n" : "") +
|
|
353
|
+
(this._having.length > 0 ? tabs + "HAVING " + this._having.join("\n" + TAB + " AND ") + "\n" : "") +
|
|
354
|
+
(this._windows.length > 0 ? tabs + "WINDOW " + this._windows.join(",\n" + TAB) + "\n" : "") +
|
|
355
|
+
(this._orderBy.length > 0 ? tabs + "ORDER BY " + this._orderBy.join(", ") + "\n" : "") +
|
|
356
|
+
(this._limit ? tabs + "LIMIT " + this._limit + "\n" : "") +
|
|
357
|
+
(this._forUpdate && this.unions.length === 0 ? tabs + "FOR UPDATE\n" : "");
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
public async exec<Args extends any[]>(executor: SelectExecutor<Result, Args>, ...args: Args): Promise<Result[]> {
|
|
361
|
+
const res = await executor(this.toSqlString(), ...args);
|
|
362
|
+
if (res && res.length > 0 && this.transformers.length > 0) {
|
|
363
|
+
await this.transformResult(res)
|
|
364
|
+
}
|
|
365
|
+
return res;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
public async execOne<Args extends any[]>(executor: SelectExecutor<Result, Args>, ...args: Args): Promise<Result> {
|
|
369
|
+
return (await this.exec(executor, ...args))?.[0]
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {ExecMethods} from "./S7Exec";
|
|
2
|
+
import {OrderByStructure} from "../../Types";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export interface GatewayWhereMethods<Entity, Result> {
|
|
6
|
+
|
|
7
|
+
where(where: Partial<Entity>): GatewaySelectGroupByMethods<Entity, Result> & GatewaySelectOrderByMethods<Entity, Result> & GatewaySelectLimitMethods<Result> & ExecMethods<Result>
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface GatewaySelectGroupByMethods<Entity, Result> extends GatewaySelectLimitMethods<Result> {
|
|
12
|
+
|
|
13
|
+
groupBy(...fields: (keyof Entity)[]): GatewaySelectOrderByMethods<Entity, Result> & GatewaySelectLimitMethods<Result> & ExecMethods<Result>
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface GatewaySelectOrderByMethods<Entity, Result> extends GatewaySelectLimitMethods<Result> {
|
|
18
|
+
|
|
19
|
+
orderBy(...fields: OrderByStructure<keyof Entity>): GatewaySelectLimitMethods<Result> & ExecMethods<Result>
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface GatewaySelectLimitMethods<Result> {
|
|
24
|
+
|
|
25
|
+
noLimit(): ExecMethods<Result>
|
|
26
|
+
|
|
27
|
+
limit(limit: number | [number, number]): ExecMethods<Result>
|
|
28
|
+
|
|
29
|
+
limit1(): ExecMethods<Result>
|
|
30
|
+
|
|
31
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {ExecMethods} from "./S7Exec";
|
|
2
|
+
import {GroupByMethods} from "./S3GroupBy";
|
|
3
|
+
|
|
4
|
+
export interface UnionMethods<Result> {
|
|
5
|
+
|
|
6
|
+
union<Exec, MergedResult = Merge<Result, Exec>>(
|
|
7
|
+
table: Check<Result, Exec> & Exec
|
|
8
|
+
): UnionMethods<MergedResult> & GroupByMethods<MergedResult, {}>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
unionAll<Exec, MergedResult = Merge<Result, Exec>>(
|
|
12
|
+
table: Check<Result, Exec> & Exec
|
|
13
|
+
): UnionMethods<MergedResult> & GroupByMethods<MergedResult, {}>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type Check<Result1, Exec> = Exec extends ExecMethods<infer Result2>
|
|
17
|
+
? Key1Checker<Result1, Result2> extends never
|
|
18
|
+
? Key2Checker<Result1, Result2> extends never
|
|
19
|
+
? Exec
|
|
20
|
+
: Key2Checker<Result1, Result2>
|
|
21
|
+
: Key1Checker<Result1, Result2>
|
|
22
|
+
: never
|
|
23
|
+
|
|
24
|
+
type Key1Checker<Result1, Result2> = {
|
|
25
|
+
[K in keyof Result1]: K extends keyof Result2
|
|
26
|
+
? never
|
|
27
|
+
: `Missing column '${K extends string ? K : "???"}' on added union table! (...,${K extends string ? K : "???"}) UNION (..., ${K extends string ? K : "???"} <- Missing!)
|
|
28
|
+
`
|
|
29
|
+
// Empty line is intentional to have only this message as an Error and no obejct comparison.
|
|
30
|
+
}[keyof Result1]
|
|
31
|
+
|
|
32
|
+
type Key2Checker<Result1, Result2> = {
|
|
33
|
+
[K in keyof Result2]: K extends keyof Result1
|
|
34
|
+
? never
|
|
35
|
+
: `Column '${K extends string ? K : "???"}' does not exist in previous queries! (...) UNION (...,'${K extends string ? K : "???"}' <--- is a mistake (or add it to previous queries)!)
|
|
36
|
+
`
|
|
37
|
+
// Empty line is intentional to have only this message as an Error and no obejct comparison.
|
|
38
|
+
}[keyof Result2]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
type Merge<Result, Exec> = Exec extends ExecMethods<infer Result2> ? {
|
|
42
|
+
[K in keyof Result]: K extends keyof Result2 ? Result[K] | Result2[K] : never
|
|
43
|
+
} : never;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {AliasedTable, Key, NotUsingWithPart} from "../../Types";
|
|
2
|
+
import {JoinMethods} from "./S1Join";
|
|
3
|
+
|
|
4
|
+
export interface UsesMethods<Aliases, Tables> {
|
|
5
|
+
|
|
6
|
+
// uses<
|
|
7
|
+
// Alias extends string,
|
|
8
|
+
// TableRef extends `${string} as ${Alias}`
|
|
9
|
+
// >(
|
|
10
|
+
// table: isAliasAlreadyUsed<Aliases, Alias, AliasedTable<Alias, TableRef, any, NotUsingWithPart>>
|
|
11
|
+
// ): UsesMethods<Aliases & Key<Alias>, Tables & Key<TableRef>>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
selectFrom<
|
|
15
|
+
Alias extends string,
|
|
16
|
+
TableRef extends `${string} as ${Alias}`
|
|
17
|
+
>(
|
|
18
|
+
table: AliasedTable<Alias, TableRef, object, object, string | NotUsingWithPart>
|
|
19
|
+
): JoinMethods<Aliases & Key<Alias>, {}, Tables & Key<TableRef>>
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {AliasedTable, Key, NotUsingWithPart} from "../../Types";
|
|
2
|
+
import {JoinMethods} from "./S1Join";
|
|
3
|
+
|
|
4
|
+
export interface WithMethods<AliasesFromWith> {
|
|
5
|
+
|
|
6
|
+
// with<
|
|
7
|
+
// Alias extends string,
|
|
8
|
+
// TableRef extends `${string} as ${Alias}`
|
|
9
|
+
// >(
|
|
10
|
+
// table: isAliasAlreadyUsed<AliasesFromWith, Alias, AliasedTable<Alias, TableRef, object, NotUsingWithPart>>
|
|
11
|
+
// ): WithMethods<AliasesFromWith & Key<Alias>>
|
|
12
|
+
|
|
13
|
+
selectFrom<
|
|
14
|
+
Alias extends string,
|
|
15
|
+
TableRef extends `${string} as ${Alias}`
|
|
16
|
+
>(
|
|
17
|
+
table: AliasedTable<Alias, TableRef, object, object, string | NotUsingWithPart>
|
|
18
|
+
): JoinMethods<Key<Alias>, AliasesFromWith, Key<TableRef>>
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {AliasedTable, isAliasAlreadyUsed, isTableReferenced, Key, NotUsingWithPart, SQL_BOOL} from "../../Types";
|
|
2
|
+
import {Expr, Over} from "../../SqlExpression";
|
|
3
|
+
import {ColumnsMethods} from "./S2Columns";
|
|
4
|
+
|
|
5
|
+
export interface JoinMethods<Aliases, AliasesFromWith, Tables> extends ColumnsMethods<{}, Tables> {
|
|
6
|
+
|
|
7
|
+
join<
|
|
8
|
+
Alias extends string,
|
|
9
|
+
TableRef extends `${string} as ${Alias}`,
|
|
10
|
+
RefAlias extends NotUsingWithPart | string,
|
|
11
|
+
ColTableRef extends string
|
|
12
|
+
>(
|
|
13
|
+
table: isRefAliasInAliasesFromWith<AliasesFromWith, RefAlias, isAliasAlreadyUsed<Aliases & AliasesFromWith, Alias, AliasedTable<Alias, TableRef, object, object, RefAlias>>>,
|
|
14
|
+
condition: isConditionUsingJoinedTable<TableRef, ColTableRef, isTableReferenced<Tables & Key<TableRef>, Key<ColTableRef>, Expr<ColTableRef, unknown, SQL_BOOL>>>
|
|
15
|
+
): JoinMethods<Aliases & Key<Alias>, AliasesFromWith, Tables & Key<TableRef>>
|
|
16
|
+
|
|
17
|
+
leftJoin<
|
|
18
|
+
Alias extends string,
|
|
19
|
+
TableRef extends `${string} as ${Alias}`,
|
|
20
|
+
RefAlias extends NotUsingWithPart | string,
|
|
21
|
+
ColTableRef extends string
|
|
22
|
+
>(
|
|
23
|
+
table: isRefAliasInAliasesFromWith<AliasesFromWith, RefAlias, isAliasAlreadyUsed<Aliases & AliasesFromWith, Alias, AliasedTable<Alias, TableRef, object, object, RefAlias>>>,
|
|
24
|
+
condition: isConditionUsingJoinedTable<TableRef, ColTableRef, isTableReferenced<Tables & Key<TableRef>, Key<ColTableRef>, Expr<ColTableRef, unknown, SQL_BOOL>>>
|
|
25
|
+
): JoinMethods<Aliases & Key<Alias>, AliasesFromWith, Tables & Key<TableRef>>
|
|
26
|
+
|
|
27
|
+
window<
|
|
28
|
+
WindowName extends string,
|
|
29
|
+
UsedTablesRef extends string
|
|
30
|
+
>(
|
|
31
|
+
name: isAliasAlreadyUsed<Aliases & AliasesFromWith, WindowName, WindowName>,
|
|
32
|
+
func: (builder: Over<never>) => Over<UsedTablesRef>
|
|
33
|
+
): JoinMethods<Aliases & Key<WindowName>, AliasesFromWith, Tables & Key<`(window) as ${WindowName}`>>
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type isConditionUsingJoinedTable<TableRef, ColTableRef, OUT> = TableRef extends ColTableRef ? OUT : "Join condition should use columns from the joined table!"
|
|
38
|
+
|
|
39
|
+
type isRefAliasInAliasesFromWith<AliasesFromWith, RefAlias, OUT> = RefAlias extends NotUsingWithPart | string & keyof AliasesFromWith ? OUT : `Alias '${RefAlias extends string ? RefAlias : RefAlias extends NotUsingWithPart ? "NOT_REFERENCED" : "???"}' is not defined by any of the with queries!`
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {WhereMethods} from "./S2Where";
|
|
2
|
+
import {Expr} from "../../SqlExpression";
|
|
3
|
+
import {AliasedTable, NotUsingWithPart} from "../../Types";
|
|
4
|
+
|
|
5
|
+
export interface ColumnsMethods<Result, Tables> {
|
|
6
|
+
|
|
7
|
+
distinct(): ColumnsMethods<Result, Tables>
|
|
8
|
+
|
|
9
|
+
allColumnsFrom<TableRef, Entity, Result2 = Result & Entity>(table: AliasedTable<string, TableRef, Entity, any, NotUsingWithPart>): ColumnsMethods<Result2, Tables> & WhereMethods<Result2, Tables>
|
|
10
|
+
|
|
11
|
+
one(): WhereMethods<Result & { one: 1 }, Tables>
|
|
12
|
+
|
|
13
|
+
columns<
|
|
14
|
+
TableRef,
|
|
15
|
+
Columns extends Expr<TableRef, string, any>[]
|
|
16
|
+
>(
|
|
17
|
+
//...columns: Columns - this will enable seeing sources of Result object properties.
|
|
18
|
+
...columns: isColumnOkToAdd<Result, Tables, Columns>
|
|
19
|
+
): WhereMethods<Result & ExtractObj<Columns>, Tables>
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// --------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Take array of Col-s and convert to Record<key, value> & ... object.
|
|
27
|
+
*/
|
|
28
|
+
export type ExtractObj<Columns extends Expr<any, string, any>[]> = {
|
|
29
|
+
[K in Columns[number]['nameAs']]: Extract<Columns[number], { nameAs: K }>['type']
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
// --------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
type _checkIfExistsInOtherFields<Rest extends any[], Expr> =
|
|
36
|
+
Rest extends []
|
|
37
|
+
? Expr
|
|
38
|
+
: Expr extends { nameAs: string } ?
|
|
39
|
+
Expr["nameAs"] extends (Rest extends { nameAs: infer A }[] ? A : never)
|
|
40
|
+
? `'${Expr["nameAs"]}' already exists in columns!`
|
|
41
|
+
: Expr
|
|
42
|
+
: Expr extends { nameAs: unknown } ?
|
|
43
|
+
`Is missing column name. Add .as('name')`
|
|
44
|
+
: Expr
|
|
45
|
+
|
|
46
|
+
type _checkIfExistsInResult<Result, Expr> =
|
|
47
|
+
Expr extends { nameAs: string } ?
|
|
48
|
+
Expr["nameAs"] extends keyof Result
|
|
49
|
+
? `'${Expr["nameAs"]}' already exists in result columns!`
|
|
50
|
+
: Expr
|
|
51
|
+
: Expr
|
|
52
|
+
|
|
53
|
+
type _checkThatTableIsReferenced<Tables, Expr> =
|
|
54
|
+
Expr extends { tableRef: string } ?
|
|
55
|
+
Expr["tableRef"] extends keyof Tables
|
|
56
|
+
? Expr
|
|
57
|
+
: `'${Expr["tableRef"]}' is not used in this query!`
|
|
58
|
+
: Expr
|
|
59
|
+
|
|
60
|
+
type isColumnOkToAdd<Result, Tables, ColumnExpressions> =
|
|
61
|
+
ColumnExpressions extends []
|
|
62
|
+
? ColumnExpressions
|
|
63
|
+
: ColumnExpressions extends [...(infer Rest), infer A]
|
|
64
|
+
? [...isColumnOkToAdd<Result, Tables, Rest>, _checkIfExistsInOtherFields<Rest, _checkIfExistsInResult<Result, _checkThatTableIsReferenced<Tables, A>>>]
|
|
65
|
+
: ColumnExpressions;
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
// --------------------------------------------------------------------
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {isTableReferenced, Key, SQL_BOOL} from "../../Types";
|
|
2
|
+
import {GroupByMethods} from "./S3GroupBy";
|
|
3
|
+
import {Expr} from "../../SqlExpression";
|
|
4
|
+
import {OrderByMethods} from "./S5OrderBy";
|
|
5
|
+
import {LimitMethods} from "./S6Limit";
|
|
6
|
+
import {ExecMethods} from "./S7Exec";
|
|
7
|
+
|
|
8
|
+
export interface WhereMethods<Result, Tables> {
|
|
9
|
+
|
|
10
|
+
noWhere(): GroupByMethods<Result, Tables> & OrderByMethods<Result, Tables> & LimitMethods<Result> & ExecMethods<Result>
|
|
11
|
+
|
|
12
|
+
where<
|
|
13
|
+
T1 extends string,
|
|
14
|
+
T2 extends string = never,
|
|
15
|
+
T3 extends string = never,
|
|
16
|
+
T4 extends string = never,
|
|
17
|
+
T5 extends string = never,
|
|
18
|
+
T6 extends string = never,
|
|
19
|
+
T7 extends string = never,
|
|
20
|
+
T8 extends string = never,
|
|
21
|
+
T9 extends string = never,
|
|
22
|
+
T10 extends string = never,
|
|
23
|
+
T11 extends string = never,
|
|
24
|
+
T12 extends string = never,
|
|
25
|
+
T13 extends string = never,
|
|
26
|
+
T14 extends string = never,
|
|
27
|
+
T15 extends string = never,
|
|
28
|
+
T = Tables
|
|
29
|
+
>(
|
|
30
|
+
c1: C<T, T1>,
|
|
31
|
+
c2?: C<T, T2>,
|
|
32
|
+
c3?: C<T, T3>,
|
|
33
|
+
c4?: C<T, T4>,
|
|
34
|
+
c5?: C<T, T5>,
|
|
35
|
+
c6?: C<T, T6>,
|
|
36
|
+
c7?: C<T, T7>,
|
|
37
|
+
c8?: C<T, T8>,
|
|
38
|
+
c9?: C<T, T9>,
|
|
39
|
+
c10?: C<T, T10>,
|
|
40
|
+
c11?: C<T, T11>,
|
|
41
|
+
c12?: C<T, T12>,
|
|
42
|
+
c13?: C<T, T13>,
|
|
43
|
+
c14?: C<T, T14>,
|
|
44
|
+
c15?: C<T, T15>,
|
|
45
|
+
): GroupByMethods<Result, Tables> & OrderByMethods<Result, Tables> & LimitMethods<Result> & ExecMethods<Result>
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type C<Tables, T extends string> = isTableReferenced<Tables, Key<T>, Expr<T, unknown, SQL_BOOL>>
|
|
50
|
+
|
|
51
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {AliasedTable, isColumnOkToUse, Key, NotUsingWithPart} from "../../Types";
|
|
2
|
+
import {HavingMethods} from "./S4Having";
|
|
3
|
+
import {Expr} from "../../SqlExpression";
|
|
4
|
+
import {OrderByMethods} from "./S5OrderBy";
|
|
5
|
+
import {LimitMethods} from "./S6Limit";
|
|
6
|
+
|
|
7
|
+
export interface GroupByMethods<Result, Tables> extends OrderByMethods<Result, Tables>, LimitMethods<Result> {
|
|
8
|
+
groupBy<
|
|
9
|
+
TableRef,
|
|
10
|
+
Columns extends Expr<TableRef, string | unknown, any>[]
|
|
11
|
+
>(
|
|
12
|
+
...items: isColumnOkToUse<Tables, Columns>
|
|
13
|
+
): HavingMethods<Result, Tables>
|
|
14
|
+
|
|
15
|
+
groupByF<
|
|
16
|
+
TableRef,
|
|
17
|
+
Columns extends Expr<TableRef, string | unknown, any>[]
|
|
18
|
+
>(
|
|
19
|
+
func: (columnsTable: AliasedTable<"(columns)", "(columns)", Result, object, NotUsingWithPart>) => isColumnOkToUse<Tables & Key<"(columns)">, Columns>
|
|
20
|
+
): HavingMethods<Result, Tables>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|