@eggjs/dal-runtime 4.0.0-beta.4 → 4.0.0-beta.6

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.
Files changed (62) hide show
  1. package/README.md +13 -1
  2. package/dist/BaseSqlMap.d.ts +18 -0
  3. package/dist/BaseSqlMap.js +247 -0
  4. package/dist/CodeGenerator.d.ts +17 -0
  5. package/dist/CodeGenerator.js +114 -0
  6. package/dist/DaoLoader.d.ts +8 -0
  7. package/dist/DaoLoader.js +16 -0
  8. package/dist/DataSource.d.ts +32 -0
  9. package/dist/DataSource.js +72 -0
  10. package/dist/DatabaseForker.d.ts +16 -0
  11. package/dist/DatabaseForker.js +47 -0
  12. package/dist/MySqlDataSource.d.ts +27 -0
  13. package/dist/MySqlDataSource.js +49 -0
  14. package/dist/NunjucksConverter.d.ts +76 -0
  15. package/dist/NunjucksConverter.js +90 -0
  16. package/dist/NunjucksUtil.d.ts +9 -0
  17. package/dist/NunjucksUtil.js +64 -0
  18. package/dist/SqlGenerator.d.ts +13 -0
  19. package/dist/SqlGenerator.js +224 -0
  20. package/dist/SqlMapLoader.d.ts +14 -0
  21. package/dist/SqlMapLoader.js +22 -0
  22. package/dist/SqlUtil.d.ts +6 -0
  23. package/dist/SqlUtil.js +193 -0
  24. package/dist/TableModelInstanceBuilder.d.ts +10 -0
  25. package/dist/TableModelInstanceBuilder.js +25 -0
  26. package/dist/TableSqlMap.d.ts +18 -0
  27. package/dist/TableSqlMap.js +81 -0
  28. package/dist/TemplateUtil.d.ts +22 -0
  29. package/dist/TemplateUtil.js +78 -0
  30. package/dist/index.d.ts +15 -0
  31. package/dist/index.js +16 -0
  32. package/package.json +27 -28
  33. package/src/BaseSqlMap.d.ts +0 -15
  34. package/src/BaseSqlMap.js +0 -303
  35. package/src/CodeGenerator.d.ts +0 -14
  36. package/src/CodeGenerator.js +0 -138
  37. package/src/DaoLoader.d.ts +0 -4
  38. package/src/DaoLoader.js +0 -13
  39. package/src/DataSource.d.ts +0 -28
  40. package/src/DataSource.js +0 -79
  41. package/src/DatabaseForker.d.ts +0 -12
  42. package/src/DatabaseForker.js +0 -49
  43. package/src/MySqlDataSource.d.ts +0 -23
  44. package/src/MySqlDataSource.js +0 -63
  45. package/src/NunjucksConverter.d.ts +0 -73
  46. package/src/NunjucksConverter.js +0 -93
  47. package/src/NunjucksUtil.d.ts +0 -5
  48. package/src/NunjucksUtil.js +0 -74
  49. package/src/SqlGenerator.d.ts +0 -9
  50. package/src/SqlGenerator.js +0 -391
  51. package/src/SqlMapLoader.d.ts +0 -10
  52. package/src/SqlMapLoader.js +0 -19
  53. package/src/SqlUtil.d.ts +0 -3
  54. package/src/SqlUtil.js +0 -221
  55. package/src/TableModelInstanceBuilder.d.ts +0 -6
  56. package/src/TableModelInstanceBuilder.js +0 -22
  57. package/src/TableSqlMap.d.ts +0 -19
  58. package/src/TableSqlMap.js +0 -91
  59. package/src/TemplateUtil.d.ts +0 -19
  60. package/src/TemplateUtil.js +0 -86
  61. package/src/index.d.ts +0 -15
  62. package/src/index.js +0 -16
