pg-mvc-service 1.0.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.
Files changed (56) hide show
  1. package/README.md +1 -0
  2. package/dist/PoolManager.js +57 -0
  3. package/dist/Service.js +257 -0
  4. package/dist/clients/AwsS3Client.js +249 -0
  5. package/dist/clients/Base64Client.js +153 -0
  6. package/dist/clients/EncryptClient.js +85 -0
  7. package/dist/clients/StringClient.js +13 -0
  8. package/dist/documents/Swagger.js +94 -0
  9. package/dist/exceptions/Exception.js +53 -0
  10. package/dist/index.js +16 -0
  11. package/dist/models/MigrateDatabase.js +138 -0
  12. package/dist/models/MigrateRollback.js +146 -0
  13. package/dist/models/MigrateTable.js +51 -0
  14. package/dist/models/SqlUtils/SelectExpression.js +92 -0
  15. package/dist/models/SqlUtils/ValidateValueUtil.js +250 -0
  16. package/dist/models/SqlUtils/WhereExpression.js +256 -0
  17. package/dist/models/TableDoc.js +353 -0
  18. package/dist/models/TableModel.js +636 -0
  19. package/dist/models/Type.js +2 -0
  20. package/dist/models/Utils/DateTimeUtil.js +134 -0
  21. package/dist/models/Utils/NumberUtil.js +28 -0
  22. package/dist/models/Utils/StringUtil.js +31 -0
  23. package/dist/models/ValidateClient.js +164 -0
  24. package/dist/models/index.js +14 -0
  25. package/dist/reqestResponse/ReqResType.js +196 -0
  26. package/dist/reqestResponse/RequestType.js +742 -0
  27. package/dist/reqestResponse/ResponseType.js +380 -0
  28. package/index.d.ts +306 -0
  29. package/package.json +36 -0
  30. package/src/PoolManager.ts +48 -0
  31. package/src/Service.ts +251 -0
  32. package/src/clients/AwsS3Client.ts +229 -0
  33. package/src/clients/Base64Client.ts +155 -0
  34. package/src/clients/EncryptClient.ts +100 -0
  35. package/src/clients/StringClient.ts +14 -0
  36. package/src/documents/Swagger.ts +111 -0
  37. package/src/exceptions/Exception.ts +54 -0
  38. package/src/index.ts +7 -0
  39. package/src/models/MigrateDatabase.ts +135 -0
  40. package/src/models/MigrateRollback.ts +151 -0
  41. package/src/models/MigrateTable.ts +56 -0
  42. package/src/models/SqlUtils/SelectExpression.ts +97 -0
  43. package/src/models/SqlUtils/ValidateValueUtil.ts +270 -0
  44. package/src/models/SqlUtils/WhereExpression.ts +286 -0
  45. package/src/models/TableDoc.ts +360 -0
  46. package/src/models/TableModel.ts +713 -0
  47. package/src/models/Type.ts +59 -0
  48. package/src/models/Utils/DateTimeUtil.ts +146 -0
  49. package/src/models/Utils/NumberUtil.ts +23 -0
  50. package/src/models/Utils/StringUtil.ts +33 -0
  51. package/src/models/ValidateClient.ts +182 -0
  52. package/src/models/index.ts +7 -0
  53. package/src/reqestResponse/ReqResType.ts +242 -0
  54. package/src/reqestResponse/RequestType.ts +851 -0
  55. package/src/reqestResponse/ResponseType.ts +418 -0
  56. package/tsconfig.json +14 -0
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ValidateValueUtil_1 = __importDefault(require("./ValidateValueUtil"));
7
+ class WhereExpression {
8
+ /**
9
+ * Helper method to create OR conditions
10
+ * @param conditions Array of conditions that make up the OR condition
11
+ * @returns SQL query string representing the OR condition
12
+ */
13
+ static createCondition(conditions, model, varLength) {
14
+ if (conditions.length === 0) {
15
+ return { sql: '' };
16
+ }
17
+ let logicalOperator = 'AND';
18
+ if (conditions[0] === 'AND' || conditions[0] === 'OR') {
19
+ if (conditions.length === 1) {
20
+ return { sql: '' };
21
+ }
22
+ logicalOperator = conditions[0];
23
+ conditions.shift();
24
+ }
25
+ const expression = [];
26
+ let vars = [];
27
+ for (let condition of conditions) {
28
+ if (Array.isArray(condition)) {
29
+ // If it's an array, it's a nested condition, so call this function recursively
30
+ const query = this.createCondition(condition, model, varLength + vars.length);
31
+ expression.push(query.sql);
32
+ if (query.vars !== undefined) {
33
+ vars = [...vars, ...query.vars];
34
+ }
35
+ continue;
36
+ }
37
+ if (typeof condition === 'string') {
38
+ // If specified directly as a string, it becomes a query, so insert as is
39
+ expression.push(condition);
40
+ continue;
41
+ }
42
+ if (typeof condition.l === 'string') {
43
+ const query = this.create({ model: model, name: condition.l }, condition.o, condition.r, varLength + vars.length);
44
+ expression.push(query.sql);
45
+ if (query.vars !== undefined) {
46
+ vars = [...vars, ...query.vars];
47
+ }
48
+ continue;
49
+ }
50
+ const query = this.create(condition.l, condition.o, condition.r, varLength + vars.length);
51
+ expression.push(query.sql);
52
+ if (query.vars !== undefined) {
53
+ vars = [...vars, ...query.vars];
54
+ }
55
+ }
56
+ return {
57
+ sql: `(${expression.filter(condition => condition !== null && condition !== void 0 ? condition : '' !== '').join(` ${logicalOperator} `)})`,
58
+ vars: vars
59
+ };
60
+ }
61
+ static create(left, operator, right, varLength) {
62
+ // Check if the specified ColumnInfo exists
63
+ const leftColumn = left.model.getColumn(left.name);
64
+ // Are the operators correct?
65
+ const useableOperator = {
66
+ number: ["=", "!=", ">", ">=", "<", "<=", "in", "not in"],
67
+ 'number[]': [],
68
+ string: ["=", "!=", "like", "ilike", "h2f_like", "h2f_ilike", "in", "not in"],
69
+ 'string[]': [],
70
+ uuid: ["=", "!=", "in", "not in"],
71
+ 'uuid[]': [],
72
+ bool: ["=", "!=", "in", "not in"],
73
+ 'bool[]': [],
74
+ date: ["=", "!=", ">", ">=", "<", "<="],
75
+ 'date[]': [],
76
+ time: ["=", "!=", ">", ">=", "<", "<="],
77
+ 'time[]': [],
78
+ timestamp: ["=", "!=", ">", ">=", "<", "<="],
79
+ 'timestamp[]': []
80
+ };
81
+ if (useableOperator[leftColumn.type].includes(operator) == false) {
82
+ throw new Error(`The ${operator} operator cannot be used for ${leftColumn.tableName}.${leftColumn.columnName}. (${leftColumn.type})`);
83
+ }
84
+ if (right === null) {
85
+ if (leftColumn.attribute !== "nullable") {
86
+ throw new Error(`You cannot use conditions with null values unless the attribute is nullable.`);
87
+ }
88
+ if (operator == "=") {
89
+ return {
90
+ sql: `${leftColumn.expression} is null`
91
+ };
92
+ }
93
+ else if (operator == "!=") {
94
+ return {
95
+ sql: `${leftColumn.expression} is not null`
96
+ };
97
+ }
98
+ else {
99
+ throw new Error(`When comparing with null, operators other than =, != cannot be used. (${operator})`);
100
+ }
101
+ }
102
+ if (leftColumn.type.endsWith("[]")) {
103
+ return this.createExpression(leftColumn, operator, right, varLength);
104
+ }
105
+ else {
106
+ return this.createExpression(leftColumn, operator, right, varLength);
107
+ }
108
+ }
109
+ static createExpression(leftColumn, operator, right, varLength) {
110
+ // IN NOT IN clause
111
+ if (["in", "not in"].includes(operator)) {
112
+ if (Array.isArray(right) == false) {
113
+ throw new Error(`For the 'in' operator, you cannot input anything other than an array on the right side.`);
114
+ }
115
+ if (right.length == 0) {
116
+ // Creating in, not in with 0 elements will cause an error, but since the data to be passed is correct and the expected return value does not change, do not search if there are 0 elements
117
+ return { sql: '' };
118
+ }
119
+ // Validate values
120
+ for (const value of right) {
121
+ ValidateValueUtil_1.default.validateValue(leftColumn, value);
122
+ }
123
+ return {
124
+ sql: `${leftColumn.expression} ${operator === 'in' ? '=' : '!='} ANY($${varLength})`,
125
+ vars: [right]
126
+ };
127
+ }
128
+ else if (Array.isArray(right)) {
129
+ throw new Error(`For operators other than 'in', you cannot input an array on the right side.`);
130
+ }
131
+ // If the right side value is a column specification
132
+ if (right !== null && typeof right === 'object' && 'model' in right && 'name' in right) {
133
+ const rightColumn = right.model.getColumn(right.name);
134
+ if (leftColumn.type !== rightColumn.type) {
135
+ throw new Error(`The types of [${leftColumn.tableName}].[${leftColumn.columnName}] and [${rightColumn.tableName}].[${rightColumn.columnName}] are different.`);
136
+ }
137
+ // LIKE operators are different, so handle separately
138
+ switch (operator) {
139
+ case 'like':
140
+ case 'ilike':
141
+ return {
142
+ sql: `${leftColumn.expression} ${operator} '%' || ${rightColumn.expression} || '%'`
143
+ };
144
+ case 'h2f_like': // half to full like
145
+ case 'h2f_ilike': // half to full ilike
146
+ return {
147
+ sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`'%' || ${rightColumn.expression} || '%'`)}`
148
+ };
149
+ }
150
+ return {
151
+ sql: `${leftColumn.expression} ${operator} ${rightColumn.expression}`
152
+ };
153
+ }
154
+ ValidateValueUtil_1.default.validateValue(leftColumn, right);
155
+ // LIKE operators are different, so handle separately
156
+ switch (operator) {
157
+ case 'like':
158
+ case 'ilike':
159
+ return {
160
+ sql: `${leftColumn.expression} ${operator} $${varLength}`,
161
+ vars: [`%${right}%`]
162
+ };
163
+ case 'h2f_like': // half to full like
164
+ case 'h2f_ilike': // half to full ilike
165
+ return {
166
+ sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`$${varLength}`)}`,
167
+ vars: [`%${right}%`]
168
+ };
169
+ }
170
+ return {
171
+ sql: `${leftColumn.expression} ${operator} $${varLength}`,
172
+ vars: [right]
173
+ };
174
+ }
175
+ static createExpressionArrayValue(leftColumn, operator, right, varLength) {
176
+ // ValidateValueUtil.validateValue(leftColumn, right);
177
+ // LIKE operators are different, so handle separately
178
+ // switch (operator) {
179
+ // case 'like':
180
+ // case 'ilike':
181
+ // return {
182
+ // sql: `${leftColumn.expression} ${operator} $${varLength}`,
183
+ // vars: [`%${right}%`]
184
+ // }
185
+ // case 'h2f_like': // half to full like
186
+ // case 'h2f_ilike': // half to full ilike
187
+ // return {
188
+ // sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`$${varLength}`)}`,
189
+ // vars: [`%${right}%`]
190
+ // }
191
+ // }
192
+ switch (operator) {
193
+ case '=':
194
+ // バリデーションチェックをする
195
+ return {
196
+ sql: `${leftColumn.expression} ${operator} $${varLength}`,
197
+ vars: [right]
198
+ };
199
+ }
200
+ return {
201
+ sql: `${leftColumn.expression} ${operator} $${varLength}`,
202
+ vars: [right]
203
+ };
204
+ }
205
+ /**
206
+ * SQL statement to convert half-width characters to full-width
207
+ * @param {string} columnName Column name
208
+ * @returns SQL statement
209
+ */
210
+ static makeSqlReplaceHalfToFull(columnNameOrValue) {
211
+ const num = {
212
+ '0': '0', '1': '1', '2': '2', '3': '3', '4': '4',
213
+ '5': '5', '6': '6', '7': '7', '8': '8', '9': '9'
214
+ };
215
+ const kana = {
216
+ 'ア': 'ア', 'イ': 'イ', 'ウ': 'ウ', 'エ': 'エ', 'オ': 'オ',
217
+ 'カ': 'カ', 'キ': 'キ', 'ク': 'ク', 'ケ': 'ケ', 'コ': 'コ',
218
+ 'サ': 'サ', 'シ': 'シ', 'ス': 'ス', 'セ': 'セ', 'ソ': 'ソ',
219
+ 'タ': 'タ', 'チ': 'チ', 'ツ': 'ツ', 'テ': 'テ', 'ト': 'ト',
220
+ 'ナ': 'ナ', 'ニ': 'ニ', 'ヌ': 'ヌ', 'ネ': 'ネ', 'ノ': 'ノ',
221
+ 'ハ': 'ハ', 'ヒ': 'ヒ', 'フ': 'フ', 'ヘ': 'ヘ', 'ホ': 'ホ',
222
+ 'マ': 'マ', 'ミ': 'ミ', 'ム': 'ム', 'メ': 'メ', 'モ': 'モ',
223
+ 'ヤ': 'ヤ', 'ユ': 'ユ', 'ヨ': 'ヨ',
224
+ 'ラ': 'ラ', 'リ': 'リ', 'ル': 'ル', 'レ': 'レ', 'ロ': 'ロ',
225
+ 'ワ': 'ワ', 'ヲ': 'ヲ', 'ン': 'ン',
226
+ 'ヴ': 'ヴ',
227
+ 'ガ': 'ガ', 'ギ': 'ギ', 'グ': 'グ', 'ゲ': 'ゲ', 'ゴ': 'ゴ',
228
+ 'ザ': 'ザ', 'ジ': 'ジ', 'ズ': 'ズ', 'ゼ': 'ゼ', 'ゾ': 'ゾ',
229
+ 'ダ': 'ダ', 'ヂ': 'ヂ', 'ヅ': 'ヅ', 'デ': 'デ', 'ド': 'ド',
230
+ 'バ': 'ハ', 'ビ': 'ビ', 'ブ': 'ブ', 'ベ': 'ベ', 'ボ': 'ボ',
231
+ 'パ': 'パ', 'ピ': 'ピ', 'プ': 'プ', 'ペ': 'ペ', 'ポ': 'ポ',
232
+ 'ァ': 'ァ', 'ィ': 'ィ', 'ゥ': 'ゥ', 'ェ': 'ェ', 'ォ': 'ォ',
233
+ 'ャ': 'ャ', 'ュ': 'ュ', 'ョ': 'ョ',
234
+ 'ッ': 'ッ',
235
+ 'ー': 'ー', '、': '、', '。': '。', '・': '・', '「': '「', '」': '」', '゛': ' ゙', '゜': ' ゚'
236
+ };
237
+ const alpha = {
238
+ 'A': 'A', 'B': 'B', 'C': 'C', 'D': 'D', 'E': 'E', 'F': 'F', 'G': 'G',
239
+ 'H': 'H', 'I': 'I', 'J': 'J', 'K': 'K', 'L': 'L', 'M': 'M', 'N': 'N',
240
+ 'O': 'O', 'P': 'P', 'Q': 'Q', 'R': 'R', 'S': 'S', 'T': 'T', 'U': 'U',
241
+ 'V': 'V', 'W': 'W', 'X': 'X', 'Y': 'Y', 'Z': 'Z',
242
+ 'a': 'a', 'b': 'b', 'c': 'c', 'd': 'd', 'e': 'e', 'f': 'f', 'g': 'g',
243
+ 'h': 'h', 'i': 'i', 'j': 'j', 'k': 'k', 'l': 'l', 'm': 'm', 'n': 'n',
244
+ 'o': 'o', 'p': 'p', 'q': 'q', 'r': 'r', 's': 's', 't': 't', 'u': 'u',
245
+ 'v': 'v', 'w': 'w', 'x': 'x', 'y': 'y', 'z': 'z',
246
+ };
247
+ let objs = {};
248
+ Object.assign(objs, num);
249
+ Object.assign(objs, kana);
250
+ Object.assign(objs, alpha);
251
+ let sql = columnNameOrValue;
252
+ Object.keys(objs).forEach(key => sql = `TRANSLATE(${sql} ,'${key}','${objs[key]}')`);
253
+ return sql;
254
+ }
255
+ }
256
+ exports.default = WhereExpression;
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTableDoc = void 0;
4
+ const createTableDoc = (models, serviceName) => {
5
+ var _a, _b, _c, _d;
6
+ let html = `
7
+ <!DOCTYPE html>
8
+ <html lang="ja">
9
+ <head>
10
+ <meta charset="UTF-8">
11
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
12
+ <title>table document</title>
13
+ </head>
14
+ <style>
15
+ :root {
16
+ --primary: rgb(73, 204, 144);
17
+ --primary-dark: rgb(64, 169, 121);
18
+ --bg-primary: rgba(73, 204, 144, 0.15);
19
+ --border-primary: rgba(73, 204, 144, 0.3);
20
+ --border-gray: rgb(200, 200, 200);
21
+ }
22
+
23
+ body {
24
+ padding: 0px;
25
+ padding-left: 12px;
26
+ padding-right: 12px;
27
+ margin: 0px;
28
+ color: rgb(30, 35, 40);
29
+ }
30
+
31
+
32
+ button {
33
+ padding-left: 8px;
34
+ padding-right: 8px;
35
+ padding-top: 2px;
36
+ padding-bottom: 2px;
37
+ background-color: var(--primary);
38
+ border: 0px;
39
+ color: #ffffff;
40
+ border-radius: 999px;
41
+ }
42
+
43
+ button:hover {
44
+ background-color: var(--primary-dark);
45
+ }
46
+
47
+ /* title*/
48
+ h1 {
49
+ font-size: 28px;
50
+ font-weight: bold;
51
+ }
52
+
53
+ /* db-title*/
54
+ h2 {
55
+ background-color: var(--primary);
56
+ border-top-left-radius: 8px;
57
+ border-top-right-radius: 8px;
58
+ color: #ffffff;
59
+ padding-left: 4px;
60
+ margin: 0;
61
+ font-size: 24px;
62
+ font-weight: bold;
63
+ }
64
+
65
+ .db-wrapper {
66
+ border-radius: 8px;
67
+ border: var(--primary) solid 1px;
68
+ margin-bottom: 24px;
69
+ }
70
+
71
+ /* table-title*/
72
+ h3 {
73
+ font-size: 18px;
74
+ font-weight: bold;
75
+ }
76
+
77
+ .table-wrapper {
78
+ padding: 0px;
79
+ margin-bottom: 16px;
80
+ }
81
+
82
+ .table-title-wrapper {
83
+ background-color: var(--bg-primary);
84
+ border-top: var(--border-primary) solid 1px;
85
+ margin: 0;
86
+ padding: 2px 4px;
87
+ align-items: center;
88
+ display: flex;
89
+ }
90
+
91
+ .table-title-left {
92
+ font-size: 18px;
93
+ font-weight: bold;
94
+ text-align: left;
95
+ font-size: 18px;
96
+ font-weight: bold;
97
+ }
98
+
99
+ .table-title-right {
100
+ margin-left: auto;
101
+ padding: 2px;
102
+ }
103
+
104
+ .comment-wrapper {
105
+ padding-left: 4px;
106
+ padding-top: 4px;
107
+ padding-bottom: 8px;
108
+ font-size: 14px;
109
+ }
110
+
111
+ table {
112
+ border-collapse: collapse;
113
+ margin-top: 0px;
114
+ margin-left: 8px;
115
+ margin-right: 8px;
116
+ margin-bottom: 12px;
117
+ font-size: 14px;
118
+ }
119
+
120
+ tr:nth-child(odd) {
121
+ background-color: var(--bg-primary); /* 奇数行の背景色を変更 */
122
+ }
123
+
124
+ tr:nth-child(even) {
125
+ background-color: #ffffff; /* 偶数行の背景色を変更 */
126
+ }
127
+
128
+ th {
129
+ padding-left: 4px;
130
+ padding-right: 4px;
131
+ background-color: var(--primary);
132
+ color: #ffffff;
133
+ border: 1px solid var(--border-gray); /* 線の色と太さを指定 */
134
+ }
135
+
136
+ td {
137
+ border: 1px solid var(--border-primary); /* 線の色と太さを指定 */
138
+ padding-left: 4px;
139
+ padding-right: 4px;
140
+ }
141
+
142
+ /* No */
143
+ td:nth-child(1) {
144
+ width: 16px;
145
+ text-align: center;
146
+ }
147
+
148
+ /* PK */
149
+ td:nth-child(2) {
150
+ width: 24px;
151
+ text-align: center;
152
+ }
153
+
154
+ /* name */
155
+ td:nth-child(3) {
156
+ width: 140px;
157
+ }
158
+
159
+ /* alias */
160
+ td:nth-child(4) {
161
+ width: 180px;
162
+ }
163
+
164
+ /* type */
165
+ td:nth-child(5) {
166
+ width: 60px;
167
+ }
168
+
169
+ /* length */
170
+ td:nth-child(6) {
171
+ width: 40px;
172
+ }
173
+
174
+ /* nullable */
175
+ td:nth-child(7) {
176
+ width: 40px;
177
+ }
178
+
179
+ /* default */
180
+ td:nth-child(8) {
181
+ width: 120px;
182
+ }
183
+
184
+ /* Foreign Key */
185
+ td:nth-child(9) {
186
+ width: 300px;
187
+ }
188
+
189
+ /* comment */
190
+ td:nth-child(10) {
191
+ width: auto;
192
+ }
193
+
194
+ /* function */
195
+ td:nth-child(11) {
196
+ width: auto;
197
+ }
198
+ </style>
199
+
200
+ <body>
201
+ <h1>${serviceName === undefined ? '' : serviceName + ' :'}Your Table Definition Document</h1>
202
+ `;
203
+ const dbObj = {};
204
+ for (const model of models) {
205
+ if (model.DbName in dbObj === false) {
206
+ dbObj[model.DbName] = [];
207
+ }
208
+ dbObj[model.DbName].push(model);
209
+ }
210
+ const jsCripFuncs = {};
211
+ for (const [keyDbName, models] of Object.entries(dbObj)) {
212
+ html += `
213
+ <div class="db-wrapper">
214
+ <h2>${keyDbName} Database</h2>`;
215
+ for (const model of models) {
216
+ const createFuncName = `clipboard_createTable_${model.DbName}_${model.TableName}`;
217
+ html += `
218
+ <div class="table-wrapper">
219
+ <div class="table-title-wrapper">
220
+ <div class="table-title-left">${model.TableName} ${model.TableDescription !== '' ? ` : ${model.TableDescription}` : ''}</div>
221
+ <button class="table-title-right" onclick="${createFuncName}()">Copy Create Query</button>
222
+ </div>
223
+ <div class="comment-wrapper">${model.Comment.replace('\n', '<br>')}</div>
224
+
225
+ <table>
226
+ <tr>
227
+ <th>No</th>
228
+ <th>PK</th>
229
+ <th>name</th>
230
+ <th>alias</th>
231
+ <th>type</th>
232
+ <th>length</th>
233
+ <th>nullable</th>
234
+ <th>default</th>
235
+ <th>foreign key</th>
236
+ <th>comment</th>
237
+ <th>function</th>
238
+ </tr>`;
239
+ const createColExpressions = [];
240
+ const pkColNames = [];
241
+ let index = 0;
242
+ for (const [keyColName, column] of Object.entries(model.Columns)) {
243
+ index++;
244
+ const addFuncName = `clipboard_addColumn_${model.DbName}_${model.TableName}_${keyColName}`;
245
+ const dropFuncName = `clipboard_dropColumn_${model.DbName}_${model.TableName}_${keyColName}`;
246
+ // 外部キー用
247
+ let references = [];
248
+ for (const ref of model.GetReferences(keyColName)) {
249
+ const targetRef = ref.columns.filter(col => col.target === keyColName);
250
+ if (targetRef.length > 0) {
251
+ references.push(`[${ref.table}].[${targetRef[0].ref}]`);
252
+ }
253
+ }
254
+ references = Array.from(new Set(references)); // 重複を除く
255
+ html += `
256
+ <tr>
257
+ <td>${index}</td>
258
+ <td>${column.attribute === 'primary' ? 'PK' : ''}</td>
259
+ <td>${keyColName}</td>
260
+ <td>${(_a = column.alias) !== null && _a !== void 0 ? _a : keyColName}</td>
261
+ <td>${column.type}</td>
262
+ <td>${(_b = column.length) !== null && _b !== void 0 ? _b : ''}</td>
263
+ <td>${column.attribute === 'nullable' ? 'nullable' : ''}</td>
264
+ <td>${column.attribute === 'hasDefault' ? (_c = column.default) !== null && _c !== void 0 ? _c : '???' : ''}</td>
265
+ <td>${references.length === 0 ? '' : references.join('<br>')}</td>
266
+ <td>${((_d = column.comment) !== null && _d !== void 0 ? _d : '').replace('\n', '<br>')}</td>
267
+ <td>
268
+ ${column.attribute === "primary" ? `` : `
269
+ <button onclick="${addFuncName}()">Copy add column</button>
270
+ <button onclick="${dropFuncName}()">Copy drop column</button>
271
+ `}
272
+ </td>
273
+ </tr>`;
274
+ jsCripFuncs[addFuncName] = `ALTER TABLE ${model.TableName} ADD COLUMN ${keyColName} ${toColumnType(column)} ${toColumnAttibute(column)};`;
275
+ jsCripFuncs[dropFuncName] = `ALTER TABLE ${model.TableName} DROP COLUMN ${keyColName};`;
276
+ // CreateTable作成用
277
+ createColExpressions.push(`${keyColName} ${toColumnType(column)} ${toColumnAttibute(column)}`);
278
+ if (column.attribute === 'primary') {
279
+ pkColNames.push(keyColName);
280
+ }
281
+ }
282
+ // CreateTable作成文
283
+ const expressions = [...createColExpressions];
284
+ if (pkColNames.length > 0) {
285
+ expressions.push(`PRIMARY KEY (${pkColNames.join(', ')})`);
286
+ }
287
+ for (const ref of model.References) {
288
+ expressions.push(`FOREIGN KEY (${ref.columns.map(col => col.target).join(', ')}) REFERENCES ${ref.table}(${ref.columns.map(col => col.ref).join(', ')})`);
289
+ }
290
+ jsCripFuncs[createFuncName] = `CREATE TABLE ${model.TableName} (\n ${expressions.join(',\n ')}\n);`;
291
+ html += `
292
+ </table>
293
+ </div>`;
294
+ }
295
+ html += `
296
+ </div>`;
297
+ }
298
+ html += `\n <script>\n`;
299
+ for (const [keyFunName, value] of Object.entries(jsCripFuncs)) {
300
+ html += `
301
+ function ${keyFunName}() {
302
+ const el = document.createElement('textarea');
303
+ el.value = \`${value}\`;
304
+ document.body.appendChild(el);
305
+ el.select();
306
+ document.execCommand('copy');
307
+ document.body.removeChild(el);
308
+ alert('コピーしました');
309
+ }\n`;
310
+ }
311
+ html += ` </script>
312
+ </body>
313
+ </html>
314
+ `;
315
+ return html;
316
+ };
317
+ exports.createTableDoc = createTableDoc;
318
+ function toColumnType(column) {
319
+ if (column.type.startsWith('uuid')) {
320
+ return column.type.replace('uuid', 'UUID');
321
+ }
322
+ else if (column.type.startsWith('bool')) {
323
+ return column.type.replace('bool', 'BOOLEAN');
324
+ }
325
+ else if (column.type.startsWith('date')) {
326
+ return column.type.replace('date', 'DATE');
327
+ }
328
+ else if (column.type.startsWith('number')) {
329
+ return column.type.replace('number', 'INTEGER');
330
+ }
331
+ else if (column.type.startsWith('string')) {
332
+ return column.type.replace('string', `VARCHAR(${column.length})`);
333
+ }
334
+ else if (column.type.startsWith('time')) {
335
+ return column.type.replace('time', 'TIME');
336
+ }
337
+ else if (column.type.startsWith('timestamp')) {
338
+ return column.type.replace('timestamp', 'TIMESTAMP');
339
+ }
340
+ return '';
341
+ }
342
+ function toColumnAttibute(column) {
343
+ switch (column.attribute) {
344
+ case 'hasDefault':
345
+ return 'NOT NULL DEFAULT ' + column.default;
346
+ case 'noDefault':
347
+ return 'NOT NULL';
348
+ case 'nullable':
349
+ return 'NULL';
350
+ case 'primary':
351
+ return ''; // 主キーは後で設定するので
352
+ }
353
+ }