sasat 0.21.21 → 0.22.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/dist/cli/index.cjs +604 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +604 -0
- package/dist/index.cjs +773 -943
- package/dist/index.d.cts +1047 -987
- package/dist/index.d.mts +1047 -987
- package/dist/index.mjs +765 -924
- package/dist/migrate-Cc47Mufl.cjs +4165 -0
- package/dist/migrate-DfAkhVPb.mjs +3947 -0
- package/package.json +24 -27
- package/dist/cli/cli.cjs +0 -5626
- package/dist/cli/cli.d.cts +0 -1
- package/dist/cli/cli.d.mts +0 -1
- package/dist/cli/cli.d.ts +0 -1
- package/dist/cli/cli.mjs +0 -5601
- package/dist/index.d.ts +0 -1167
- package/dist/shared/sasat.CFfsuShk.mjs +0 -398
- package/dist/shared/sasat.DHiyRw3a.cjs +0 -436
package/dist/index.mjs
CHANGED
|
@@ -1,1022 +1,863 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
})(QueryNodeKind || {});
|
|
32
|
-
|
|
1
|
+
import { D as setConfig, a as getDbClient, b as unique, c as formatQuery, d as SasatError, j as assignDeep, m as Conditions, o as MySqlTransaction, s as DBClient, t as migrate, u as SqlString, v as nonNullable, y as pick } from "./migrate-DfAkhVPb.mjs";
|
|
2
|
+
import * as SqlString$1 from "sqlstring";
|
|
3
|
+
import { createConnection } from "mysql2/promise";
|
|
4
|
+
//#region src/db/connectors/mysql/client.ts
|
|
5
|
+
var MysqlClient = class extends DBClient {
|
|
6
|
+
async release() {}
|
|
7
|
+
constructor(connectionOption, logger) {
|
|
8
|
+
super(logger);
|
|
9
|
+
this.connectionOption = connectionOption;
|
|
10
|
+
}
|
|
11
|
+
getConnection() {
|
|
12
|
+
return createConnection({
|
|
13
|
+
dateStrings: true,
|
|
14
|
+
...this.connectionOption
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
async transaction() {
|
|
18
|
+
const connection = await this.getConnection();
|
|
19
|
+
await connection.beginTransaction();
|
|
20
|
+
return new MySqlTransaction(connection);
|
|
21
|
+
}
|
|
22
|
+
async execSql(sql) {
|
|
23
|
+
const connection = await this.getConnection();
|
|
24
|
+
const r = await connection.query(sql);
|
|
25
|
+
await connection.end();
|
|
26
|
+
return r[0];
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/runtime/dsl/query/sql/nodeToSql.ts
|
|
33
31
|
function partitionBy(ids) {
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
if (!ids || ids.length === 0) return "";
|
|
33
|
+
return `PARTITION BY ${ids.map(Sql.identifier).join(",")} `;
|
|
36
34
|
}
|
|
37
35
|
function orderBy(sorts) {
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
if (!sorts || sorts.length === 0) return "";
|
|
37
|
+
return `ORDER BY ${sorts.map(Sql.sort).join(",")} `;
|
|
40
38
|
}
|
|
41
39
|
function windowValue(value) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
return value.type;
|
|
40
|
+
if (value.type === "FOLLOWING" || value.type === "PRECEDING") return `${value.value} ${value.type}`;
|
|
41
|
+
return value.type;
|
|
46
42
|
}
|
|
47
|
-
function window$1(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
return `${window2.type} ${windowValue(window2.value)}`;
|
|
43
|
+
function window$1(window) {
|
|
44
|
+
if (!window) return "";
|
|
45
|
+
if (window.between) return `${window.type} BETWEEN ${windowValue(window.start)} AND ${window.end}`;
|
|
46
|
+
return `${window.type} ${windowValue(window.value)}`;
|
|
53
47
|
}
|
|
54
48
|
function over(v) {
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
if (!v) return "";
|
|
50
|
+
return `OVER (${partitionBy(v.partitionBy)}${orderBy(v.orderBy)}${window$1(v.window)})`;
|
|
57
51
|
}
|
|
58
|
-
const SELECT_ALIAS_SEPARATOR = "__";
|
|
59
52
|
const Sql = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return `EXISTS (${Sql.queryOrRaw(expr.query)})`;
|
|
145
|
-
},
|
|
146
|
-
sort: (expr) => {
|
|
147
|
-
const field = () => {
|
|
148
|
-
switch (expr.field.kind) {
|
|
149
|
-
case QueryNodeKind.Field:
|
|
150
|
-
return Sql.fieldInCondition(expr.field);
|
|
151
|
-
case QueryNodeKind.Identifier:
|
|
152
|
-
return Sql.identifier(expr.field);
|
|
153
|
-
default:
|
|
154
|
-
return Sql.fn(expr.field);
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
if (expr.direction)
|
|
158
|
-
return `${field()} ${expr.direction === "DESC" ? "DESC" : "ASC"}`;
|
|
159
|
-
return field();
|
|
160
|
-
},
|
|
161
|
-
sorts: (sorts) => sorts.map(Sql.sort).join(", "),
|
|
162
|
-
queryOrRaw: (expr) => {
|
|
163
|
-
if ("kind" in expr) {
|
|
164
|
-
return expr.expr;
|
|
165
|
-
}
|
|
166
|
-
return queryToSql(expr);
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
|
|
53
|
+
select: (expr) => {
|
|
54
|
+
switch (expr.kind) {
|
|
55
|
+
case 15: return expr.expr;
|
|
56
|
+
case 0: return Sql.fieldInSelect(expr);
|
|
57
|
+
case 13: return Sql.identifier(expr);
|
|
58
|
+
case 1: return Sql.fn(expr);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
literal: (literal) => SqlString.escape(literal.value),
|
|
62
|
+
fieldInCondition: (identifier) => SqlString.escapeId(identifier.table) + "." + SqlString.escapeId(identifier.name),
|
|
63
|
+
fieldInSelect: (identifier) => {
|
|
64
|
+
const alias = identifier.alias && identifier.name !== identifier.alias ? " AS " + SqlString.escapeId(identifier.alias) : "";
|
|
65
|
+
return SqlString.escapeId(identifier.table) + "." + SqlString.escapeId(identifier.name) + alias;
|
|
66
|
+
},
|
|
67
|
+
identifier: (ident) => {
|
|
68
|
+
return SqlString.escapeId(ident.identifier);
|
|
69
|
+
},
|
|
70
|
+
fn: (fn) => `${fn.fnName}(${fn.args.map(Sql.value).join(",")})${over(fn.over)}${fn.alias ? ` AS ${fn.alias}` : ""}`,
|
|
71
|
+
value: (v) => {
|
|
72
|
+
if (v.kind === 1) return Sql.fn(v);
|
|
73
|
+
if (v.kind === 0) return Sql.fieldInCondition(v);
|
|
74
|
+
if (v.kind === 13) return Sql.identifier(v);
|
|
75
|
+
return Sql.literal(v);
|
|
76
|
+
},
|
|
77
|
+
between: (expr) => `${Sql.value(expr.left)} BETWEEN ${Sql.value(expr.begin)} AND ${Sql.value(expr.end)}`,
|
|
78
|
+
contains: (expr) => {
|
|
79
|
+
const operator = expr.isNot ? "NOT LIKE" : "LIKE";
|
|
80
|
+
const val = (value, type) => {
|
|
81
|
+
if (type === "contains") return "%" + value + "%";
|
|
82
|
+
if (type === "start") return "%" + value;
|
|
83
|
+
return value + "%";
|
|
84
|
+
};
|
|
85
|
+
return `${Sql.value(expr.left)} ${operator} ${SqlString.escape(val(expr.right, expr.type))}`;
|
|
86
|
+
},
|
|
87
|
+
in: (expr) => {
|
|
88
|
+
if ("right" in expr) return `${Sql.value(expr.left)} ${expr.operator} (${expr.right.map(Sql.value).join(", ")})`;
|
|
89
|
+
return `${Sql.value(expr.left)} ${expr.operator} (${Sql.queryOrRaw(expr.query)})`;
|
|
90
|
+
},
|
|
91
|
+
comparison: (expr) => `${Sql.value(expr.left)} ${expr.operator} ${Sql.value(expr.right)}`,
|
|
92
|
+
compound: (expr) => `${Sql.booleanValue(expr.left)} ${expr.operator} ${Sql.booleanValue(expr.right)}`,
|
|
93
|
+
isNull: (expr) => `${Sql.value(expr.expr)} ${expr.isNot ? "IS NOT NULL" : "IS NULL"}`,
|
|
94
|
+
paren: (expr) => "(" + Sql.booleanValue(expr.expression) + ")",
|
|
95
|
+
table: (table) => {
|
|
96
|
+
if (!table.subquery) {
|
|
97
|
+
if (table.alias === table.name) return SqlString.escapeId(table.name);
|
|
98
|
+
return SqlString.escapeId(table.name) + " AS " + SqlString.escapeId(table.alias);
|
|
99
|
+
}
|
|
100
|
+
return `(${queryToSql(table.query)}) AS ${SqlString.escapeId(table.alias)}`;
|
|
101
|
+
},
|
|
102
|
+
join: (join) => `${join.type ? join.type + " " : ""}JOIN ${Sql.table(join.table)} ON ` + Sql.booleanValue(join.conditions),
|
|
103
|
+
booleanValue: (expr) => {
|
|
104
|
+
switch (expr.kind) {
|
|
105
|
+
case 9: return Sql.between(expr);
|
|
106
|
+
case 4: return Sql.compound(expr);
|
|
107
|
+
case 5: return Sql.comparison(expr);
|
|
108
|
+
case 10: return Sql.contains(expr);
|
|
109
|
+
case 7: return Sql.paren(expr);
|
|
110
|
+
case 8: return Sql.in(expr);
|
|
111
|
+
case 6: return Sql.isNull(expr);
|
|
112
|
+
case 14: return Sql.exists(expr);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
exists: (expr) => {
|
|
116
|
+
return `EXISTS (${Sql.queryOrRaw(expr.query)})`;
|
|
117
|
+
},
|
|
118
|
+
sort: (expr) => {
|
|
119
|
+
const field = () => {
|
|
120
|
+
switch (expr.field.kind) {
|
|
121
|
+
case 0: return Sql.fieldInCondition(expr.field);
|
|
122
|
+
case 13: return Sql.identifier(expr.field);
|
|
123
|
+
default: return Sql.fn(expr.field);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
if (expr.direction) return `${field()} ${expr.direction === "DESC" ? "DESC" : "ASC"}`;
|
|
127
|
+
return field();
|
|
128
|
+
},
|
|
129
|
+
sorts: (sorts) => sorts.map(Sql.sort).join(", "),
|
|
130
|
+
queryOrRaw: (expr) => {
|
|
131
|
+
if ("kind" in expr) return expr.expr;
|
|
132
|
+
return queryToSql(expr);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/runtime/dsl/query/sql/queryToSql.ts
|
|
170
137
|
const getJoin = (from) => {
|
|
171
|
-
|
|
138
|
+
return from.joins.flatMap((join) => [join, ...getJoin(join.table)]);
|
|
172
139
|
};
|
|
173
140
|
const getLock = (lock) => {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
141
|
+
if (!lock) return "";
|
|
142
|
+
if (lock === "FOR UPDATE") return " FOR UPDATE";
|
|
143
|
+
return " FOR SHARE";
|
|
177
144
|
};
|
|
178
145
|
const queryToSql = (query) => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
146
|
+
const select = query.select.map(Sql.select).join(", ");
|
|
147
|
+
const join = getJoin(query.from).map(Sql.join).join(" ");
|
|
148
|
+
const where = query.where ? " WHERE " + Sql.booleanValue(query.where) : "";
|
|
149
|
+
const groupBy = query.groupBy ? " GROUP BY" + query.groupBy.cols.map(Sql.value).join(",") : "";
|
|
150
|
+
const having = query.having ? "HAVING " + Sql.booleanValue(query.having) : "";
|
|
151
|
+
const sort = query.sort && query.sort.length !== 0 ? " ORDER BY " + Sql.sorts(query.sort) : "";
|
|
152
|
+
const limit = query.limit ? " LIMIT " + query.limit : "";
|
|
153
|
+
const offset = query.offset ? " OFFSET " + query.offset : "";
|
|
154
|
+
if (offset && !limit) throw new Error("LIMIT is required to use OFFSET.");
|
|
155
|
+
return `SELECT ${select} FROM ${Sql.table(query.from)}` + join + where + groupBy + having + sort + limit + offset + getLock(query.lock);
|
|
156
|
+
};
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/db/sql/expression/comparison.ts
|
|
159
|
+
let Comparison = /* @__PURE__ */ function(Comparison) {
|
|
160
|
+
Comparison["eq"] = "=";
|
|
161
|
+
Comparison["gt"] = ">";
|
|
162
|
+
Comparison["lt"] = "<";
|
|
163
|
+
Comparison["gte"] = ">=";
|
|
164
|
+
Comparison["lte"] = "<=";
|
|
165
|
+
Comparison["neq"] = "<>";
|
|
166
|
+
Comparison["like"] = "LIKE";
|
|
167
|
+
Comparison["notLike"] = "NOT LIKE";
|
|
168
|
+
return Comparison;
|
|
169
|
+
}({});
|
|
170
|
+
const comparisonExpressionToSql = (exp) => {
|
|
171
|
+
const type = Object.hasOwn(exp, "__type") ? exp.__type || "AND" : "AND";
|
|
172
|
+
return Object.entries(exp).map(([key, value]) => {
|
|
173
|
+
const column = SqlString$1.escapeId(key);
|
|
174
|
+
if (!Array.isArray(value)) return `${column} = ${SqlString$1.escape(value)}`;
|
|
175
|
+
if (value[0] === "IS NULL") return `${column} IS NULL`;
|
|
176
|
+
if (value[0] === "IS NOT NULL") return `${column} IS NOT NULL`;
|
|
177
|
+
if (value[0] === "IN") {
|
|
178
|
+
const [, ...columns] = value;
|
|
179
|
+
return `${column} IN (${[columns.map((column) => SqlString$1.escape(column)).join(", ")]})`;
|
|
180
|
+
}
|
|
181
|
+
if (value[0] === "BETWEEN") return `${column} BETWEEN ${SqlString$1.escape(value[1])} AND ${SqlString$1.escape(value[2])}`;
|
|
182
|
+
if (Object.keys(Comparison).includes(value[0])) return `${column} ${value[0]} ${SqlString$1.escape(value[1])}`;
|
|
183
|
+
throw new SasatError("SQL PARSE ERROR");
|
|
184
|
+
}).join(` ${type} `);
|
|
185
|
+
};
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/db/sql/expression/conditionExpression.ts
|
|
188
|
+
const conditionExpressionToSql = (exp) => {
|
|
189
|
+
if (Array.isArray(exp)) return CompositeCondition.and(exp).toSQL();
|
|
190
|
+
if (exp instanceof CompositeCondition) return exp.toSQL();
|
|
191
|
+
return comparisonExpressionToSql(exp);
|
|
192
|
+
};
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region src/db/sql/expression/compositeCondition.ts
|
|
195
|
+
var CompositeCondition = class CompositeCondition {
|
|
196
|
+
constructor(type, conditions) {
|
|
197
|
+
this.type = type;
|
|
198
|
+
this.conditions = conditions;
|
|
199
|
+
}
|
|
200
|
+
static or(conditions) {
|
|
201
|
+
return new CompositeCondition("OR", conditions);
|
|
202
|
+
}
|
|
203
|
+
static and(conditions) {
|
|
204
|
+
return new CompositeCondition("AND", conditions);
|
|
205
|
+
}
|
|
206
|
+
toSQL() {
|
|
207
|
+
return "(" + this.conditions.map(conditionExpressionToSql).join(this.type) + ")";
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/migration/makeMutaion.ts
|
|
212
|
+
const formatSubscription = (subscription) => {
|
|
213
|
+
if (subscription === void 0 || subscription === false) return {
|
|
214
|
+
enabled: false,
|
|
215
|
+
subscriptionFilter: []
|
|
216
|
+
};
|
|
217
|
+
if (subscription === true) return {
|
|
218
|
+
enabled: true,
|
|
219
|
+
subscriptionFilter: []
|
|
220
|
+
};
|
|
221
|
+
return {
|
|
222
|
+
enabled: subscription.enabled,
|
|
223
|
+
subscriptionFilter: subscription.subscriptionFilter || []
|
|
224
|
+
};
|
|
196
225
|
};
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
226
|
+
const formatOptions = (type, option) => ({
|
|
227
|
+
type,
|
|
228
|
+
noReFetch: option?.noRefetch || false,
|
|
229
|
+
middlewares: option?.middlewares || [],
|
|
230
|
+
contextFields: option?.contextFields || [],
|
|
231
|
+
subscription: formatSubscription(option?.subscription)
|
|
232
|
+
});
|
|
233
|
+
const Mutations = {
|
|
234
|
+
create: (options) => formatOptions("create", options),
|
|
235
|
+
update: (options) => formatOptions("update", options),
|
|
236
|
+
delete: (options) => formatOptions("delete", options)
|
|
203
237
|
};
|
|
204
|
-
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/migration/makeQuery.ts
|
|
205
240
|
const single = (name, options) => ({
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
241
|
+
type: "single",
|
|
242
|
+
name,
|
|
243
|
+
conditions: options?.conditions || [],
|
|
244
|
+
middlewares: options?.middlewares || []
|
|
210
245
|
});
|
|
211
246
|
const listAll = (name, options) => ({
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
247
|
+
type: "list-all",
|
|
248
|
+
name,
|
|
249
|
+
conditions: options?.conditions || [],
|
|
250
|
+
middlewares: options?.middlewares || []
|
|
216
251
|
});
|
|
217
252
|
const paging = (name, options) => ({
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
253
|
+
type: "list-paging",
|
|
254
|
+
name,
|
|
255
|
+
conditions: options?.conditions || [],
|
|
256
|
+
middlewares: options?.middlewares || []
|
|
222
257
|
});
|
|
223
258
|
const primary = (middlewares = []) => ({
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
259
|
+
type: "primary",
|
|
260
|
+
conditions: [],
|
|
261
|
+
middlewares
|
|
227
262
|
});
|
|
228
263
|
const Queries = {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
264
|
+
single,
|
|
265
|
+
listAll,
|
|
266
|
+
paging,
|
|
267
|
+
primary
|
|
233
268
|
};
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
subscriptionFilter: []
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
if (subscription === true)
|
|
243
|
-
return {
|
|
244
|
-
enabled: true,
|
|
245
|
-
subscriptionFilter: []
|
|
246
|
-
};
|
|
247
|
-
return {
|
|
248
|
-
enabled: subscription.enabled,
|
|
249
|
-
subscriptionFilter: subscription.subscriptionFilter || []
|
|
250
|
-
};
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/runtime/createTypeDef.ts
|
|
271
|
+
const makeArgs = (args) => {
|
|
272
|
+
if (!args || args.length === 0) return "";
|
|
273
|
+
return `(${args.map((arg) => `${arg.name}: ${arg.type}`).join(", ")})`;
|
|
251
274
|
};
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
275
|
+
const makeTypedefString = (typeName, typedef, type) => {
|
|
276
|
+
const entries = Object.entries(typedef);
|
|
277
|
+
if (entries.length === 0) return "";
|
|
278
|
+
return `\
|
|
279
|
+
${type} ${typeName} {
|
|
280
|
+
${entries.map(([field, value]) => {
|
|
281
|
+
if (!value.return) throw new Error(`Return type required: ${typeName}.${field}`);
|
|
282
|
+
return ` ${field}${makeArgs(value.args)}: ${value.return}`;
|
|
283
|
+
}).join("\n")}
|
|
284
|
+
}
|
|
285
|
+
`;
|
|
263
286
|
};
|
|
264
|
-
|
|
287
|
+
const createTypeDef = (typeDefs, inputs) => {
|
|
288
|
+
const types = Object.entries(typeDefs).map(([type, fields]) => makeTypedefString(type, fields, "type"));
|
|
289
|
+
const input = Object.entries(inputs).map(([type, fields]) => makeTypedefString(type, fields, "input"));
|
|
290
|
+
return types.join("\n") + input.join("\n");
|
|
291
|
+
};
|
|
292
|
+
//#endregion
|
|
293
|
+
//#region src/runtime/dsl/factory.ts
|
|
265
294
|
const compound = (expr, operator) => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
295
|
+
const active = expr.filter(nonNullable);
|
|
296
|
+
if (active.length === 0) return conditions.eq(literal(1), literal(1));
|
|
297
|
+
return active.reduce((acc, current) => ({
|
|
298
|
+
kind: 4,
|
|
299
|
+
left: acc,
|
|
300
|
+
operator,
|
|
301
|
+
right: current
|
|
302
|
+
}));
|
|
274
303
|
};
|
|
275
304
|
const containsExpr = (isNot, type) => (left, right) => ({
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
305
|
+
kind: 10,
|
|
306
|
+
type,
|
|
307
|
+
left,
|
|
308
|
+
isNot,
|
|
309
|
+
right
|
|
281
310
|
});
|
|
282
311
|
const comparison = (operator) => (left, right) => ({
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
312
|
+
kind: 5,
|
|
313
|
+
left,
|
|
314
|
+
operator,
|
|
315
|
+
right
|
|
287
316
|
});
|
|
288
317
|
const and = (...expr) => compound(expr, "AND");
|
|
289
318
|
const or = (...expr) => compound(expr, "OR");
|
|
290
|
-
const field = (
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
319
|
+
const field = (table, name, alias) => ({
|
|
320
|
+
kind: 0,
|
|
321
|
+
table,
|
|
322
|
+
name,
|
|
323
|
+
alias
|
|
295
324
|
});
|
|
296
325
|
const fn = (fnName, args, alias) => ({
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
326
|
+
kind: 1,
|
|
327
|
+
fnName,
|
|
328
|
+
args,
|
|
329
|
+
alias
|
|
301
330
|
});
|
|
302
331
|
const window = (type, value) => ({
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
332
|
+
kind: 18,
|
|
333
|
+
type,
|
|
334
|
+
between: false,
|
|
335
|
+
value
|
|
307
336
|
});
|
|
308
337
|
const windowBetween = (type, start, end) => ({
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
338
|
+
kind: 18,
|
|
339
|
+
type,
|
|
340
|
+
between: true,
|
|
341
|
+
start,
|
|
342
|
+
end
|
|
314
343
|
});
|
|
315
344
|
const paren = (expression) => ({
|
|
316
|
-
|
|
317
|
-
|
|
345
|
+
kind: 7,
|
|
346
|
+
expression
|
|
318
347
|
});
|
|
319
348
|
const In = (left, right) => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
349
|
+
if (Array.isArray(right)) {
|
|
350
|
+
if (right.length === 0) return conditions.eq(literal(0), literal(1));
|
|
351
|
+
return {
|
|
352
|
+
kind: 8,
|
|
353
|
+
left,
|
|
354
|
+
operator: "IN",
|
|
355
|
+
right: right.map(literal)
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
kind: 8,
|
|
360
|
+
left,
|
|
361
|
+
operator: "IN",
|
|
362
|
+
query: right
|
|
363
|
+
};
|
|
335
364
|
};
|
|
336
365
|
const notIn = (left, values) => ({
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
366
|
+
kind: 8,
|
|
367
|
+
left,
|
|
368
|
+
operator: "NOT IN",
|
|
369
|
+
right: values.map(literal)
|
|
341
370
|
});
|
|
342
371
|
const between = (left, begin, end) => ({
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
372
|
+
kind: 9,
|
|
373
|
+
left,
|
|
374
|
+
begin,
|
|
375
|
+
end
|
|
347
376
|
});
|
|
348
377
|
const isNull = (isNot) => (expr) => ({
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
378
|
+
kind: 6,
|
|
379
|
+
expr,
|
|
380
|
+
isNot
|
|
352
381
|
});
|
|
353
382
|
const simpleWhere = (tableNameOrAlias, where, isOr = false) => {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return comparison(value[0])(fe, literal(value[1]));
|
|
360
|
-
return conditions.eq(fe, literal(value));
|
|
361
|
-
})
|
|
362
|
-
);
|
|
383
|
+
return (isOr ? or : and)(...Object.entries(where).map(([f, value]) => {
|
|
384
|
+
const fe = field(tableNameOrAlias, f);
|
|
385
|
+
if (Array.isArray(value)) return comparison(value[0])(fe, literal(value[1]));
|
|
386
|
+
return conditions.eq(fe, literal(value));
|
|
387
|
+
}));
|
|
363
388
|
};
|
|
364
389
|
const exists = (query) => ({
|
|
365
|
-
|
|
366
|
-
|
|
390
|
+
kind: 14,
|
|
391
|
+
query
|
|
367
392
|
});
|
|
368
393
|
const raw = (sql) => ({
|
|
369
|
-
|
|
370
|
-
|
|
394
|
+
kind: 15,
|
|
395
|
+
expr: sql
|
|
371
396
|
});
|
|
372
397
|
const conditions = {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
398
|
+
simpleWhere,
|
|
399
|
+
and,
|
|
400
|
+
or,
|
|
401
|
+
eq: comparison("="),
|
|
402
|
+
neq: comparison("<>"),
|
|
403
|
+
gt: comparison(">"),
|
|
404
|
+
gte: comparison(">="),
|
|
405
|
+
lt: comparison("<"),
|
|
406
|
+
lte: comparison("<="),
|
|
407
|
+
comparison: (left, operator, right) => comparison(operator)(left, right),
|
|
408
|
+
contains: containsExpr(false, "contains"),
|
|
409
|
+
notContains: containsExpr(true, "contains"),
|
|
410
|
+
startsWith: containsExpr(false, "start"),
|
|
411
|
+
notStartsWith: containsExpr(true, "start"),
|
|
412
|
+
endsWith: containsExpr(false, "end"),
|
|
413
|
+
notEndsWith: containsExpr(true, "end"),
|
|
414
|
+
in: In,
|
|
415
|
+
notIn,
|
|
416
|
+
between,
|
|
417
|
+
isNull: isNull(false),
|
|
418
|
+
isNotNull: isNull(true),
|
|
419
|
+
exists
|
|
395
420
|
};
|
|
396
421
|
const table = (name, joins, alias) => ({
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
422
|
+
kind: 2,
|
|
423
|
+
subquery: false,
|
|
424
|
+
name,
|
|
425
|
+
alias,
|
|
426
|
+
joins
|
|
402
427
|
});
|
|
403
428
|
const subQueryTable = (query, joins, alias) => ({
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
429
|
+
kind: 2,
|
|
430
|
+
subquery: true,
|
|
431
|
+
query,
|
|
432
|
+
alias,
|
|
433
|
+
joins
|
|
409
434
|
});
|
|
410
|
-
const join = (
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
435
|
+
const join = (table, conditions, type) => ({
|
|
436
|
+
kind: 3,
|
|
437
|
+
type,
|
|
438
|
+
table,
|
|
439
|
+
conditions
|
|
415
440
|
});
|
|
416
441
|
const literal = (value) => ({
|
|
417
|
-
|
|
418
|
-
|
|
442
|
+
kind: 11,
|
|
443
|
+
value
|
|
419
444
|
});
|
|
420
|
-
const sort = (
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
445
|
+
const sort = (field, direction) => ({
|
|
446
|
+
kind: 12,
|
|
447
|
+
field,
|
|
448
|
+
direction
|
|
424
449
|
});
|
|
425
450
|
const ident = (identifier) => ({
|
|
426
|
-
|
|
427
|
-
|
|
451
|
+
kind: 13,
|
|
452
|
+
identifier
|
|
428
453
|
});
|
|
429
454
|
const QExpr = {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
};
|
|
447
|
-
|
|
455
|
+
conditions,
|
|
456
|
+
...conditions,
|
|
457
|
+
field,
|
|
458
|
+
fn,
|
|
459
|
+
window,
|
|
460
|
+
windowBetween,
|
|
461
|
+
paren,
|
|
462
|
+
table,
|
|
463
|
+
subQueryTable,
|
|
464
|
+
join,
|
|
465
|
+
value: literal,
|
|
466
|
+
sort,
|
|
467
|
+
order: sort,
|
|
468
|
+
ident,
|
|
469
|
+
id: ident,
|
|
470
|
+
raw
|
|
471
|
+
};
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region src/runtime/date.ts
|
|
474
|
+
const dateOffset = (date, timeZoneHour) => {
|
|
475
|
+
const offset = timeZoneHour ? timeZoneHour * 60 * 60 * 1e3 : date.getTimezoneOffset() * 6e4;
|
|
476
|
+
return new Date(date.getTime() + offset);
|
|
477
|
+
};
|
|
478
|
+
const zeroPad = (v, len) => v.toString().padStart(len, "0");
|
|
479
|
+
const dateToDatetimeString = (d) => {
|
|
480
|
+
const year = d.getUTCFullYear();
|
|
481
|
+
const month = d.getUTCMonth() + 1;
|
|
482
|
+
const day = d.getUTCDate();
|
|
483
|
+
const hour = d.getUTCHours();
|
|
484
|
+
const minute = d.getUTCMinutes();
|
|
485
|
+
const second = d.getUTCSeconds();
|
|
486
|
+
const millisecond = d.getUTCMilliseconds();
|
|
487
|
+
return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2) + " " + zeroPad(hour, 2) + ":" + zeroPad(minute, 2) + ":" + zeroPad(second, 2) + "." + zeroPad(millisecond, 3);
|
|
488
|
+
};
|
|
489
|
+
const dateToDateString = (d) => {
|
|
490
|
+
const year = d.getUTCFullYear();
|
|
491
|
+
const month = d.getUTCMonth() + 1;
|
|
492
|
+
const day = d.getUTCDate();
|
|
493
|
+
return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2);
|
|
494
|
+
};
|
|
495
|
+
const getTodayDateString = (timeZoneHour) => {
|
|
496
|
+
const date = /* @__PURE__ */ new Date();
|
|
497
|
+
date.setHours(0, 0, 0, 0);
|
|
498
|
+
return dateToDateString(dateOffset(date, timeZoneHour));
|
|
499
|
+
};
|
|
500
|
+
const getTodayDateTimeString = (timeZoneHour) => {
|
|
501
|
+
const date = /* @__PURE__ */ new Date();
|
|
502
|
+
date.setHours(0, 0, 0, 0);
|
|
503
|
+
return dateToDatetimeString(dateOffset(date, timeZoneHour));
|
|
504
|
+
};
|
|
505
|
+
const getDayRange = (date, timeZoneHour) => {
|
|
506
|
+
date.setHours(0, 0, 0, 0);
|
|
507
|
+
const d = dateOffset(date, timeZoneHour || 0);
|
|
508
|
+
const begin = dateToDatetimeString(d);
|
|
509
|
+
d.setDate(d.getDate() + 1);
|
|
510
|
+
return [begin, dateToDatetimeString(d)];
|
|
511
|
+
};
|
|
512
|
+
const getDayRangeQExpr = (date, timeZoneHour) => {
|
|
513
|
+
return getDayRange(date, timeZoneHour).map(QExpr.value);
|
|
514
|
+
};
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region src/runtime/gqlResolveInfoToField.ts
|
|
448
517
|
const selectionSetToField = (selections, number) => {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
return [result, num];
|
|
518
|
+
const result = {
|
|
519
|
+
fields: [],
|
|
520
|
+
relations: {},
|
|
521
|
+
tableAlias: "t" + number
|
|
522
|
+
};
|
|
523
|
+
let num = number;
|
|
524
|
+
for (const it of selections) {
|
|
525
|
+
if (it.kind !== "Field") continue;
|
|
526
|
+
if (it.selectionSet) {
|
|
527
|
+
num += 1;
|
|
528
|
+
const field = selectionSetToField(it.selectionSet.selections, num);
|
|
529
|
+
result.relations[it.name.value] = field[0];
|
|
530
|
+
num = field[1];
|
|
531
|
+
} else if (it.name.value !== "__typename") result.fields.push(it.name.value);
|
|
532
|
+
}
|
|
533
|
+
return [result, num];
|
|
467
534
|
};
|
|
468
535
|
const gqlResolveInfoToField = (info) => {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
536
|
+
return selectionSetToField(info.fieldNodes[0].selectionSet.selections, 0)[0];
|
|
537
|
+
};
|
|
538
|
+
//#endregion
|
|
539
|
+
//#region src/runtime/id.ts
|
|
540
|
+
const makeNumberIdEncoder = (hashId) => {
|
|
541
|
+
return {
|
|
542
|
+
encode: (id) => hashId.encode(id),
|
|
543
|
+
decode: (id) => hashId.decode(id)[0]
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
//#endregion
|
|
547
|
+
//#region src/runtime/makeResolver.ts
|
|
548
|
+
const makeResolver = (resolver, middlewares = []) => {
|
|
549
|
+
return (...args) => {
|
|
550
|
+
return resolver(...middlewares.reduce((args, middleware) => {
|
|
551
|
+
return middleware(args);
|
|
552
|
+
}, args));
|
|
553
|
+
};
|
|
554
|
+
};
|
|
555
|
+
//#endregion
|
|
556
|
+
//#region src/runtime/resolverMiddleware.ts
|
|
557
|
+
const makeParamsMiddleware = (update) => {
|
|
558
|
+
return (args) => {
|
|
559
|
+
args[1] = update(args[1]);
|
|
560
|
+
return args;
|
|
561
|
+
};
|
|
562
|
+
};
|
|
563
|
+
//#endregion
|
|
564
|
+
//#region src/runtime/dsl/mutation/mutation.ts
|
|
565
|
+
const escapeId = SqlString.escapeId;
|
|
477
566
|
const onDuplicateKeyUpdate = (columns) => {
|
|
478
|
-
|
|
479
|
-
|
|
567
|
+
if (!columns || columns.length === 0) return "";
|
|
568
|
+
return " ON DUPLICATE KEY UPDATE " + columns.map(escapeId).map((it) => `${it} = VALUES(${it})`).join(",");
|
|
480
569
|
};
|
|
481
570
|
const createToSql = (dsl, tableInfo) => {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
dsl.table
|
|
486
|
-
)}(${dsl.fields.map((it) => escapeId(map[it]))}) VALUES ${values} ${onDuplicateKeyUpdate(dsl.upsert)}`;
|
|
571
|
+
const map = tableInfo[dsl.table].columnMap;
|
|
572
|
+
const values = dsl.entities.map((it) => `(${it.map((it) => SqlString.escape(it)).join(",")})`).join(",");
|
|
573
|
+
return `INSERT ${dsl.ignore ? "IGNORE " : ""}INTO ${escapeId(dsl.table)}(${dsl.fields.map((it) => escapeId(map[it]))}) VALUES ${values} ${onDuplicateKeyUpdate(dsl.upsert)}`;
|
|
487
574
|
};
|
|
488
575
|
const updateToSql = (dsl, tableInfo) => {
|
|
489
|
-
|
|
490
|
-
|
|
576
|
+
const map = tableInfo[dsl.table].columnMap;
|
|
577
|
+
return `UPDATE ${escapeId(dsl.table)} SET ${dsl.values.map((it) => escapeId(map[it.field]) + " = " + SqlString.escape(it.value)).join(", ")} WHERE ${Sql.booleanValue(dsl.where)}`;
|
|
491
578
|
};
|
|
492
579
|
const deleteToSql = (dsl) => {
|
|
493
|
-
|
|
494
|
-
dsl.where
|
|
495
|
-
)}`;
|
|
580
|
+
return `DELETE FROM ${escapeId(dsl.table)} WHERE ${Sql.booleanValue(dsl.where)}`;
|
|
496
581
|
};
|
|
497
|
-
|
|
582
|
+
//#endregion
|
|
583
|
+
//#region src/runtime/dsl/query/createQueryResolveInfo.ts
|
|
498
584
|
const joinToQueryResolveInfo = (parentTableAlias, property, fields, map, tableInfo) => {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
info.table,
|
|
509
|
-
key,
|
|
510
|
-
value,
|
|
511
|
-
map,
|
|
512
|
-
tableInfo
|
|
513
|
-
)
|
|
514
|
-
).filter(nonNullable),
|
|
515
|
-
property
|
|
516
|
-
};
|
|
585
|
+
const info = map[parentTableAlias][property];
|
|
586
|
+
if (!info) return void 0;
|
|
587
|
+
return {
|
|
588
|
+
tableAlias: fields.tableAlias || info.table,
|
|
589
|
+
isArray: info.array,
|
|
590
|
+
keyAliases: tableInfo[info.table].identifiableFields,
|
|
591
|
+
joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(info.table, key, value, map, tableInfo)).filter(nonNullable),
|
|
592
|
+
property
|
|
593
|
+
};
|
|
517
594
|
};
|
|
518
595
|
const createQueryResolveInfo = (tableName, fields, map, tableInfo) => {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
map,
|
|
530
|
-
tableInfo
|
|
531
|
-
)
|
|
532
|
-
).filter(nonNullable),
|
|
533
|
-
property: ""
|
|
534
|
-
};
|
|
535
|
-
};
|
|
536
|
-
|
|
596
|
+
return {
|
|
597
|
+
tableAlias: fields.tableAlias || tableName,
|
|
598
|
+
isArray: true,
|
|
599
|
+
keyAliases: tableInfo[tableName].identifiableFields,
|
|
600
|
+
joins: Object.entries(fields.relations || {}).filter(([, value]) => value).map(([key, value]) => joinToQueryResolveInfo(tableName, key, value, map, tableInfo)).filter(nonNullable),
|
|
601
|
+
property: ""
|
|
602
|
+
};
|
|
603
|
+
};
|
|
604
|
+
//#endregion
|
|
605
|
+
//#region src/runtime/dsl/query/sql/hydrate.ts
|
|
537
606
|
const rowToObjs = (row) => {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
546
|
-
return objs;
|
|
607
|
+
const objs = {};
|
|
608
|
+
for (const [key, value] of Object.entries(row)) {
|
|
609
|
+
const [table, column] = key.split("__");
|
|
610
|
+
if (!objs[table]) objs[table] = {};
|
|
611
|
+
objs[table][column] = value;
|
|
612
|
+
}
|
|
613
|
+
return objs;
|
|
547
614
|
};
|
|
548
615
|
const getUnique = (obj, info) => info.keyAliases.map((it) => obj[it]).join("_~_");
|
|
549
616
|
const execTable = (info, objs, current) => {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
currentTarget[it.property] = execTable(
|
|
577
|
-
it,
|
|
578
|
-
objs,
|
|
579
|
-
currentTarget[it.property]
|
|
580
|
-
);
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
return result;
|
|
584
|
-
};
|
|
617
|
+
let entity = objs[info.tableAlias];
|
|
618
|
+
if (entity[info.keyAliases[0]] == null) entity = null;
|
|
619
|
+
let result;
|
|
620
|
+
let currentTarget;
|
|
621
|
+
if (info.isArray) if (!current) {
|
|
622
|
+
result = entity == null ? [] : [entity];
|
|
623
|
+
currentTarget = entity;
|
|
624
|
+
} else {
|
|
625
|
+
currentTarget = entity == null ? null : current.find((item) => item && info.keyAliases.every((key) => item[key] === entity[key]));
|
|
626
|
+
if (currentTarget) result = current;
|
|
627
|
+
else {
|
|
628
|
+
currentTarget = entity;
|
|
629
|
+
result = current;
|
|
630
|
+
if (currentTarget) result.push(currentTarget);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
currentTarget = current || entity;
|
|
635
|
+
result = currentTarget;
|
|
636
|
+
}
|
|
637
|
+
if (currentTarget !== null) for (const it of info.joins) currentTarget[it.property] = execTable(it, objs, currentTarget[it.property]);
|
|
638
|
+
return result;
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* to use this function require to select primary keys for every table
|
|
642
|
+
*/
|
|
585
643
|
const hydrate = (data, info) => {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
};
|
|
603
|
-
|
|
644
|
+
const result = [];
|
|
645
|
+
const t0mapper = {};
|
|
646
|
+
info.isArray = false;
|
|
647
|
+
for (const row of data) {
|
|
648
|
+
const objs = rowToObjs(row);
|
|
649
|
+
const currentObj = objs[info.tableAlias];
|
|
650
|
+
const unique = getUnique(currentObj, info);
|
|
651
|
+
if (t0mapper[unique] === void 0) {
|
|
652
|
+
t0mapper[unique] = result.length;
|
|
653
|
+
result.push(execTable(info, objs, currentObj));
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
const base = result[t0mapper[unique]];
|
|
657
|
+
execTable(info, objs, base);
|
|
658
|
+
}
|
|
659
|
+
return result;
|
|
660
|
+
};
|
|
661
|
+
//#endregion
|
|
662
|
+
//#region src/runtime/sql/runQuery.ts
|
|
604
663
|
const notTypeName = (fieldName) => fieldName !== "__typename";
|
|
605
664
|
const createQuery = (baseTableName, fields, options, tableInfo, relationMap, context) => {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
resolveFields(rel.table, table2),
|
|
636
|
-
QExpr.and(
|
|
637
|
-
rel.condition({
|
|
638
|
-
parentTableAlias: tableAlias,
|
|
639
|
-
childTableAlias: table2.tableAlias || "t" + current,
|
|
640
|
-
context
|
|
641
|
-
}),
|
|
642
|
-
table2.joinOn
|
|
643
|
-
),
|
|
644
|
-
"LEFT"
|
|
645
|
-
);
|
|
646
|
-
}).filter(nonNullable),
|
|
647
|
-
tableAlias
|
|
648
|
-
);
|
|
649
|
-
};
|
|
650
|
-
const from = resolveFields(baseTableName, fields);
|
|
651
|
-
return {
|
|
652
|
-
select,
|
|
653
|
-
from,
|
|
654
|
-
...options
|
|
655
|
-
};
|
|
665
|
+
let tableCount = 0;
|
|
666
|
+
const select = [];
|
|
667
|
+
const resolveFields = (tableName, table) => {
|
|
668
|
+
const tableAlias = table.tableAlias || "t" + tableCount;
|
|
669
|
+
table.tableAlias = tableAlias;
|
|
670
|
+
tableCount++;
|
|
671
|
+
const info = tableInfo[tableName];
|
|
672
|
+
select.push(...unique([...table.fields.filter((it) => {
|
|
673
|
+
return notTypeName(it) && info.columnMap[it];
|
|
674
|
+
}), ...info.identifiableFields]).map((it) => {
|
|
675
|
+
const realName = info.columnMap[it] || it;
|
|
676
|
+
return QExpr.field(tableAlias, realName, tableAlias + "__" + it);
|
|
677
|
+
}));
|
|
678
|
+
return QExpr.table(tableName, Object.entries(table.relations || {}).map(([relationName, table]) => {
|
|
679
|
+
const current = tableCount;
|
|
680
|
+
const rel = relationMap[tableName][relationName];
|
|
681
|
+
if (!rel) return void 0;
|
|
682
|
+
return QExpr.join(resolveFields(rel.table, table), QExpr.and(rel.condition({
|
|
683
|
+
parentTableAlias: tableAlias,
|
|
684
|
+
childTableAlias: table.tableAlias || "t" + current,
|
|
685
|
+
context
|
|
686
|
+
}), table.joinOn), "LEFT");
|
|
687
|
+
}).filter(nonNullable), tableAlias);
|
|
688
|
+
};
|
|
689
|
+
return {
|
|
690
|
+
select,
|
|
691
|
+
from: resolveFields(baseTableName, fields),
|
|
692
|
+
...options
|
|
693
|
+
};
|
|
656
694
|
};
|
|
657
695
|
const createPagingInnerQuery = (tableName, tableAlias, fields, option, tableInfo, relationMap) => {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
};
|
|
674
|
-
const createPagingFieldQuery = ({
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
async find(fields = { fields: this.fields }, options, context) {
|
|
807
|
-
const query = createQuery(
|
|
808
|
-
this.tableName,
|
|
809
|
-
fields,
|
|
810
|
-
options,
|
|
811
|
-
this.tableInfo,
|
|
812
|
-
this.relationMap,
|
|
813
|
-
context
|
|
814
|
-
);
|
|
815
|
-
return this.executeQuery(query, fields);
|
|
816
|
-
}
|
|
817
|
-
async findPageable(paging, fields = { fields: this.fields }, options, context) {
|
|
818
|
-
const query = createPagingFieldQuery({
|
|
819
|
-
baseTableName: this.tableName,
|
|
820
|
-
fields,
|
|
821
|
-
tableInfo: this.tableInfo,
|
|
822
|
-
relationMap: this.relationMap,
|
|
823
|
-
pagingOption: paging,
|
|
824
|
-
queryOption: options,
|
|
825
|
-
context
|
|
826
|
-
});
|
|
827
|
-
return this.executeQuery(query, fields);
|
|
828
|
-
}
|
|
829
|
-
async executeQuery(query, fields) {
|
|
830
|
-
const info = createQueryResolveInfo(
|
|
831
|
-
this.tableName,
|
|
832
|
-
fields,
|
|
833
|
-
this.relationMap,
|
|
834
|
-
this.tableInfo
|
|
835
|
-
);
|
|
836
|
-
const sql = queryToSql(query);
|
|
837
|
-
this.queryLogger(sql);
|
|
838
|
-
const resultRows = await this.client.rawQuery(sql);
|
|
839
|
-
return hydrate(resultRows, info);
|
|
840
|
-
}
|
|
841
|
-
createIdentifiableExpression(entity) {
|
|
842
|
-
const expr = this.identifyFields.map((it) => {
|
|
843
|
-
const value = entity[it];
|
|
844
|
-
if (!value) throw new Error(`field ${it} is required`);
|
|
845
|
-
return QExpr.eq(
|
|
846
|
-
QExpr.field(this.tableName, this.tableInfo[this.tableName].columnMap[it]),
|
|
847
|
-
QExpr.value(value)
|
|
848
|
-
);
|
|
849
|
-
});
|
|
850
|
-
return QExpr.and(...expr);
|
|
851
|
-
}
|
|
852
|
-
getRelationMap() {
|
|
853
|
-
return this.relationMap[this.tableName];
|
|
854
|
-
}
|
|
855
|
-
fieldToColumn(fields) {
|
|
856
|
-
return fields.map((it) => this.tableInfo[this.tableName].columnMap[it] || it);
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
const noop = () => {
|
|
860
|
-
};
|
|
861
|
-
|
|
696
|
+
const map = tableInfo[tableName].columnMap;
|
|
697
|
+
return {
|
|
698
|
+
select: unique([
|
|
699
|
+
...tableInfo[tableName].identifiableKeys,
|
|
700
|
+
...Object.keys(fields.relations || {}).flatMap((key) => {
|
|
701
|
+
return relationMap[tableName][key]?.requiredColumns || [];
|
|
702
|
+
}),
|
|
703
|
+
...fields.fields.filter((it) => notTypeName(it) && map[it]).map((it) => map[it] || it)
|
|
704
|
+
]).map((it) => QExpr.field(tableAlias, it)),
|
|
705
|
+
from: QExpr.table(tableName, option.join || [], tableAlias),
|
|
706
|
+
limit: option.numberOfItem,
|
|
707
|
+
offset: option.offset,
|
|
708
|
+
where: option.where,
|
|
709
|
+
sort: option.sort
|
|
710
|
+
};
|
|
711
|
+
};
|
|
712
|
+
const createPagingFieldQuery = ({ baseTableName, fields, queryOption, pagingOption, tableInfo, relationMap, context }) => {
|
|
713
|
+
const innerQuery = createPagingInnerQuery(baseTableName, fields.tableAlias || "t0", fields, pagingOption, tableInfo, relationMap);
|
|
714
|
+
const main = createQuery(baseTableName, fields, queryOption, tableInfo, relationMap, context);
|
|
715
|
+
return {
|
|
716
|
+
select: main.select,
|
|
717
|
+
from: {
|
|
718
|
+
...main.from,
|
|
719
|
+
subquery: true,
|
|
720
|
+
query: innerQuery
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
};
|
|
724
|
+
//#endregion
|
|
725
|
+
//#region src/runtime/sasatDBDatasource.ts
|
|
726
|
+
var SasatDBDatasource = class {
|
|
727
|
+
constructor(client = getDbClient()) {
|
|
728
|
+
this.client = client;
|
|
729
|
+
}
|
|
730
|
+
async create(entity, option) {
|
|
731
|
+
const obj = {
|
|
732
|
+
...this.getDefaultValueString(),
|
|
733
|
+
...entity
|
|
734
|
+
};
|
|
735
|
+
const fields = Object.keys(obj);
|
|
736
|
+
const sql = createToSql({
|
|
737
|
+
table: this.tableName,
|
|
738
|
+
fields,
|
|
739
|
+
entities: [fields.map((key) => obj[key])],
|
|
740
|
+
upsert: option?.upsert?.updateColumns,
|
|
741
|
+
ignore: option?.ignore
|
|
742
|
+
}, this.tableInfo);
|
|
743
|
+
const response = await this.client.rawCommand(sql);
|
|
744
|
+
if (!this.autoIncrementColumn) return obj;
|
|
745
|
+
return {
|
|
746
|
+
...obj,
|
|
747
|
+
[this.autoIncrementColumn]: response.insertId
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
async createBulk(entities, option) {
|
|
751
|
+
const objects = entities.map((it) => ({
|
|
752
|
+
...this.getDefaultValueString(),
|
|
753
|
+
...it
|
|
754
|
+
}));
|
|
755
|
+
const keys = Object.keys(objects[0]);
|
|
756
|
+
const values = objects.map((it) => keys.map((key) => it[key]));
|
|
757
|
+
const sql = createToSql({
|
|
758
|
+
table: this.tableName,
|
|
759
|
+
fields: keys,
|
|
760
|
+
entities: values,
|
|
761
|
+
upsert: option?.upsert?.updateColumns,
|
|
762
|
+
ignore: option?.ignore
|
|
763
|
+
}, this.tableInfo);
|
|
764
|
+
return await this.client.rawCommand(sql);
|
|
765
|
+
}
|
|
766
|
+
async upsert(entity, updateFields = this.primaryKeys) {
|
|
767
|
+
return this.create(entity, { upsert: { updateColumns: this.fieldToColumn(updateFields) } });
|
|
768
|
+
}
|
|
769
|
+
update(entity) {
|
|
770
|
+
const sql = updateToSql({
|
|
771
|
+
table: this.tableName,
|
|
772
|
+
values: Object.entries(entity).filter(([, value]) => value !== void 0).map(([column, value]) => ({
|
|
773
|
+
field: column,
|
|
774
|
+
value
|
|
775
|
+
})),
|
|
776
|
+
where: this.createIdentifiableExpression(entity)
|
|
777
|
+
}, this.tableInfo);
|
|
778
|
+
return this.client.rawCommand(sql);
|
|
779
|
+
}
|
|
780
|
+
updateWhere(update, condition) {
|
|
781
|
+
const sql = updateToSql({
|
|
782
|
+
table: this.tableName,
|
|
783
|
+
values: Object.entries(update).filter(([, value]) => value !== void 0).map(([column, value]) => ({
|
|
784
|
+
field: column,
|
|
785
|
+
value
|
|
786
|
+
})),
|
|
787
|
+
where: condition
|
|
788
|
+
}, this.tableInfo);
|
|
789
|
+
return this.client.rawCommand(sql);
|
|
790
|
+
}
|
|
791
|
+
async delete(entity) {
|
|
792
|
+
return this.deleteWhere(this.createIdentifiableExpression(entity));
|
|
793
|
+
}
|
|
794
|
+
async deleteWhere(condition) {
|
|
795
|
+
const sql = deleteToSql({
|
|
796
|
+
table: this.tableName,
|
|
797
|
+
where: condition
|
|
798
|
+
});
|
|
799
|
+
return this.client.rawCommand(sql);
|
|
800
|
+
}
|
|
801
|
+
async first(fields, option, context) {
|
|
802
|
+
const result = await this.find(fields, option, context);
|
|
803
|
+
if (result.length !== 0) return result[0];
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
async find(fields = { fields: this.fields }, options, context) {
|
|
807
|
+
const query = createQuery(this.tableName, fields, options, this.tableInfo, this.relationMap, context);
|
|
808
|
+
return this.executeQuery(query, fields);
|
|
809
|
+
}
|
|
810
|
+
async findPageable(paging, fields = { fields: this.fields }, options, context) {
|
|
811
|
+
const query = createPagingFieldQuery({
|
|
812
|
+
baseTableName: this.tableName,
|
|
813
|
+
fields,
|
|
814
|
+
tableInfo: this.tableInfo,
|
|
815
|
+
relationMap: this.relationMap,
|
|
816
|
+
pagingOption: paging,
|
|
817
|
+
queryOption: options,
|
|
818
|
+
context
|
|
819
|
+
});
|
|
820
|
+
return this.executeQuery(query, fields);
|
|
821
|
+
}
|
|
822
|
+
async executeQuery(query, fields) {
|
|
823
|
+
const info = createQueryResolveInfo(this.tableName, fields, this.relationMap, this.tableInfo);
|
|
824
|
+
const sql = queryToSql(query);
|
|
825
|
+
return hydrate(await this.client.rawQuery(sql), info);
|
|
826
|
+
}
|
|
827
|
+
createIdentifiableExpression(entity) {
|
|
828
|
+
const expr = this.identifyFields.map((it) => {
|
|
829
|
+
const value = entity[it];
|
|
830
|
+
if (!value) throw new Error(`field ${it} is required`);
|
|
831
|
+
return QExpr.eq(QExpr.field(this.tableName, this.tableInfo[this.tableName].columnMap[it]), QExpr.value(value));
|
|
832
|
+
});
|
|
833
|
+
return QExpr.and(...expr);
|
|
834
|
+
}
|
|
835
|
+
getRelationMap() {
|
|
836
|
+
return this.relationMap[this.tableName];
|
|
837
|
+
}
|
|
838
|
+
fieldToColumn(fields) {
|
|
839
|
+
return fields.map((it) => this.tableInfo[this.tableName].columnMap[it] || it);
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
//#endregion
|
|
843
|
+
//#region src/util/dateUtil.ts
|
|
862
844
|
const getCurrentDateTimeString = () => {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
const makeArgs = (args) => {
|
|
874
|
-
if (!args || args.length === 0) return "";
|
|
875
|
-
return `(${args.map((arg) => `${arg.name}: ${arg.type}`).join(", ")})`;
|
|
876
|
-
};
|
|
877
|
-
const makeTypedefString = (typeName, typedef, type) => {
|
|
878
|
-
const entries = Object.entries(typedef);
|
|
879
|
-
if (entries.length === 0) return "";
|
|
880
|
-
return `${type} ${typeName} {
|
|
881
|
-
${entries.map(([field, value]) => {
|
|
882
|
-
if (!value.return)
|
|
883
|
-
throw new Error(`Return type required: ${typeName}.${field}`);
|
|
884
|
-
return ` ${field}${makeArgs(value.args)}: ${value.return}`;
|
|
885
|
-
}).join("\n")}
|
|
886
|
-
}
|
|
887
|
-
`;
|
|
888
|
-
};
|
|
889
|
-
const createTypeDef = (typeDefs, inputs) => {
|
|
890
|
-
const types = Object.entries(typeDefs).map(
|
|
891
|
-
([type, fields]) => makeTypedefString(type, fields, "type")
|
|
892
|
-
);
|
|
893
|
-
const input = Object.entries(inputs).map(
|
|
894
|
-
([type, fields]) => makeTypedefString(type, fields, "input")
|
|
895
|
-
);
|
|
896
|
-
return types.join("\n") + input.join("\n");
|
|
897
|
-
};
|
|
898
|
-
|
|
899
|
-
var Comparison = /* @__PURE__ */ ((Comparison2) => {
|
|
900
|
-
Comparison2["eq"] = "=";
|
|
901
|
-
Comparison2["gt"] = ">";
|
|
902
|
-
Comparison2["lt"] = "<";
|
|
903
|
-
Comparison2["gte"] = ">=";
|
|
904
|
-
Comparison2["lte"] = "<=";
|
|
905
|
-
Comparison2["neq"] = "<>";
|
|
906
|
-
Comparison2["like"] = "LIKE";
|
|
907
|
-
Comparison2["notLike"] = "NOT LIKE";
|
|
908
|
-
return Comparison2;
|
|
909
|
-
})(Comparison || {});
|
|
910
|
-
const comparisonExpressionToSql = (exp) => {
|
|
911
|
-
const type = Object.prototype.hasOwnProperty.call(exp, "__type") ? exp.__type || "AND" : "AND";
|
|
912
|
-
return Object.entries(exp).map(([key, value]) => {
|
|
913
|
-
const column = SqlString.escapeId(key);
|
|
914
|
-
if (!Array.isArray(value))
|
|
915
|
-
return `${column} = ${SqlString.escape(value)}`;
|
|
916
|
-
if (value[0] === "IS NULL") return `${column} IS NULL`;
|
|
917
|
-
if (value[0] === "IS NOT NULL") return `${column} IS NOT NULL`;
|
|
918
|
-
if (value[0] === "IN") {
|
|
919
|
-
const [, ...columns] = value;
|
|
920
|
-
return `${column} IN (${[
|
|
921
|
-
columns.map((column2) => SqlString.escape(column2)).join(", ")
|
|
922
|
-
]})`;
|
|
923
|
-
}
|
|
924
|
-
if (value[0] === "BETWEEN")
|
|
925
|
-
return `${column} BETWEEN ${SqlString.escape(
|
|
926
|
-
value[1]
|
|
927
|
-
)} AND ${SqlString.escape(value[2])}`;
|
|
928
|
-
if (Object.keys(Comparison).includes(value[0]))
|
|
929
|
-
return `${column} ${value[0]} ${SqlString.escape(value[1])}`;
|
|
930
|
-
throw new SasatError("SQL PARSE ERROR");
|
|
931
|
-
}).join(` ${type} `);
|
|
932
|
-
};
|
|
933
|
-
|
|
934
|
-
const conditionExpressionToSql = (exp) => {
|
|
935
|
-
if (Array.isArray(exp)) {
|
|
936
|
-
return CompositeCondition.and(exp).toSQL();
|
|
937
|
-
}
|
|
938
|
-
if (exp instanceof CompositeCondition) return exp.toSQL();
|
|
939
|
-
return comparisonExpressionToSql(exp);
|
|
940
|
-
};
|
|
941
|
-
|
|
942
|
-
class CompositeCondition {
|
|
943
|
-
constructor(type, conditions) {
|
|
944
|
-
this.type = type;
|
|
945
|
-
this.conditions = conditions;
|
|
946
|
-
}
|
|
947
|
-
static or(conditions) {
|
|
948
|
-
return new CompositeCondition("OR", conditions);
|
|
949
|
-
}
|
|
950
|
-
static and(conditions) {
|
|
951
|
-
return new CompositeCondition("AND", conditions);
|
|
952
|
-
}
|
|
953
|
-
toSQL() {
|
|
954
|
-
return "(" + this.conditions.map(conditionExpressionToSql).join(this.type) + ")";
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
const dateOffset = (date, timeZoneHour) => {
|
|
959
|
-
const offset = timeZoneHour ? timeZoneHour * 60 * 60 * 1e3 : date.getTimezoneOffset() * 6e4;
|
|
960
|
-
return new Date(date.getTime() + offset);
|
|
961
|
-
};
|
|
962
|
-
const zeroPad = (v, len) => v.toString().padStart(len, "0");
|
|
963
|
-
const dateToDatetimeString = (d) => {
|
|
964
|
-
const year = d.getUTCFullYear();
|
|
965
|
-
const month = d.getUTCMonth() + 1;
|
|
966
|
-
const day = d.getUTCDate();
|
|
967
|
-
const hour = d.getUTCHours();
|
|
968
|
-
const minute = d.getUTCMinutes();
|
|
969
|
-
const second = d.getUTCSeconds();
|
|
970
|
-
const millisecond = d.getUTCMilliseconds();
|
|
971
|
-
return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2) + " " + zeroPad(hour, 2) + ":" + zeroPad(minute, 2) + ":" + zeroPad(second, 2) + "." + zeroPad(millisecond, 3);
|
|
972
|
-
};
|
|
973
|
-
const dateToDateString = (d) => {
|
|
974
|
-
const year = d.getUTCFullYear();
|
|
975
|
-
const month = d.getUTCMonth() + 1;
|
|
976
|
-
const day = d.getUTCDate();
|
|
977
|
-
return zeroPad(year, 4) + "-" + zeroPad(month, 2) + "-" + zeroPad(day, 2);
|
|
978
|
-
};
|
|
979
|
-
const getTodayDateString = (timeZoneHour) => {
|
|
980
|
-
const date = /* @__PURE__ */ new Date();
|
|
981
|
-
date.setHours(0, 0, 0, 0);
|
|
982
|
-
return dateToDateString(dateOffset(date, timeZoneHour));
|
|
983
|
-
};
|
|
984
|
-
const getTodayDateTimeString = (timeZoneHour) => {
|
|
985
|
-
const date = /* @__PURE__ */ new Date();
|
|
986
|
-
date.setHours(0, 0, 0, 0);
|
|
987
|
-
return dateToDatetimeString(dateOffset(date, timeZoneHour));
|
|
988
|
-
};
|
|
989
|
-
const getDayRange = (date, timeZoneHour) => {
|
|
990
|
-
date.setHours(0, 0, 0, 0);
|
|
991
|
-
const d = dateOffset(date, timeZoneHour || 0);
|
|
992
|
-
const begin = dateToDatetimeString(d);
|
|
993
|
-
d.setDate(d.getDate() + 1);
|
|
994
|
-
return [begin, dateToDatetimeString(d)];
|
|
995
|
-
};
|
|
996
|
-
const getDayRangeQExpr = (date, timeZoneHour) => {
|
|
997
|
-
return getDayRange(date, timeZoneHour).map(QExpr.value);
|
|
998
|
-
};
|
|
999
|
-
|
|
1000
|
-
const makeResolver = (resolver, middlewares = []) => {
|
|
1001
|
-
return (...args) => {
|
|
1002
|
-
const newArgs = middlewares.reduce(
|
|
1003
|
-
(args2, middleware) => {
|
|
1004
|
-
return middleware(args2);
|
|
1005
|
-
},
|
|
1006
|
-
args
|
|
1007
|
-
);
|
|
1008
|
-
return resolver(...newArgs);
|
|
1009
|
-
};
|
|
1010
|
-
};
|
|
1011
|
-
|
|
845
|
+
const pad = (number) => {
|
|
846
|
+
if (number < 10) return "0" + number;
|
|
847
|
+
return number;
|
|
848
|
+
};
|
|
849
|
+
const date = /* @__PURE__ */ new Date();
|
|
850
|
+
return date.getFullYear() + "-" + pad(date.getMonth() + 1) + "-" + pad(date.getDate()) + " " + pad(date.getHours()) + ":" + pad(date.getMinutes()) + ":" + pad(date.getSeconds());
|
|
851
|
+
};
|
|
852
|
+
//#endregion
|
|
853
|
+
//#region src/runtime/pagingOption.ts
|
|
1012
854
|
const pagingOption = (option) => {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
export { CompositeCondition, Mutations, QExpr, Queries, SasatDBDatasource, Sql, SqlString$1 as SqlString, createTypeDef, dateOffset, dateToDateString, dateToDatetimeString, getCurrentDateTimeString, getDayRange, getDayRangeQExpr, getDbClient, getTodayDateString, getTodayDateTimeString, gqlResolveInfoToField, makeNumberIdEncoder, makeParamsMiddleware, makeResolver, pagingOption, QExpr as qe, queryToSql };
|
|
855
|
+
const sort = option.order ? [QExpr.sort(QExpr.field("t1", option.order), option?.asc === false ? "DESC" : "ASC")] : [];
|
|
856
|
+
return {
|
|
857
|
+
numberOfItem: option.numberOfItem,
|
|
858
|
+
offset: option.offset,
|
|
859
|
+
sort
|
|
860
|
+
};
|
|
861
|
+
};
|
|
862
|
+
//#endregion
|
|
863
|
+
export { CompositeCondition, Conditions, Mutations, MysqlClient, QExpr, QExpr as qe, Queries, SasatDBDatasource, Sql, SqlString, assignDeep, createTypeDef, dateOffset, dateToDateString, dateToDatetimeString, formatQuery, getCurrentDateTimeString, getDayRange, getDayRangeQExpr, getDbClient, getTodayDateString, getTodayDateTimeString, gqlResolveInfoToField, makeNumberIdEncoder, makeParamsMiddleware, makeResolver, migrate, pagingOption, pick, queryToSql, setConfig };
|