@@ -0,0 +1,76 @@
1
+ //#region src/NunjucksConverter.d.ts
2
+ declare class NunjucksConverter {
3
+ /**
4
+ * 将变量 HTML 转义的逻辑改为 MySQL 防注入转义
5
+ *
6
+ * eg:
7
+ *
8
+ * output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "allColumns")
9
+ *
10
+ * 转换为
11
+ *
12
+ * output += runtime.escapeSQL.call(this, "allColumns", runtime.contextOrFrameLookup(context, frame, "allColumns")
13
+ *
14
+ * @param {String} code 转换前的代码
15
+ * @return {String} 转换后的代码
16
+ */
17
+ static convertNormalVariableCode(code: string): string;
18
+ /**
19
+ * 三目运算的 MySQL 防注入转义
20
+ *
21
+ * eg:
22
+ *
23
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(context, frame, "$gmtCreate") !== \
24
+ * runtime.contextOrFrameLookup(context, frame, "undefined")?runtime.contextOrFrameLookup(context,\
25
+ * frame, "$gmtCreate"):"NOW()"), env.opts.autoescape);
26
+ *
27
+ * 转换为
28
+ *
29
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(...) != ...) ?
30
+ * runtime.escapeSQL.call(this, "...", runtime.contextOrFrameLookup(...)) :
31
+ * ...)
32
+ *
33
+ * @param {String} code 转换前的代码
34
+ * @return {String} 转换后的代码
35
+ */
36
+ static convertTernaryCode(code: string): string;
37
+ /**
38
+ * 对象的属性,如 `user.id` 防注入转义
39
+ *
40
+ * eg:
41
+ * output += runtime.suppressValue(runtime.memberLookup(\
42
+ * (runtime.contextOrFrameLookup(context, frame, "user")),"id"), env.opts.autoescape);
43
+ *
44
+ * 转换为
45
+ *
46
+ * output += runtime.escapeSQL.call(this, "<...>", runtime.memberLookup(...), env.opts.autoescape);
47
+ *
48
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
49
+ * 所以找一个绝对不会匹配的 "<...>" 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
50
+ *
51
+ * @param {String} code 转换前的代码
52
+ * @return {String} 转换后的代码
53
+ */
54
+ static convertNestedObjectCode(code: string): string;
55
+ /**
56
+ * For 中的 `t_xxx` 要被转义:
57
+ *
58
+ * eg:
59
+ * frame.set("...", t_...);
60
+ * ...
61
+ * output += runtime.suppressValue(t_.., env.opts.autoscape);
62
+ *
63
+ * 转换为
64
+ *
65
+ * output += runtime.escapeSQL.call(this, "for.t_...", t_..., env.opts.autoescape);
66
+ *
67
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
68
+ * 所以找一个绝对不会匹配的 "for.t_..." 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
69
+ *
70
+ * @param {String} code 转换前的代码
71
+ * @return {String} 转换后的代码
72
+ */
73
+ static convertValueInsideFor(code: string): string;
74
+ }
75
+ //#endregion
76
+ export { NunjucksConverter };
@@ -0,0 +1,90 @@
1
+ //#region src/NunjucksConverter.ts
2
+ var NunjucksConverter = class {
3
+ /**
4
+ * 将变量 HTML 转义的逻辑改为 MySQL 防注入转义
5
+ *
6
+ * eg:
7
+ *
8
+ * output += runtime.suppressValue(runtime.contextOrFrameLookup(context, frame, "allColumns")
9
+ *
10
+ * 转换为
11
+ *
12
+ * output += runtime.escapeSQL.call(this, "allColumns", runtime.contextOrFrameLookup(context, frame, "allColumns")
13
+ *
14
+ * @param {String} code 转换前的代码
15
+ * @return {String} 转换后的代码
16
+ */
17
+ static convertNormalVariableCode(code) {
18
+ return code.replace(/\Woutput\W*?\+=\W*?runtime\.suppressValue\(runtime\.contextOrFrameLookup\((.+?),(.*?),\W*?"(.+?)"\)/g, "\noutput += runtime.escapeSQL.call(this, \"$3\", runtime.contextOrFrameLookup($1, $2, \"$3\")");
19
+ }
20
+ /**
21
+ * 三目运算的 MySQL 防注入转义
22
+ *
23
+ * eg:
24
+ *
25
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(context, frame, "$gmtCreate") !== \
26
+ * runtime.contextOrFrameLookup(context, frame, "undefined")?runtime.contextOrFrameLookup(context,\
27
+ * frame, "$gmtCreate"):"NOW()"), env.opts.autoescape);
28
+ *
29
+ * 转换为
30
+ *
31
+ * output += runtime.suppressValue((runtime.contextOrFrameLookup(...) != ...) ?
32
+ * runtime.escapeSQL.call(this, "...", runtime.contextOrFrameLookup(...)) :
33
+ * ...)
34
+ *
35
+ * @param {String} code 转换前的代码
36
+ * @return {String} 转换后的代码
37
+ */
38
+ static convertTernaryCode(code) {
39
+ const ternaryBefore = code.match(/\Woutput\W*?\+=\W*?runtime\.suppressValue\(\(.*\W*?\?\W*?.*?:.*\),\W*?env\.opts\.autoescape/g) || [];
40
+ const ternaryAfter = ternaryBefore.map((str) => {
41
+ return str.replace(/([?:])runtime\.contextOrFrameLookup\((.+?),(.*?),\W*?"(.+?)"\)/g, "$1runtime.escapeSQL.call(this, \"$4\", runtime.contextOrFrameLookup($2, $3, \"$4\"))").replace(/env.opts.autoescape$/g, "false");
42
+ });
43
+ for (let i = 0; i < ternaryBefore.length; i++) code = code.replace(ternaryBefore[i], ternaryAfter[i]);
44
+ return code;
45
+ }
46
+ /**
47
+ * 对象的属性,如 `user.id` 防注入转义
48
+ *
49
+ * eg:
50
+ * output += runtime.suppressValue(runtime.memberLookup(\
51
+ * (runtime.contextOrFrameLookup(context, frame, "user")),"id"), env.opts.autoescape);
52
+ *
53
+ * 转换为
54
+ *
55
+ * output += runtime.escapeSQL.call(this, "<...>", runtime.memberLookup(...), env.opts.autoescape);
56
+ *
57
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
58
+ * 所以找一个绝对不会匹配的 "<...>" 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
59
+ *
60
+ * @param {String} code 转换前的代码
61
+ * @return {String} 转换后的代码
62
+ */
63
+ static convertNestedObjectCode(code) {
64
+ return code.replace(/\Woutput\W*?\+=\W*?runtime\.suppressValue\(runtime\.memberLookup\((.+?)\), env\.opts\.autoescape\)/g, "\noutput += runtime.escapeSQL.call(this, \"<...>\", runtime.memberLookup($1), env.opts.autoescape)");
65
+ }
66
+ /**
67
+ * For 中的 `t_xxx` 要被转义:
68
+ *
69
+ * eg:
70
+ * frame.set("...", t_...);
71
+ * ...
72
+ * output += runtime.suppressValue(t_.., env.opts.autoscape);
73
+ *
74
+ * 转换为
75
+ *
76
+ * output += runtime.escapeSQL.call(this, "for.t_...", t_..., env.opts.autoescape);
77
+ *
78
+ * 由于 escapeSQL 中是根据 key 与预定义 block 匹配决定是否转义,而 memberLookup 的状态下总的 key 肯定不会匹配,
79
+ * 所以找一个绝对不会匹配的 "for.t_..." 传入。事实上它可以是任意一个不会被匹配的字符串,比如说 ">_<" 等。
80
+ *
81
+ * @param {String} code 转换前的代码
82
+ * @return {String} 转换后的代码
83
+ */
84
+ static convertValueInsideFor(code) {
85
+ return code.replace(/\Woutput\W*?\+=\W*?runtime\.suppressValue\((t_\d+), env\.opts\.autoescape\)/g, "\noutput += runtime.escapeSQL.call(this, \"for.$1\", $1, env.opts.autoescape)");
86
+ }
87
+ };
88
+
89
+ //#endregion
90
+ export { NunjucksConverter };
@@ -0,0 +1,9 @@
1
+ import nunjucks from "nunjucks";
2
+
3
+ //#region src/NunjucksUtil.d.ts
4
+ declare class NunjucksUtils {
5
+ static createEnv(modelName: string): nunjucks.Environment;
6
+ static compile(modelName: string, sqlName: string, sql: string): nunjucks.Template;
7
+ }
8
+ //#endregion
9
+ export { NunjucksUtils };
@@ -0,0 +1,64 @@
1
+ import { NunjucksConverter } from "./NunjucksConverter.js";
2
+ import { SqlUtil } from "./SqlUtil.js";
3
+ import nunjucks, { Template } from "nunjucks";
4
+ import sqlstring from "sqlstring";
5
+
6
+ //#region src/NunjucksUtil.ts
7
+ const compiler = nunjucks.compiler;
8
+ const envs = {};
9
+ const ROOT_RENDER_FUNC = Symbol("rootRenderFunc");
10
+ const RUNTIME = Object.assign({}, nunjucks.runtime, { escapeSQL: function escapeSQL(key, value) {
11
+ if (this.env.globals[key]) return value;
12
+ return sqlstring.escape(value, true, this.env.timezone);
13
+ } });
14
+ function _replaceCodeWithSQLFeature(source) {
15
+ return [
16
+ "convertNormalVariableCode",
17
+ "convertTernaryCode",
18
+ "convertNestedObjectCode",
19
+ "convertValueInsideFor"
20
+ ].reduce((source$1, func) => NunjucksConverter[func](source$1), source);
21
+ }
22
+ /**
23
+ * compile the string into function
24
+ * @see https://github.com/mozilla/nunjucks/blob/2fd547f/src/environment.js#L571-L592
25
+ */
26
+ function _compile() {
27
+ let source = compiler.compile(this.tmplStr, this.env.asyncFilters, this.env.extensionsList, this.path, this.env.opts);
28
+ /**
29
+ * 将一些 Nunjucks 的 HTML 转义的代码转换成 SQL 防注入的代码
30
+ */
31
+ source = _replaceCodeWithSQLFeature(source);
32
+ const props = new Function(source)();
33
+ this.blocks = this._getBlocks(props);
34
+ this[ROOT_RENDER_FUNC] = props.root;
35
+ this.rootRenderFunc = function(env, context, frame, _runtime, cb) {
36
+ /**
37
+ * 1. 将 runtime 遗弃,用新的
38
+ * 2. 移除 SQL 语句中多余空白符
39
+ */
40
+ return this[ROOT_RENDER_FUNC](env, context, frame, RUNTIME, function(err, ret) {
41
+ // istanbul ignore if
42
+ if (err) return cb(err, ret);
43
+ return cb(err, SqlUtil.minify(ret || ""));
44
+ });
45
+ };
46
+ this.compiled = true;
47
+ }
48
+ var NunjucksUtils = class {
49
+ static createEnv(modelName) {
50
+ if (envs[modelName]) return envs[modelName];
51
+ return envs[modelName] = nunjucks.configure({ autoescape: false });
52
+ }
53
+ static compile(modelName, sqlName, sql) {
54
+ // istanbul ignore if
55
+ if (!envs[modelName]) throw new Error(`you should create an Environment for ${modelName} first.`);
56
+ const template = new Template(sql, envs[modelName], `egg-dal:MySQL:${modelName}:${sqlName}`, false);
57
+ template._compile = _compile;
58
+ template.compile();
59
+ return template;
60
+ }
61
+ };
62
+
63
+ //#endregion
64
+ export { NunjucksUtils };
@@ -0,0 +1,13 @@
1
+ import { TableModel } from "@eggjs/dal-decorator";
2
+
3
+ //#region src/SqlGenerator.d.ts
4
+ declare class SqlGenerator {
5
+ private formatComment;
6
+ private generateColumn;
7
+ private generateColumnType;
8
+ private generateIndex;
9
+ private generateTableOptions;
10
+ generate(tableModel: TableModel): string;
11
+ }
12
+ //#endregion
13
+ export { SqlGenerator };
@@ -0,0 +1,224 @@
1
+ import { ColumnModel, TableModel } from "@eggjs/dal-decorator";
2
+ import { ColumnType, IndexType } from "@eggjs/tegg-types";
3
+
4
+ //#region src/SqlGenerator.ts
5
+ var SqlGenerator = class {
6
+ formatComment(comment) {
7
+ return comment.replace(/\n/g, "\\n");
8
+ }
9
+ generateColumn(column) {
10
+ const sqls = [
11
+ " ",
12
+ column.columnName,
13
+ this.generateColumnType(column.type)
14
+ ];
15
+ if (column.canNull) sqls.push("NULL");
16
+ else sqls.push("NOT NULL");
17
+ if ([
18
+ ColumnType.POINT,
19
+ ColumnType.GEOMETRY,
20
+ ColumnType.POINT,
21
+ ColumnType.LINESTRING,
22
+ ColumnType.POLYGON,
23
+ ColumnType.MULTIPOINT,
24
+ ColumnType.MULTILINESTRING,
25
+ ColumnType.MULTIPOLYGON,
26
+ ColumnType.GEOMETRYCOLLECTION
27
+ ].includes(column.type.type)) {
28
+ const SRID = column.type.SRID;
29
+ if (SRID) sqls.push(`SRID ${SRID}`);
30
+ }
31
+ if (typeof column.default !== "undefined") sqls.push(`DEFAULT ${column.default}`);
32
+ if (column.autoIncrement) sqls.push("AUTO_INCREMENT");
33
+ if (column.uniqueKey) sqls.push("UNIQUE KEY");
34
+ if (column.primaryKey) sqls.push("PRIMARY KEY");
35
+ if (column.comment) sqls.push(`COMMENT '${this.formatComment(column.comment)}'`);
36
+ if (column.collate) sqls.push(`COLLATE ${column.collate}`);
37
+ if (column.columnFormat) sqls.push(`COLUMN_FORMAT ${column.columnFormat}`);
38
+ if (column.engineAttribute) sqls.push(`ENGINE_ATTRIBUTE='${column.engineAttribute}'`);
39
+ if (column.secondaryEngineAttribute) sqls.push(`SECONDARY_ENGINE_ATTRIBUTE='${column.secondaryEngineAttribute}'`);
40
+ return sqls.join(" ");
41
+ }
42
+ generateColumnType(columnType) {
43
+ const sqls = [];
44
+ switch (columnType.type) {
45
+ case ColumnType.BOOL:
46
+ sqls.push("BOOL");
47
+ break;
48
+ case ColumnType.BIT:
49
+ if (columnType.length) sqls.push(`BIT(${columnType.length})`);
50
+ else sqls.push("BIT");
51
+ break;
52
+ case ColumnType.TINYINT:
53
+ case ColumnType.SMALLINT:
54
+ case ColumnType.MEDIUMINT:
55
+ case ColumnType.INT:
56
+ case ColumnType.BIGINT:
57
+ if (typeof columnType.length === "number") sqls.push(`${columnType.type}(${columnType.length})`);
58
+ else sqls.push(columnType.type);
59
+ if (columnType.unsigned) sqls.push("UNSIGNED");
60
+ if (columnType.zeroFill) sqls.push("ZEROFILL");
61
+ break;
62
+ case ColumnType.DECIMAL:
63
+ case ColumnType.FLOAT:
64
+ case ColumnType.DOUBLE:
65
+ if (typeof columnType.length === "number" && typeof columnType.fractionalLength === "number") sqls.push(`${columnType.type}(${columnType.length},${columnType.fractionalLength})`);
66
+ else if (typeof columnType.length === "number") sqls.push(`${columnType.type}(${columnType.length})`);
67
+ else sqls.push("TINYINT");
68
+ if (columnType.unsigned) sqls.push("UNSIGNED");
69
+ if (columnType.zeroFill) sqls.push("ZEROFILL");
70
+ break;
71
+ case ColumnType.DATE:
72
+ sqls.push("DATE");
73
+ break;
74
+ case ColumnType.DATETIME:
75
+ case ColumnType.TIMESTAMP:
76
+ if (columnType.precision) sqls.push(`${columnType.type}(${columnType.precision})`);
77
+ else sqls.push(columnType.type);
78
+ if (columnType.autoUpdate) if (columnType.precision) sqls.push(`ON UPDATE CURRENT_TIMESTAMP(${columnType.precision})`);
79
+ else sqls.push("ON UPDATE CURRENT_TIMESTAMP");
80
+ break;
81
+ case ColumnType.TIME:
82
+ if (columnType.precision) sqls.push(`${columnType.type}(${columnType.precision})`);
83
+ else sqls.push(columnType.type);
84
+ break;
85
+ case ColumnType.YEAR:
86
+ sqls.push("YEAR");
87
+ break;
88
+ case ColumnType.CHAR:
89
+ case ColumnType.TEXT:
90
+ if (columnType.length) sqls.push(`${columnType.type}(${columnType.length})`);
91
+ else sqls.push(columnType.type);
92
+ if (columnType.characterSet) sqls.push(`CHARACTER SET ${columnType.characterSet}`);
93
+ if (columnType.collate) sqls.push(`COLLATE ${columnType.collate}`);
94
+ break;
95
+ case ColumnType.VARCHAR:
96
+ sqls.push(`${columnType.type}(${columnType.length})`);
97
+ if (columnType.characterSet) sqls.push(`CHARACTER SET ${columnType.characterSet}`);
98
+ if (columnType.collate) sqls.push(`COLLATE ${columnType.collate}`);
99
+ break;
100
+ case ColumnType.BINARY:
101
+ if (columnType.length) sqls.push(`${columnType.type}(${columnType.length})`);
102
+ else sqls.push(columnType.type);
103
+ break;
104
+ case ColumnType.VARBINARY:
105
+ sqls.push(`${columnType.type}(${columnType.length})`);
106
+ break;
107
+ case ColumnType.TINYBLOB:
108
+ sqls.push("TINYBLOB");
109
+ break;
110
+ case ColumnType.TINYTEXT:
111
+ case ColumnType.MEDIUMTEXT:
112
+ case ColumnType.LONGTEXT:
113
+ sqls.push(columnType.type);
114
+ if (columnType.characterSet) sqls.push(`CHARACTER SET ${columnType.characterSet}`);
115
+ if (columnType.collate) sqls.push(`COLLATE ${columnType.collate}`);
116
+ break;
117
+ case ColumnType.BLOB:
118
+ if (columnType.length) sqls.push(`${columnType.type}(${columnType.length})`);
119
+ else sqls.push(columnType.type);
120
+ break;
121
+ case ColumnType.MEDIUMBLOB:
122
+ sqls.push("MEDIUMBLOB");
123
+ break;
124
+ case ColumnType.LONGBLOB:
125
+ sqls.push("LONGBLOB");
126
+ break;
127
+ case ColumnType.ENUM: {
128
+ const enumValue = columnType.enums.map((t) => `'${t}'`).join(",");
129
+ sqls.push(`ENUM(${enumValue})`);
130
+ if (columnType.characterSet) sqls.push(`CHARACTER SET ${columnType.characterSet}`);
131
+ if (columnType.collate) sqls.push(`COLLATE ${columnType.collate}`);
132
+ break;
133
+ }
134
+ case ColumnType.SET: {
135
+ const enumValue = columnType.enums.map((t) => `'${t}'`).join(",");
136
+ sqls.push(`SET(${enumValue})`);
137
+ if (columnType.characterSet) sqls.push(`CHARACTER SET ${columnType.characterSet}`);
138
+ if (columnType.collate) sqls.push(`COLLATE ${columnType.collate}`);
139
+ break;
140
+ }
141
+ case ColumnType.JSON:
142
+ sqls.push("JSON");
143
+ break;
144
+ case ColumnType.GEOMETRY:
145
+ case ColumnType.POINT:
146
+ case ColumnType.LINESTRING:
147
+ case ColumnType.POLYGON:
148
+ case ColumnType.MULTIPOINT:
149
+ case ColumnType.MULTILINESTRING:
150
+ case ColumnType.MULTIPOLYGON:
151
+ case ColumnType.GEOMETRYCOLLECTION:
152
+ sqls.push(columnType.type);
153
+ break;
154
+ default: throw new Error(`unknown ColumnType ${columnType}`);
155
+ }
156
+ return sqls.join(" ");
157
+ }
158
+ generateIndex(indexModel) {
159
+ const indexSql = [" "];
160
+ switch (indexModel.type) {
161
+ case IndexType.INDEX:
162
+ indexSql.push("KEY");
163
+ break;
164
+ case IndexType.UNIQUE:
165
+ indexSql.push("UNIQUE KEY");
166
+ break;
167
+ case IndexType.PRIMARY:
168
+ indexSql.push("PRIMARY KEY");
169
+ break;
170
+ case IndexType.FULLTEXT:
171
+ indexSql.push("FULLTEXT KEY");
172
+ break;
173
+ case IndexType.SPATIAL:
174
+ indexSql.push("SPATIAL KEY");
175
+ break;
176
+ default: throw new Error(`unknown IndexType ${indexModel.type}`);
177
+ }
178
+ indexSql.push(indexModel.name);
179
+ indexSql.push(`(${indexModel.keys.map((t) => t.columnName).join(",")})`);
180
+ if (indexModel.storeType) indexSql.push(`USING ${indexModel.storeType}`);
181
+ if (indexModel.parser) indexSql.push(`WITH PARSER ${indexModel.parser}`);
182
+ if (indexModel.comment) indexSql.push(`COMMENT '${this.formatComment(indexModel.comment)}'`);
183
+ if (indexModel.engineAttribute) indexSql.push(`ENGINE_ATTRIBUTE='${indexModel.engineAttribute}'`);
184
+ if (indexModel.secondaryEngineAttribute) indexSql.push(`SECONDARY_ENGINE_ATTRIBUTE='${indexModel.secondaryEngineAttribute}'`);
185
+ return indexSql.join(" ");
186
+ }
187
+ generateTableOptions(tableModel) {
188
+ const sqls = [];
189
+ if (tableModel.autoExtendSize) sqls.push(`AUTOEXTEND_SIZE=${tableModel.autoExtendSize}`);
190
+ if (tableModel.autoIncrement) sqls.push(`AUTO_INCREMENT=${tableModel.autoIncrement}`);
191
+ if (tableModel.avgRowLength) sqls.push(`AVG_ROW_LENGTH=${tableModel.avgRowLength}`);
192
+ if (tableModel.characterSet) sqls.push(`DEFAULT CHARACTER SET ${tableModel.characterSet}`);
193
+ if (tableModel.collate) sqls.push(`DEFAULT COLLATE ${tableModel.collate}`);
194
+ if (tableModel.comment) sqls.push(`COMMENT='${this.formatComment(tableModel.comment)}'`);
195
+ if (tableModel.compression) sqls.push(`COMPRESSION='${tableModel.compression}'`);
196
+ if (typeof tableModel.encryption !== "undefined") sqls.push(`ENCRYPTION='${tableModel.encryption ? "Y" : "N"}'`);
197
+ if (typeof tableModel.engine !== "undefined") sqls.push(`ENGINE=${tableModel.engine}`);
198
+ if (tableModel.engineAttribute) sqls.push(`ENGINE_ATTRIBUTE='${tableModel.engineAttribute}'`);
199
+ if (tableModel.secondaryEngineAttribute) sqls.push(`SECONDARY_ENGINE_ATTRIBUTE = '${tableModel.secondaryEngineAttribute}'`);
200
+ if (tableModel.insertMethod) sqls.push(`INSERT_METHOD=${tableModel.insertMethod}`);
201
+ if (tableModel.keyBlockSize) sqls.push(`KEY_BLOCK_SIZE=${tableModel.keyBlockSize}`);
202
+ if (tableModel.maxRows) sqls.push(`MAX_ROWS=${tableModel.maxRows}`);
203
+ if (tableModel.minRows) sqls.push(`MIN_ROWS=${tableModel.minRows}`);
204
+ if (tableModel.rowFormat) sqls.push(`ROW_FORMAT=${tableModel.rowFormat}`);
205
+ return sqls.join(", ");
206
+ }
207
+ generate(tableModel) {
208
+ const createSql = [];
209
+ createSql.push(`CREATE TABLE IF NOT EXISTS ${tableModel.name} (`);
210
+ const columnSql = [];
211
+ for (const column of tableModel.columns) columnSql.push(this.generateColumn(column));
212
+ const indexSql = [];
213
+ for (const index of tableModel.indices) indexSql.push(this.generateIndex(index));
214
+ if (indexSql.length) {
215
+ createSql.push(columnSql.join(",\n") + ",");
216
+ createSql.push(indexSql.join(",\n"));
217
+ } else createSql.push(columnSql.join(",\n"));
218
+ createSql.push(`) ${this.generateTableOptions(tableModel)};`);
219
+ return createSql.join("\n");
220
+ }
221
+ };
222
+
223
+ //#endregion
224
+ export { SqlGenerator };
@@ -0,0 +1,14 @@
1
+ import { TableSqlMap } from "./TableSqlMap.js";
2
+ import { BaseDaoType, TableModel } from "@eggjs/dal-decorator";
3
+ import { Logger } from "@eggjs/tegg-types";
4
+
5
+ //#region src/SqlMapLoader.d.ts
6
+ declare class SqlMapLoader {
7
+ private readonly logger;
8
+ private readonly tableModel;
9
+ private readonly clazzExtension;
10
+ constructor(tableModel: TableModel, baseDaoClazz: BaseDaoType, logger: Logger);
11
+ load(): TableSqlMap;
12
+ }
13
+ //#endregion
14
+ export { SqlMapLoader };
@@ -0,0 +1,22 @@
1
+ import { BaseSqlMapGenerator } from "./BaseSqlMap.js";
2
+ import { TableSqlMap } from "./TableSqlMap.js";
3
+ import { TableModel } from "@eggjs/dal-decorator";
4
+
5
+ //#region src/SqlMapLoader.ts
6
+ var SqlMapLoader = class {
7
+ constructor(tableModel, baseDaoClazz, logger) {
8
+ this.clazzExtension = baseDaoClazz.clazzExtension;
9
+ this.logger = logger;
10
+ this.tableModel = tableModel;
11
+ }
12
+ load() {
13
+ const sqlMap = {
14
+ ...new BaseSqlMapGenerator(this.tableModel, this.logger).load(),
15
+ ...this.clazzExtension
16
+ };
17
+ return new TableSqlMap(this.tableModel.clazz.name, sqlMap);
18
+ }
19
+ };
20
+
21
+ //#endregion
22
+ export { SqlMapLoader };
@@ -0,0 +1,6 @@
1
+ //#region src/SqlUtil.d.ts
2
+ declare class SqlUtil {
3
+ static minify(sql: string): string;
4
+ }
5
+ //#endregion
6
+ export { SqlUtil };