@eggjs/dal-runtime 4.0.0-beta.8 → 4.0.1-beta.0

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.
@@ -0,0 +1,193 @@
1
+ //#region src/SqlUtil.ts
2
+ function isWhiteChar(ch) {
3
+ return ch === " " || ch === "\n" || ch === "\r" || ch === " ";
4
+ }
5
+ const COMMENT_CHARS = "-#/";
6
+ const MUL_CHAR_LEADING_COMMENT_FIRST_CHAR = {
7
+ MAY_BE_FIRST_COMMENT: "-",
8
+ MAY_BE_FIRST_BLOCK_COMMENT: "/"
9
+ };
10
+ const MUL_CHAR_LEADING_COMMENT_VERIFIER = {
11
+ MAY_BE_FIRST_COMMENT: "-",
12
+ MAY_BE_FIRST_BLOCK_COMMENT: "*"
13
+ };
14
+ const MUL_CHAR_LEADING_COMMENT_NEXT_STATE = {
15
+ MAY_BE_FIRST_COMMENT: "IN_COMMENT_WAIT_HINT",
16
+ MAY_BE_FIRST_BLOCK_COMMENT: "IN_BLOCK_COMMENT_WAIT_HINT"
17
+ };
18
+ var SqlUtil = class {
19
+ static minify(sql) {
20
+ let ret = "";
21
+ let state = "START";
22
+ let tempNextState;
23
+ for (let i = 0; i < sql.length; i++) {
24
+ const ch = sql[i];
25
+ switch (state) {
26
+ case "MAY_BE_FIRST_COMMENT":
27
+ case "MAY_BE_FIRST_BLOCK_COMMENT":
28
+ switch (ch) {
29
+ case "\"":
30
+ tempNextState = "DOUBLE_QUOTE";
31
+ break;
32
+ case "'":
33
+ tempNextState = "SINGLE_QUOTE";
34
+ break;
35
+ case MUL_CHAR_LEADING_COMMENT_VERIFIER[state]:
36
+ tempNextState = MUL_CHAR_LEADING_COMMENT_NEXT_STATE[state];
37
+ break;
38
+ default:
39
+ tempNextState = "CONTENT";
40
+ break;
41
+ }
42
+ if (ch !== MUL_CHAR_LEADING_COMMENT_VERIFIER[state]) ret += `${MUL_CHAR_LEADING_COMMENT_FIRST_CHAR[state]}${ch}`;
43
+ state = tempNextState;
44
+ break;
45
+ case "IN_COMMENT_WAIT_HINT":
46
+ if (ch !== "+") state = "IN_COMMENT";
47
+ else {
48
+ state = "IN_COMMENT_HINT";
49
+ ret += "--+";
50
+ }
51
+ break;
52
+ case "IN_BLOCK_COMMENT_WAIT_HINT":
53
+ if (ch !== "+") state = "IN_BLOCK_COMMENT";
54
+ else {
55
+ state = "IN_BLOCK_COMMENT_HINT";
56
+ ret += "/*+";
57
+ }
58
+ break;
59
+ case "MAY_BE_LAST_BLOCK_COMMENT":
60
+ if (ch === "/") {
61
+ if (ret && !isWhiteChar(ret[ret.length - 1])) ret += " ";
62
+ state = "IN_SPACE";
63
+ } else state = "IN_BLOCK_COMMENT";
64
+ break;
65
+ case "MAY_BE_LAST_BLOCK_COMMENT_HINT":
66
+ ret += ch;
67
+ if (ch === "/") {
68
+ state = "IN_SPACE";
69
+ if (isWhiteChar(sql[i + 1])) ret += sql[i + 1];
70
+ } else state = "IN_BLOCK_COMMENT_HINT";
71
+ break;
72
+ case "IN_COMMENT":
73
+ if (ch === "\n" || ch === "\r") {
74
+ if (ret && !isWhiteChar(ret[ret.length - 1])) ret += " ";
75
+ state = "IN_SPACE";
76
+ }
77
+ break;
78
+ case "IN_COMMENT_HINT":
79
+ ret += ch;
80
+ if (ch === "\n" || ch === "\r") state = "IN_SPACE";
81
+ break;
82
+ case "IN_BLOCK_COMMENT":
83
+ if (ch === "*") state = "MAY_BE_LAST_BLOCK_COMMENT";
84
+ break;
85
+ case "IN_BLOCK_COMMENT_HINT":
86
+ ret += ch;
87
+ if (ch === "*") state = "MAY_BE_LAST_BLOCK_COMMENT_HINT";
88
+ break;
89
+ case "START":
90
+ if (isWhiteChar(ch)) continue;
91
+ switch (ch) {
92
+ case "\"":
93
+ state = "DOUBLE_QUOTE";
94
+ break;
95
+ case "'":
96
+ state = "SINGLE_QUOTE";
97
+ break;
98
+ case "-":
99
+ state = "MAY_BE_FIRST_COMMENT";
100
+ break;
101
+ case "#":
102
+ state = "IN_COMMENT";
103
+ break;
104
+ case "/":
105
+ state = "MAY_BE_FIRST_BLOCK_COMMENT";
106
+ break;
107
+ default:
108
+ state = "CONTENT";
109
+ break;
110
+ }
111
+ if (!COMMENT_CHARS.includes(ch)) ret += ch;
112
+ break;
113
+ case "DOUBLE_QUOTE":
114
+ case "SINGLE_QUOTE":
115
+ switch (ch) {
116
+ case "\\":
117
+ state = `BACKSLASH_AFTER_${state}`;
118
+ break;
119
+ case "'":
120
+ if (state === "SINGLE_QUOTE") state = "QUOTE_DONE";
121
+ break;
122
+ case "\"":
123
+ if (state === "DOUBLE_QUOTE") state = "QUOTE_DONE";
124
+ break;
125
+ default: break;
126
+ }
127
+ ret += ch;
128
+ break;
129
+ case "BACKSLASH_AFTER_SINGLE_QUOTE":
130
+ case "BACKSLASH_AFTER_DOUBLE_QUOTE":
131
+ ret += ch;
132
+ state = state.substr(16);
133
+ break;
134
+ case "QUOTE_DONE":
135
+ case "CONTENT":
136
+ switch (ch) {
137
+ case "'":
138
+ state = "SINGLE_QUOTE";
139
+ break;
140
+ case "\"":
141
+ state = "DOUBLE_QUOTE";
142
+ break;
143
+ case "-":
144
+ state = "MAY_BE_FIRST_COMMENT";
145
+ break;
146
+ case "#":
147
+ state = "IN_COMMENT";
148
+ break;
149
+ case "/":
150
+ state = "MAY_BE_FIRST_BLOCK_COMMENT";
151
+ break;
152
+ default:
153
+ if (isWhiteChar(ch)) {
154
+ state = "IN_SPACE";
155
+ ret += " ";
156
+ continue;
157
+ }
158
+ state = "CONTENT";
159
+ }
160
+ if (!COMMENT_CHARS.includes(ch)) ret += ch;
161
+ break;
162
+ case "IN_SPACE":
163
+ switch (ch) {
164
+ case "'":
165
+ state = "SINGLE_QUOTE";
166
+ break;
167
+ case "\"":
168
+ state = "DOUBLE_QUOTE";
169
+ break;
170
+ case "-":
171
+ state = "MAY_BE_FIRST_COMMENT";
172
+ break;
173
+ case "#":
174
+ state = "IN_COMMENT";
175
+ break;
176
+ case "/":
177
+ state = "MAY_BE_FIRST_BLOCK_COMMENT";
178
+ break;
179
+ default:
180
+ if (isWhiteChar(ch)) continue;
181
+ state = "CONTENT";
182
+ }
183
+ if (!COMMENT_CHARS.includes(ch)) ret += ch;
184
+ break;
185
+ default: throw new Error("Unexpected state machine while minifying SQL.");
186
+ }
187
+ }
188
+ return ret.trim();
189
+ }
190
+ };
191
+
192
+ //#endregion
193
+ export { SqlUtil };
@@ -0,0 +1,10 @@
1
+ import { TableModel } from "@eggjs/dal-decorator";
2
+
3
+ //#region src/TableModelInstanceBuilder.d.ts
4
+ declare class TableModelInstanceBuilder {
5
+ constructor(tableModel: TableModel, row: Record<string, any>);
6
+ static buildInstance<T>(tableModel: TableModel<T>, row: Record<string, any>): T;
7
+ static buildRow<T extends object>(instance: T, tableModel: TableModel<T>): Record<string, any>;
8
+ }
9
+ //#endregion
10
+ export { TableModelInstanceBuilder };
@@ -0,0 +1,25 @@
1
+ import { TableModel } from "@eggjs/dal-decorator";
2
+
3
+ //#region src/TableModelInstanceBuilder.ts
4
+ var TableModelInstanceBuilder = class TableModelInstanceBuilder {
5
+ constructor(tableModel, row) {
6
+ for (const [key, value] of Object.entries(row)) {
7
+ const column = tableModel.columns.find((t) => t.columnName === key);
8
+ Reflect.set(this, column?.propertyName ?? key, value);
9
+ }
10
+ }
11
+ static buildInstance(tableModel, row) {
12
+ return Reflect.construct(TableModelInstanceBuilder, [tableModel, row], tableModel.clazz);
13
+ }
14
+ static buildRow(instance, tableModel) {
15
+ const result = {};
16
+ for (const column of tableModel.columns) {
17
+ const columnValue = Reflect.get(instance, column.propertyName);
18
+ if (typeof columnValue !== "undefined") result[`$${column.propertyName}`] = columnValue;
19
+ }
20
+ return result;
21
+ }
22
+ };
23
+
24
+ //#endregion
25
+ export { TableModelInstanceBuilder };
@@ -0,0 +1,21 @@
1
+ import { SqlMap, SqlType } from "@eggjs/tegg-types";
2
+ import { Template } from "nunjucks";
3
+
4
+ //#region src/TableSqlMap.d.ts
5
+ interface GeneratedSql {
6
+ sql: string;
7
+ params: any[];
8
+ }
9
+ declare class TableSqlMap {
10
+ #private;
11
+ readonly name: string;
12
+ private readonly map;
13
+ private readonly blocks;
14
+ private readonly sqlGenerator;
15
+ constructor(name: string, map: Record<string, SqlMap>);
16
+ generate(name: string, data: object, timezone: string): GeneratedSql;
17
+ getType(name: string): SqlType;
18
+ getTemplateString(name: string): string;
19
+ }
20
+ //#endregion
21
+ export { TableSqlMap };
@@ -0,0 +1,98 @@
1
+ import { TemplateUtil } from "./TemplateUtil.js";
2
+ import { NunjucksUtils } from "./NunjucksUtil.js";
3
+ import { SqlType } from "@eggjs/tegg-types";
4
+ import { Template } from "nunjucks";
5
+
6
+ //#region src/TableSqlMap.ts
7
+ const SQL_PARAMS = "$$__sql_params";
8
+ var TableSqlMap = class {
9
+ name;
10
+ map;
11
+ blocks;
12
+ sqlGenerator;
13
+ constructor(name, map) {
14
+ this.name = name;
15
+ this.map = map;
16
+ const env = NunjucksUtils.createEnv(name);
17
+ const extracted = this.#extract(this.map);
18
+ this.blocks = extracted.blocks;
19
+ this.sqlGenerator = extracted.sqlGenerator;
20
+ for (const key in this.blocks) {
21
+ // istanbul ignore if
22
+ if (!this.blocks.hasOwnProperty(key)) continue;
23
+ env.addGlobal(key, this.blocks[key]);
24
+ }
25
+ env.addFilter("toJson", TemplateUtil.toJson);
26
+ env.addFilter("toPoint", TemplateUtil.toPoint);
27
+ env.addFilter("toLine", TemplateUtil.toLine);
28
+ env.addFilter("toPolygon", TemplateUtil.toPolygon);
29
+ env.addFilter("toGeometry", TemplateUtil.toGeometry);
30
+ env.addFilter("toMultiPoint", TemplateUtil.toMultiPoint);
31
+ env.addFilter("toMultiLine", TemplateUtil.toMultiLine);
32
+ env.addFilter("toMultiPolygon", TemplateUtil.toMultiPolygon);
33
+ env.addFilter("toGeometryCollection", TemplateUtil.toGeometryCollection);
34
+ env.addFilter("param", function(value) {
35
+ if (this.ctx[SQL_PARAMS]) this.ctx[SQL_PARAMS].push(value);
36
+ return "?";
37
+ });
38
+ }
39
+ #extract(map) {
40
+ const ret = {
41
+ blocks: {},
42
+ sqlGenerator: {}
43
+ };
44
+ for (const key in map) {
45
+ // istanbul ignore if
46
+ if (!map.hasOwnProperty(key)) continue;
47
+ const sqlMap = map[key];
48
+ switch (sqlMap.type) {
49
+ case SqlType.BLOCK:
50
+ ret.blocks[key] = sqlMap.content || "";
51
+ break;
52
+ case SqlType.INSERT:
53
+ case SqlType.SELECT:
54
+ case SqlType.UPDATE:
55
+ case SqlType.DELETE:
56
+ default:
57
+ ret.sqlGenerator[key] = {
58
+ type: sqlMap.type,
59
+ template: NunjucksUtils.compile(this.name, key, sqlMap.sql || ""),
60
+ raw: sqlMap.sql
61
+ };
62
+ break;
63
+ }
64
+ }
65
+ return ret;
66
+ }
67
+ generate(name, data, timezone) {
68
+ const generator = this.sqlGenerator[name];
69
+ // istanbul ignore if
70
+ if (!generator) throw new Error(`No sql map named '${name}' in '${name}'.`);
71
+ const template = generator.template;
72
+ const params = [];
73
+ template.env.timezone = timezone;
74
+ const context = {
75
+ ...data,
76
+ [SQL_PARAMS]: params
77
+ };
78
+ return {
79
+ sql: template.render(context),
80
+ params
81
+ };
82
+ }
83
+ getType(name) {
84
+ const generator = this.sqlGenerator[name];
85
+ // istanbul ignore if
86
+ if (!generator) throw new Error(`No sql map named '${name}' in '${name}'.`);
87
+ return generator.type;
88
+ }
89
+ getTemplateString(name) {
90
+ const generator = this.sqlGenerator[name];
91
+ // istanbul ignore if
92
+ if (!generator) throw new Error(`No sql map named '${name}' in '${name}'.`);
93
+ return generator.raw;
94
+ }
95
+ };
96
+
97
+ //#endregion
98
+ export { TableSqlMap };
@@ -0,0 +1,22 @@
1
+ import { ColumnModel } from "@eggjs/dal-decorator";
2
+ import { ColumnType, Geometry, GeometryCollection, Line, MultiLine, MultiPoint, MultiPolygon, Point, Polygon } from "@eggjs/tegg-types";
3
+
4
+ //#region src/TemplateUtil.d.ts
5
+ declare class TemplateUtil {
6
+ static isSpatialType(columnModel: ColumnModel): boolean;
7
+ static importPath(tableModelPath: string, currentPath: string): string;
8
+ static dbTypeToTsType(columnType: ColumnType): string;
9
+ static toJson(value: any): string;
10
+ static toPoint(point: Point): string;
11
+ static toLine(val: Line): string;
12
+ static toPolygon(val: Polygon): string;
13
+ static toGeometry(val: Geometry): string;
14
+ static toMultiPoint(val: MultiPoint): string;
15
+ static toMultiLine(val: MultiLine): string;
16
+ static toMultiPolygon(val: MultiPolygon): string;
17
+ static toGeometryCollection(val: GeometryCollection): string;
18
+ static spatialFilter: Record<ColumnType, string>;
19
+ static getSpatialFilter(columnType: ColumnType): string;
20
+ }
21
+ //#endregion
22
+ export { TemplateUtil };
@@ -0,0 +1,75 @@
1
+ import { ColumnModel, SpatialHelper } from "@eggjs/dal-decorator";
2
+ import { ColumnType } from "@eggjs/tegg-types";
3
+ import path from "node:path";
4
+
5
+ //#region src/TemplateUtil.ts
6
+ var TemplateUtil = class TemplateUtil {
7
+ static isSpatialType(columnModel) {
8
+ switch (columnModel.type.type) {
9
+ case ColumnType.GEOMETRY:
10
+ case ColumnType.POINT:
11
+ case ColumnType.LINESTRING:
12
+ case ColumnType.POLYGON:
13
+ case ColumnType.MULTIPOINT:
14
+ case ColumnType.MULTILINESTRING:
15
+ case ColumnType.MULTIPOLYGON:
16
+ case ColumnType.GEOMETRYCOLLECTION: return true;
17
+ default: return false;
18
+ }
19
+ }
20
+ static importPath(tableModelPath, currentPath) {
21
+ return path.relative(currentPath, tableModelPath);
22
+ }
23
+ static dbTypeToTsType(columnType) {
24
+ return `ColumnTsType['${columnType}']`;
25
+ }
26
+ static toJson(value) {
27
+ return JSON.stringify(JSON.stringify(value));
28
+ }
29
+ static toPoint(point) {
30
+ if (typeof point.x !== "number" || typeof point.y !== "number") throw new Error(`invalidate point ${JSON.stringify(point)}`);
31
+ return `Point(${point.x}, ${point.y})`;
32
+ }
33
+ static toLine(val) {
34
+ return `LINESTRING(${val.map((t) => TemplateUtil.toPoint(t)).join(",")})`;
35
+ }
36
+ static toPolygon(val) {
37
+ return `POLYGON(${val.map((t) => TemplateUtil.toLine(t)).join(",")})`;
38
+ }
39
+ static toGeometry(val) {
40
+ const type = SpatialHelper.getGeometryType(val);
41
+ return TemplateUtil[TemplateUtil.getSpatialFilter(type)](val);
42
+ }
43
+ static toMultiPoint(val) {
44
+ return `MULTIPOINT(${val.map((t) => TemplateUtil.toPoint(t)).join(",")})`;
45
+ }
46
+ static toMultiLine(val) {
47
+ return `MULTILINESTRING(${val.map((t) => TemplateUtil.toLine(t)).join(",")})`;
48
+ }
49
+ static toMultiPolygon(val) {
50
+ return `MULTIPOLYGON(${val.map((t) => TemplateUtil.toPolygon(t)).join(",")})`;
51
+ }
52
+ static toGeometryCollection(val) {
53
+ return `GEOMETRYCOLLECTION(${val.map((t) => {
54
+ return TemplateUtil.toGeometry(t);
55
+ }).join(",")})`;
56
+ }
57
+ static spatialFilter = {
58
+ [ColumnType.POINT]: "toPoint",
59
+ [ColumnType.LINESTRING]: "toLine",
60
+ [ColumnType.POLYGON]: "toPolygon",
61
+ [ColumnType.GEOMETRY]: "toGeometry",
62
+ [ColumnType.MULTIPOINT]: "toMultiPoint",
63
+ [ColumnType.MULTILINESTRING]: "toMultiLine",
64
+ [ColumnType.MULTIPOLYGON]: "toMultiPolygon",
65
+ [ColumnType.GEOMETRYCOLLECTION]: "toGeometryCollection"
66
+ };
67
+ static getSpatialFilter(columnType) {
68
+ const filter = TemplateUtil.spatialFilter[columnType];
69
+ if (!filter) throw new Error(`type ${columnType} is not spatial type`);
70
+ return filter;
71
+ }
72
+ };
73
+
74
+ //#endregion
75
+ export { TemplateUtil };