pg-mvc-service 1.0.28 → 2.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.
- package/dist/models/TableModel.js +64 -159
- package/dist/models/Utils/MessageUtil.js +58 -0
- package/package.json +1 -1
- package/src/models/TableModel.ts +74 -165
- package/src/models/Utils/MessageUtil.ts +60 -0
|
@@ -20,6 +20,7 @@ const ValidateClient_1 = __importDefault(require("./ValidateClient"));
|
|
|
20
20
|
const Exception_1 = require("../exceptions/Exception");
|
|
21
21
|
const ExpressionClient_1 = __importDefault(require("./ExpressionClient"));
|
|
22
22
|
const UpdateExpression_1 = __importDefault(require("./SqlUtils/UpdateExpression"));
|
|
23
|
+
const MessageUtil_1 = __importDefault(require("./Utils/MessageUtil"));
|
|
23
24
|
class TableModel {
|
|
24
25
|
get DbName() { return this.dbName; }
|
|
25
26
|
get TableName() {
|
|
@@ -113,71 +114,14 @@ class TableModel {
|
|
|
113
114
|
this.groupExpression = [];
|
|
114
115
|
this.sortExpression = [];
|
|
115
116
|
this.vars = [];
|
|
116
|
-
this.
|
|
117
|
-
'string': '{name} should be entered as a string or number type.',
|
|
118
|
-
'string[]': '{name} should be entered as an array of string or number types.',
|
|
119
|
-
'uuid': '{name} should be entered as a UUID.',
|
|
120
|
-
'uuid[]': '{name} should be entered as an array of UUIDs.',
|
|
121
|
-
'integer': '{name} should be entered as a number.',
|
|
122
|
-
'integer[]': '{name} should be entered as an array of numbers.',
|
|
123
|
-
'real': '{name} should be entered as a number.',
|
|
124
|
-
'real[]': '{name} should be entered as an array of numbers.',
|
|
125
|
-
'bool': '{name} should be entered as a bool type, "true", "false", 0, or 1.',
|
|
126
|
-
'bool[]': '{name} should be entered as an array of bool types, "true", "false", 0, or 1.',
|
|
127
|
-
'date': '{name} should be entered in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as a Date type.',
|
|
128
|
-
'date[]': '{name} should be entered as an array of dates in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as Date types.',
|
|
129
|
-
'time': '{name} should be entered in "hh:mi" format or "hh:mi:ss" format.',
|
|
130
|
-
'time[]': '{name} should be entered as an array of times in "hh:mi" format or "hh:mi:ss" format.',
|
|
131
|
-
'timestamp': '{name} should be entered in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as a Date type.',
|
|
132
|
-
'timestamp[]': '{name} should be entered as an array of timestamps in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as Date types.',
|
|
133
|
-
'json': '{name} should be entered as an Object or JSON string.',
|
|
134
|
-
'json[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
135
|
-
'jsonb': '{name} should be entered as an Object or JSON string.',
|
|
136
|
-
'jsonb[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
137
|
-
'length': '{name} should be entered within {length} characters.',
|
|
138
|
-
'null': '{name} is not allowed to be null.',
|
|
139
|
-
'notInput': 'Please enter {name}.',
|
|
140
|
-
'fk': 'The value of {name} does not exist in the table.',
|
|
141
|
-
'idNotExist': 'The specified ID({id}) does not exist in the table.',
|
|
142
|
-
'find': 'The specified data does not exist in the table. ({pks})'
|
|
143
|
-
};
|
|
144
|
-
this.errorMessageJapan = {
|
|
145
|
-
'string': '{name}はstringかnumberで入力してください。',
|
|
146
|
-
'string[]': '{name}はstringかnumberの配列で入力してください。',
|
|
147
|
-
'uuid': '{name}はuuidで入力してください。',
|
|
148
|
-
'uuid[]': '{name}はuuidの配列で入力してください。',
|
|
149
|
-
'integer': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
150
|
-
'integer[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
151
|
-
'real': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
152
|
-
'real[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
153
|
-
'bool': '{name}はbool型、"true"、"false"、0、または1で入力してください。',
|
|
154
|
-
'bool[]': '{name}はbool型、"true"、"false"、0、または1の配列で入力してください。',
|
|
155
|
-
'date': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型で入力してください。',
|
|
156
|
-
'date[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
157
|
-
'time': '{name}は"hh:mi"形式または"hh:mi:ss"形式で入力してください。',
|
|
158
|
-
'time[]': '{name}は"hh:mi"形式または"hh:mi:ss"形式の配列で入力してください。',
|
|
159
|
-
'timestamp': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型で入力してください。',
|
|
160
|
-
'timestamp[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
161
|
-
'json': '{name}はObject形またはJSON文字列で入力してください。',
|
|
162
|
-
'json[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
163
|
-
'jsonb': '{name}はObject形またはJSON文字列で入力してください。',
|
|
164
|
-
'jsonb[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
165
|
-
'length': '{name}は{length}文字以内で入力してください。',
|
|
166
|
-
'null': '{name}はnullを許可されていません。',
|
|
167
|
-
'notInput': '{name}を入力してください。',
|
|
168
|
-
'fk': '{name}の値がテーブルに存在しません。',
|
|
169
|
-
'idNotExist': '指定されたID({id})はテーブルに存在しません。',
|
|
170
|
-
'find': '指定されたデータはテーブルに存在しません。({pks})'
|
|
171
|
-
};
|
|
172
|
-
this.errorMessages = process.env.TZ === 'Asia/Tokyo' ? this.errorMessageJapan : this.errorMessageEnglish;
|
|
117
|
+
this.errorMessages = process.env.TZ === 'Asia/Tokyo' ? MessageUtil_1.default.optionErrorMessageJapan : MessageUtil_1.default.optionErrorMessageEnglish;
|
|
173
118
|
this.client = client;
|
|
174
119
|
if (tableAlias !== undefined && tableAlias.trim() !== '') {
|
|
175
120
|
this.tableAlias = tableAlias;
|
|
176
121
|
}
|
|
177
122
|
}
|
|
178
|
-
|
|
179
|
-
return __awaiter(this, arguments, void 0, function* (
|
|
180
|
-
ValidateValueUtil_1.default.validateId(this.Columns, id);
|
|
123
|
+
find(pkOrId_1) {
|
|
124
|
+
return __awaiter(this, arguments, void 0, function* (pkOrId, selectColumns = "*", selectExpressions = null, keyFormat = 'snake') {
|
|
181
125
|
let selects = [];
|
|
182
126
|
if (selectColumns == "*") {
|
|
183
127
|
for (const key of Object.keys(this.Columns)) {
|
|
@@ -194,32 +138,16 @@ class TableModel {
|
|
|
194
138
|
selects.push(`${expression.expression} as "${expression.alias}"`);
|
|
195
139
|
}
|
|
196
140
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
find(pk_1) {
|
|
203
|
-
return __awaiter(this, arguments, void 0, function* (pk, selectColumns = "*", selectExpressions = null, keyFormat = 'snake') {
|
|
204
|
-
let selects = [];
|
|
205
|
-
if (selectColumns == "*") {
|
|
206
|
-
for (const key of Object.keys(this.Columns)) {
|
|
207
|
-
selects.push(SelectExpression_1.default.create({ model: this, name: key }, null, null, keyFormat));
|
|
208
|
-
}
|
|
141
|
+
let query;
|
|
142
|
+
if (typeof pkOrId === 'string' || typeof pkOrId === 'number' || typeof pkOrId === 'boolean') {
|
|
143
|
+
ValidateValueUtil_1.default.validateId(this.Columns, pkOrId);
|
|
144
|
+
query = WhereExpression_1.default.createConditionPk(this, { id: pkOrId });
|
|
209
145
|
}
|
|
210
|
-
else
|
|
211
|
-
|
|
212
|
-
selects.push(SelectExpression_1.default.create({ model: this, name: key }, null, null, keyFormat));
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (selectExpressions != null) {
|
|
216
|
-
for (const expression of selectExpressions) {
|
|
217
|
-
selects.push(`${expression.expression} as "${expression.alias}"`);
|
|
218
|
-
}
|
|
146
|
+
else {
|
|
147
|
+
query = WhereExpression_1.default.createConditionPk(this, pkOrId);
|
|
219
148
|
}
|
|
220
|
-
const {
|
|
221
|
-
|
|
222
|
-
let datas = yield this.executeQuery(sql, vars);
|
|
149
|
+
const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${query.expression}`;
|
|
150
|
+
let datas = yield this.executeQuery(sql, query.vars);
|
|
223
151
|
return datas.rowCount == 0 ? null : datas.rows[0];
|
|
224
152
|
});
|
|
225
153
|
}
|
|
@@ -395,7 +323,7 @@ class TableModel {
|
|
|
395
323
|
return { datas: data.rows, count: Number(countData.rows[0].count), lastPage: Math.ceil(Number(countData.rows[0].count) / this.PageCount) };
|
|
396
324
|
});
|
|
397
325
|
}
|
|
398
|
-
throwException(code, type, columnName,
|
|
326
|
+
throwException(code, type, columnName, value) {
|
|
399
327
|
var _a;
|
|
400
328
|
const column = this.getColumn(columnName);
|
|
401
329
|
let message = this.errorMessages[type];
|
|
@@ -447,6 +375,16 @@ class TableModel {
|
|
|
447
375
|
}
|
|
448
376
|
// 外部キー制約チェック
|
|
449
377
|
if (isInsert) {
|
|
378
|
+
for (const key in this.Columns) {
|
|
379
|
+
const column = this.getColumn(key);
|
|
380
|
+
const name = (column.alias === undefined || column.alias === '') ? key : column.alias;
|
|
381
|
+
if (options[key] === undefined || options[key] === null) {
|
|
382
|
+
// Null許容されていないカラムにNULLを入れようとしているか?
|
|
383
|
+
if (column.attribute === "primary" || column.attribute === "noDefault") {
|
|
384
|
+
this.throwException("005", "notInput", key, options[key]);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
450
388
|
for (const ref of this.References) {
|
|
451
389
|
const refValues = ref.columns.map(col => options[col.target]);
|
|
452
390
|
// 全ての値がnullの場合はスキップ
|
|
@@ -456,49 +394,22 @@ class TableModel {
|
|
|
456
394
|
// 一部の値がnullの場合はエラー
|
|
457
395
|
if (refValues.some(value => value === null || value === undefined)) {
|
|
458
396
|
const name = ref.columns.map(col => { var _a; return (_a = this.getColumn(col.target).alias) !== null && _a !== void 0 ? _a : this.getColumn(col.target).columnName; }).join(',');
|
|
459
|
-
throw new Exception_1.UnprocessableException("
|
|
397
|
+
throw new Exception_1.UnprocessableException("006", this.errorMessages.null.replace('{name}', name));
|
|
460
398
|
}
|
|
461
399
|
let refIndex = 1;
|
|
462
400
|
const sql = `SELECT COUNT(*) as count FROM ${ref.table} WHERE ${ref.columns.map(col => `${col.ref} = $${refIndex++}`).join(" AND ")}`;
|
|
463
401
|
const datas = yield this.clientQuery(sql, refValues);
|
|
464
402
|
if (datas.rows[0].count == "0") {
|
|
465
403
|
const name = ref.columns.map(col => { var _a; return (_a = this.getColumn(col.target).alias) !== null && _a !== void 0 ? _a : this.getColumn(col.target).columnName; }).join(',');
|
|
466
|
-
throw new Exception_1.DbConflictException("
|
|
404
|
+
throw new Exception_1.DbConflictException("007", this.errorMessages.fk.replace('{name}', name));
|
|
467
405
|
}
|
|
468
406
|
}
|
|
469
407
|
}
|
|
470
408
|
});
|
|
471
409
|
}
|
|
472
|
-
|
|
473
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
474
|
-
for (const key in this.Columns) {
|
|
475
|
-
const column = this.getColumn(key);
|
|
476
|
-
const name = (column.alias === undefined || column.alias === '') ? key : column.alias;
|
|
477
|
-
if (options[key] === undefined || options[key] === null) {
|
|
478
|
-
// Null許容されていないカラムにNULLを入れようとしているか?
|
|
479
|
-
if (column.attribute === "primary" || column.attribute === "noDefault") {
|
|
480
|
-
this.throwException("101", "notInput", key, options[key]);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
validateUpdate(options) {
|
|
487
|
-
return __awaiter(this, void 0, void 0, function* () { });
|
|
488
|
-
}
|
|
489
|
-
validateUpdateId(id, options) {
|
|
490
|
-
return __awaiter(this, void 0, void 0, function* () { });
|
|
491
|
-
}
|
|
492
|
-
validateDelete() {
|
|
493
|
-
return __awaiter(this, void 0, void 0, function* () { });
|
|
494
|
-
}
|
|
495
|
-
validateDeleteId(id) {
|
|
496
|
-
return __awaiter(this, void 0, void 0, function* () { });
|
|
497
|
-
}
|
|
498
|
-
executeInsert(options) {
|
|
410
|
+
insert(options) {
|
|
499
411
|
return __awaiter(this, void 0, void 0, function* () {
|
|
500
412
|
yield this.validateOptions(options, true);
|
|
501
|
-
yield this.validateInsert(options);
|
|
502
413
|
const columns = [];
|
|
503
414
|
const vars = [];
|
|
504
415
|
for (const [key, value] of Object.entries(options)) {
|
|
@@ -513,10 +424,47 @@ class TableModel {
|
|
|
513
424
|
yield this.executeQuery(sql, vars);
|
|
514
425
|
});
|
|
515
426
|
}
|
|
427
|
+
update(pkOrId, options) {
|
|
428
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
429
|
+
var _a;
|
|
430
|
+
yield this.validateOptions(options, false);
|
|
431
|
+
const updateSetQuery = UpdateExpression_1.default.createUpdateSet(this, options);
|
|
432
|
+
let whereQuery;
|
|
433
|
+
if (typeof pkOrId === 'string' || typeof pkOrId === 'number' || typeof pkOrId === 'boolean') {
|
|
434
|
+
ValidateValueUtil_1.default.validateId(this.Columns, pkOrId);
|
|
435
|
+
whereQuery = WhereExpression_1.default.createConditionPk(this, { id: pkOrId }, updateSetQuery.vars);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
whereQuery = WhereExpression_1.default.createConditionPk(this, pkOrId, updateSetQuery.vars);
|
|
439
|
+
}
|
|
440
|
+
const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
|
|
441
|
+
const data = yield this.executeQuery(sql, whereQuery.vars);
|
|
442
|
+
if (data.rowCount !== 1) {
|
|
443
|
+
throw new Exception_1.UnprocessableException("201", this.errorMessages.find.replace('{pks}', ((_a = whereQuery.vars) !== null && _a !== void 0 ? _a : []).join(',')));
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
delete(pkOrId) {
|
|
448
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
449
|
+
var _a;
|
|
450
|
+
let whereQuery;
|
|
451
|
+
if (typeof pkOrId === 'string' || typeof pkOrId === 'number' || typeof pkOrId === 'boolean') {
|
|
452
|
+
ValidateValueUtil_1.default.validateId(this.Columns, pkOrId);
|
|
453
|
+
whereQuery = WhereExpression_1.default.createConditionPk(this, { id: pkOrId });
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
whereQuery = WhereExpression_1.default.createConditionPk(this, pkOrId);
|
|
457
|
+
}
|
|
458
|
+
const sql = `DELETE FROM ${this.TableName} WHERE ${whereQuery.expression}`;
|
|
459
|
+
const data = yield this.executeQuery(sql, whereQuery.vars);
|
|
460
|
+
if (data.rowCount !== 1) {
|
|
461
|
+
throw new Exception_1.UnprocessableException("301", this.errorMessages.find.replace('{pks}', ((_a = whereQuery.vars) !== null && _a !== void 0 ? _a : []).join(',')));
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
}
|
|
516
465
|
executeUpdate(options) {
|
|
517
466
|
return __awaiter(this, void 0, void 0, function* () {
|
|
518
467
|
yield this.validateOptions(options, false);
|
|
519
|
-
yield this.validateUpdate(options);
|
|
520
468
|
const updateExpressions = [];
|
|
521
469
|
for (const [key, value] of Object.entries(options)) {
|
|
522
470
|
const column = this.getColumn(key);
|
|
@@ -544,40 +492,8 @@ class TableModel {
|
|
|
544
492
|
return data.rowCount;
|
|
545
493
|
});
|
|
546
494
|
}
|
|
547
|
-
executeUpdateId(id, options) {
|
|
548
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
549
|
-
var _a;
|
|
550
|
-
ValidateValueUtil_1.default.validateId(this.Columns, id);
|
|
551
|
-
yield this.validateOptions(options, false);
|
|
552
|
-
yield this.validateUpdateId(id, options);
|
|
553
|
-
yield this.validateUpdate(options);
|
|
554
|
-
const updateSetQuery = UpdateExpression_1.default.createUpdateSet(this, options);
|
|
555
|
-
const whereQuery = WhereExpression_1.default.createConditionPk(this, { id: id }, updateSetQuery.vars);
|
|
556
|
-
const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
|
|
557
|
-
const data = yield this.executeQuery(sql, whereQuery.vars);
|
|
558
|
-
if (data.rowCount !== 1) {
|
|
559
|
-
throw new Exception_1.UnprocessableException("201", this.errorMessages.find.replace('{pks}', ((_a = whereQuery.vars) !== null && _a !== void 0 ? _a : []).join(',')));
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
executeUpdateByPk(pk, options) {
|
|
564
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
565
|
-
var _a;
|
|
566
|
-
yield this.validateOptions(options, false);
|
|
567
|
-
// await this.validateUpdateId(id, options);
|
|
568
|
-
yield this.validateUpdate(options);
|
|
569
|
-
const updateSetQuery = UpdateExpression_1.default.createUpdateSet(this, options);
|
|
570
|
-
const whereQuery = WhereExpression_1.default.createConditionPk(this, pk, updateSetQuery.vars);
|
|
571
|
-
const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
|
|
572
|
-
const data = yield this.executeQuery(sql, whereQuery.vars);
|
|
573
|
-
if (data.rowCount !== 1) {
|
|
574
|
-
throw new Exception_1.UnprocessableException("401", this.errorMessages.find.replace('{pks}', ((_a = whereQuery.vars) !== null && _a !== void 0 ? _a : []).join(',')));
|
|
575
|
-
}
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
495
|
executeDelete() {
|
|
579
496
|
return __awaiter(this, void 0, void 0, function* () {
|
|
580
|
-
this.validateDelete();
|
|
581
497
|
let sql = `DELETE FROM ${this.TableName} "${this.TableAlias}" `;
|
|
582
498
|
if (this.joinConditions.length > 0) {
|
|
583
499
|
const tables = [];
|
|
@@ -598,17 +514,6 @@ class TableModel {
|
|
|
598
514
|
return datas.rowCount;
|
|
599
515
|
});
|
|
600
516
|
}
|
|
601
|
-
executeDeleteId(id) {
|
|
602
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
603
|
-
ValidateValueUtil_1.default.validateId(this.Columns, id);
|
|
604
|
-
yield this.validateDeleteId(id);
|
|
605
|
-
let sql = `DELETE FROM ${this.TableName} WHERE id = $1`;
|
|
606
|
-
const datas = yield this.executeQuery(sql, [id]);
|
|
607
|
-
if (datas.rowCount !== 1) {
|
|
608
|
-
throw new Exception_1.UnprocessableException("301", this.errorMessages.idNotExist.replace('{id}', id));
|
|
609
|
-
}
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
517
|
executeQuery(param1, vars) {
|
|
613
518
|
return __awaiter(this, void 0, void 0, function* () {
|
|
614
519
|
// 初期化項目
|
|
@@ -1 +1,59 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class MessageUtil {
|
|
4
|
+
}
|
|
5
|
+
MessageUtil.optionErrorMessageEnglish = {
|
|
6
|
+
'string': '{name} should be entered as a string or number type.',
|
|
7
|
+
'string[]': '{name} should be entered as an array of string or number types.',
|
|
8
|
+
'uuid': '{name} should be entered as a UUID.',
|
|
9
|
+
'uuid[]': '{name} should be entered as an array of UUIDs.',
|
|
10
|
+
'integer': '{name} should be entered as a number.',
|
|
11
|
+
'integer[]': '{name} should be entered as an array of numbers.',
|
|
12
|
+
'real': '{name} should be entered as a number.',
|
|
13
|
+
'real[]': '{name} should be entered as an array of numbers.',
|
|
14
|
+
'bool': '{name} should be entered as a bool type, "true", "false", 0, or 1.',
|
|
15
|
+
'bool[]': '{name} should be entered as an array of bool types, "true", "false", 0, or 1.',
|
|
16
|
+
'date': '{name} should be entered in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as a Date type.',
|
|
17
|
+
'date[]': '{name} should be entered as an array of dates in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as Date types.',
|
|
18
|
+
'time': '{name} should be entered in "hh:mi" format or "hh:mi:ss" format.',
|
|
19
|
+
'time[]': '{name} should be entered as an array of times in "hh:mi" format or "hh:mi:ss" format.',
|
|
20
|
+
'timestamp': '{name} should be entered in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as a Date type.',
|
|
21
|
+
'timestamp[]': '{name} should be entered as an array of timestamps in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as Date types.',
|
|
22
|
+
'json': '{name} should be entered as an Object or JSON string.',
|
|
23
|
+
'json[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
24
|
+
'jsonb': '{name} should be entered as an Object or JSON string.',
|
|
25
|
+
'jsonb[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
26
|
+
'length': '{name} should be entered within {length} characters.',
|
|
27
|
+
'null': '{name} is not allowed to be null.',
|
|
28
|
+
'notInput': 'Please enter {name}.',
|
|
29
|
+
'fk': 'The value of {name} does not exist in the table.',
|
|
30
|
+
'find': 'The specified data does not exist in the table. ({pks})'
|
|
31
|
+
};
|
|
32
|
+
MessageUtil.optionErrorMessageJapan = {
|
|
33
|
+
'string': '{name}はstringかnumberで入力してください。',
|
|
34
|
+
'string[]': '{name}はstringかnumberの配列で入力してください。',
|
|
35
|
+
'uuid': '{name}はuuidで入力してください。',
|
|
36
|
+
'uuid[]': '{name}はuuidの配列で入力してください。',
|
|
37
|
+
'integer': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
38
|
+
'integer[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
39
|
+
'real': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
40
|
+
'real[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
41
|
+
'bool': '{name}はbool型、"true"、"false"、0、または1で入力してください。',
|
|
42
|
+
'bool[]': '{name}はbool型、"true"、"false"、0、または1の配列で入力してください。',
|
|
43
|
+
'date': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型で入力してください。',
|
|
44
|
+
'date[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
45
|
+
'time': '{name}は"hh:mi"形式または"hh:mi:ss"形式で入力してください。',
|
|
46
|
+
'time[]': '{name}は"hh:mi"形式または"hh:mi:ss"形式の配列で入力してください。',
|
|
47
|
+
'timestamp': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型で入力してください。',
|
|
48
|
+
'timestamp[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
49
|
+
'json': '{name}はObject形またはJSON文字列で入力してください。',
|
|
50
|
+
'json[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
51
|
+
'jsonb': '{name}はObject形またはJSON文字列で入力してください。',
|
|
52
|
+
'jsonb[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
53
|
+
'length': '{name}は{length}文字以内で入力してください。',
|
|
54
|
+
'null': '{name}はnullを許可されていません。',
|
|
55
|
+
'notInput': '{name}を入力してください。',
|
|
56
|
+
'fk': '{name}の値がテーブルに存在しません。',
|
|
57
|
+
'find': '指定されたデータはテーブルに存在しません。({pks})'
|
|
58
|
+
};
|
|
59
|
+
exports.default = MessageUtil;
|
package/package.json
CHANGED
package/src/models/TableModel.ts
CHANGED
|
@@ -7,6 +7,7 @@ import ValidateClient from './ValidateClient';
|
|
|
7
7
|
import { DbConflictException, UnprocessableException } from '../exceptions/Exception';
|
|
8
8
|
import ExpressionClient from './ExpressionClient';
|
|
9
9
|
import UpdateExpression from './SqlUtils/UpdateExpression';
|
|
10
|
+
import MessageUtil, { TOptionErrorMessage } from './Utils/MessageUtil';
|
|
10
11
|
|
|
11
12
|
export class TableModel {
|
|
12
13
|
|
|
@@ -138,41 +139,19 @@ export class TableModel {
|
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
public findId<T = {[key: string]: any}>(id: any, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null, keyFormat: TKeyFormat): Promise<T | null>;
|
|
142
|
-
public findId<T = {[key: string]: any}>(id: any, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null): Promise<T | null>;
|
|
143
|
-
public findId<T = {[key: string]: any}>(id: any, selectColumns: Array<string> | "*" | null): Promise<T | null>;
|
|
144
|
-
public findId<T = {[key: string]: any}>(id: any): Promise<T | null>;
|
|
145
|
-
public async findId<T = {[key: string]: any}>(id: any, selectColumns: Array<string> | "*" | null = "*", selectExpressions: Array<TSelectExpression> | null = null, keyFormat: TKeyFormat = 'snake'): Promise<T | null> {
|
|
146
|
-
ValidateValueUtil.validateId(this.Columns, id);
|
|
147
|
-
|
|
148
|
-
let selects: Array<string> = [];
|
|
149
|
-
if (selectColumns == "*") {
|
|
150
|
-
for (const key of Object.keys(this.Columns)) {
|
|
151
|
-
selects.push(SelectExpression.create({model: this, name: key}, null, null, keyFormat));
|
|
152
|
-
}
|
|
153
|
-
} else if (selectColumns != null) {
|
|
154
|
-
for (const key of selectColumns) {
|
|
155
|
-
selects.push(SelectExpression.create({model: this, name: key}, null, null, keyFormat));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (selectExpressions != null) {
|
|
160
|
-
for (const expression of selectExpressions) {
|
|
161
|
-
selects.push(`${expression.expression} as "${expression.alias}"`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE id = $1`;
|
|
166
|
-
let datas = await this.executeQuery(sql, [id]);
|
|
167
|
-
|
|
168
|
-
return datas.rowCount == 0 ? null : datas.rows[0] as T;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
public find<T = {[key: string]: any}>(pk: {[key: string]: any}, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null, keyFormat: TKeyFormat): Promise<T | null>;
|
|
172
|
-
public find<T = {[key: string]: any}>(pk: {[key: string]: any}, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null): Promise<T | null>;
|
|
173
|
-
public find<T = {[key: string]: any}>(pk: {[key: string]: any}, selectColumns: Array<string> | "*" | null): Promise<T | null>;
|
|
174
142
|
public find<T = {[key: string]: any}>(pk: {[key: string]: any}): Promise<T | null>;
|
|
175
|
-
public
|
|
143
|
+
public find<T = {[key: string]: any}>(id: string | number | boolean): Promise<T | null>;
|
|
144
|
+
public find<T = {[key: string]: any}>(pk: {[key: string]: any}, selectColumns: Array<string> | "*" | null): Promise<T | null>;
|
|
145
|
+
public find<T = {[key: string]: any}>(id: string | number | boolean, selectColumns: Array<string> | "*" | null): Promise<T | null>;
|
|
146
|
+
public find<T = {[key: string]: any}>(pk: {[key: string]: any}, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null): Promise<T | null>;
|
|
147
|
+
public find<T = {[key: string]: any}>(id: string | number | boolean, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null): Promise<T | null>;
|
|
148
|
+
public find<T = {[key: string]: any}>(pk: {[key: string]: any}, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null, keyFormat: TKeyFormat): Promise<T | null>;
|
|
149
|
+
public find<T = {[key: string]: any}>(id: string | number | boolean, selectColumns: Array<string> | "*" | null, selectExpressions: Array<TSelectExpression> | null, keyFormat: TKeyFormat): Promise<T | null>;
|
|
150
|
+
public async find<T = {[key: string]: any}>(
|
|
151
|
+
pkOrId: string | number | boolean | {[key: string]: any},
|
|
152
|
+
selectColumns: Array<string> | "*" | null = "*",
|
|
153
|
+
selectExpressions: Array<TSelectExpression> | null = null,
|
|
154
|
+
keyFormat: TKeyFormat = 'snake'): Promise<T | null> {
|
|
176
155
|
|
|
177
156
|
let selects: Array<string> = [];
|
|
178
157
|
if (selectColumns == "*") {
|
|
@@ -191,10 +170,16 @@ export class TableModel {
|
|
|
191
170
|
}
|
|
192
171
|
}
|
|
193
172
|
|
|
194
|
-
|
|
173
|
+
let query: TQuery;
|
|
174
|
+
if (typeof pkOrId === 'string' || typeof pkOrId === 'number' || typeof pkOrId === 'boolean') {
|
|
175
|
+
ValidateValueUtil.validateId(this.Columns, pkOrId);
|
|
176
|
+
query = WhereExpression.createConditionPk(this, {id: pkOrId});
|
|
177
|
+
} else {
|
|
178
|
+
query = WhereExpression.createConditionPk(this, pkOrId);
|
|
179
|
+
}
|
|
195
180
|
|
|
196
|
-
const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${expression}`;
|
|
197
|
-
let datas = await this.executeQuery(sql, vars);
|
|
181
|
+
const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${query.expression}`;
|
|
182
|
+
let datas = await this.executeQuery(sql, query.vars);
|
|
198
183
|
|
|
199
184
|
return datas.rowCount == 0 ? null : datas.rows[0] as T;
|
|
200
185
|
}
|
|
@@ -393,64 +378,10 @@ export class TableModel {
|
|
|
393
378
|
return { datas: data.rows as Array<T>, count: Number(countData.rows[0].count), lastPage: Math.ceil(Number(countData.rows[0].count) / this.PageCount)};
|
|
394
379
|
}
|
|
395
380
|
|
|
396
|
-
|
|
397
|
-
'
|
|
398
|
-
'string[]': '{name} should be entered as an array of string or number types.',
|
|
399
|
-
'uuid': '{name} should be entered as a UUID.',
|
|
400
|
-
'uuid[]': '{name} should be entered as an array of UUIDs.',
|
|
401
|
-
'integer': '{name} should be entered as a number.',
|
|
402
|
-
'integer[]': '{name} should be entered as an array of numbers.',
|
|
403
|
-
'real': '{name} should be entered as a number.',
|
|
404
|
-
'real[]': '{name} should be entered as an array of numbers.',
|
|
405
|
-
'bool': '{name} should be entered as a bool type, "true", "false", 0, or 1.',
|
|
406
|
-
'bool[]': '{name} should be entered as an array of bool types, "true", "false", 0, or 1.',
|
|
407
|
-
'date': '{name} should be entered in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as a Date type.',
|
|
408
|
-
'date[]': '{name} should be entered as an array of dates in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as Date types.',
|
|
409
|
-
'time': '{name} should be entered in "hh:mi" format or "hh:mi:ss" format.',
|
|
410
|
-
'time[]': '{name} should be entered as an array of times in "hh:mi" format or "hh:mi:ss" format.',
|
|
411
|
-
'timestamp': '{name} should be entered in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as a Date type.',
|
|
412
|
-
'timestamp[]': '{name} should be entered as an array of timestamps in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as Date types.',
|
|
413
|
-
'json': '{name} should be entered as an Object or JSON string.',
|
|
414
|
-
'json[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
415
|
-
'jsonb': '{name} should be entered as an Object or JSON string.',
|
|
416
|
-
'jsonb[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
417
|
-
'length': '{name} should be entered within {length} characters.',
|
|
418
|
-
'null': '{name} is not allowed to be null.',
|
|
419
|
-
'notInput': 'Please enter {name}.',
|
|
420
|
-
'fk': 'The value of {name} does not exist in the table.',
|
|
421
|
-
'idNotExist': 'The specified ID({id}) does not exist in the table.',
|
|
422
|
-
'find': 'The specified data does not exist in the table. ({pks})'
|
|
423
|
-
}
|
|
424
|
-
private readonly errorMessageJapan: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist' | 'find', string> = {
|
|
425
|
-
'string': '{name}はstringかnumberで入力してください。',
|
|
426
|
-
'string[]': '{name}はstringかnumberの配列で入力してください。',
|
|
427
|
-
'uuid': '{name}はuuidで入力してください。',
|
|
428
|
-
'uuid[]': '{name}はuuidの配列で入力してください。',
|
|
429
|
-
'integer': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
430
|
-
'integer[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
431
|
-
'real': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
432
|
-
'real[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
433
|
-
'bool': '{name}はbool型、"true"、"false"、0、または1で入力してください。',
|
|
434
|
-
'bool[]': '{name}はbool型、"true"、"false"、0、または1の配列で入力してください。',
|
|
435
|
-
'date': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型で入力してください。',
|
|
436
|
-
'date[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
437
|
-
'time': '{name}は"hh:mi"形式または"hh:mi:ss"形式で入力してください。',
|
|
438
|
-
'time[]': '{name}は"hh:mi"形式または"hh:mi:ss"形式の配列で入力してください。',
|
|
439
|
-
'timestamp': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型で入力してください。',
|
|
440
|
-
'timestamp[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
441
|
-
'json': '{name}はObject形またはJSON文字列で入力してください。',
|
|
442
|
-
'json[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
443
|
-
'jsonb': '{name}はObject形またはJSON文字列で入力してください。',
|
|
444
|
-
'jsonb[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
445
|
-
'length': '{name}は{length}文字以内で入力してください。',
|
|
446
|
-
'null': '{name}はnullを許可されていません。',
|
|
447
|
-
'notInput': '{name}を入力してください。',
|
|
448
|
-
'fk': '{name}の値がテーブルに存在しません。',
|
|
449
|
-
'idNotExist': '指定されたID({id})はテーブルに存在しません。',
|
|
450
|
-
'find': '指定されたデータはテーブルに存在しません。({pks})'
|
|
451
|
-
}
|
|
381
|
+
protected readonly errorMessages: TOptionErrorMessage =
|
|
382
|
+
process.env.TZ === 'Asia/Tokyo' ? MessageUtil.optionErrorMessageJapan : MessageUtil.optionErrorMessageEnglish;
|
|
452
383
|
|
|
453
|
-
private throwException(code: string, type: TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk'
|
|
384
|
+
private throwException(code: string, type: TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk', columnName: string, value: any): never {
|
|
454
385
|
const column = this.getColumn(columnName);
|
|
455
386
|
|
|
456
387
|
let message = this.errorMessages[type];
|
|
@@ -464,9 +395,6 @@ export class TableModel {
|
|
|
464
395
|
throw new UnprocessableException(code, message);
|
|
465
396
|
}
|
|
466
397
|
|
|
467
|
-
protected readonly errorMessages: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist' | 'find', string> =
|
|
468
|
-
process.env.TZ === 'Asia/Tokyo' ? this.errorMessageJapan : this.errorMessageEnglish;
|
|
469
|
-
|
|
470
398
|
protected async validateOptions(options: {[key: string]: any}, isInsert: boolean): Promise<void> {
|
|
471
399
|
if (Object.keys(options).length === 0) {
|
|
472
400
|
throw new Error('At least one key-value pair is required in options.');
|
|
@@ -513,6 +441,17 @@ export class TableModel {
|
|
|
513
441
|
|
|
514
442
|
// 外部キー制約チェック
|
|
515
443
|
if (isInsert) {
|
|
444
|
+
for (const key in this.Columns) {
|
|
445
|
+
const column = this.getColumn(key);
|
|
446
|
+
const name = (column.alias === undefined || column.alias === '') ? key : column.alias;
|
|
447
|
+
if (options[key] === undefined || options[key] === null) {
|
|
448
|
+
// Null許容されていないカラムにNULLを入れようとしているか?
|
|
449
|
+
if (column.attribute === "primary" || column.attribute === "noDefault") {
|
|
450
|
+
this.throwException("005", "notInput", key, options[key]);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
516
455
|
for (const ref of this.References) {
|
|
517
456
|
const refValues = ref.columns.map(col => options[col.target]);
|
|
518
457
|
// 全ての値がnullの場合はスキップ
|
|
@@ -523,7 +462,7 @@ export class TableModel {
|
|
|
523
462
|
// 一部の値がnullの場合はエラー
|
|
524
463
|
if (refValues.some(value => value === null || value === undefined)) {
|
|
525
464
|
const name = ref.columns.map(col => this.getColumn(col.target).alias ?? this.getColumn(col.target).columnName).join(',');
|
|
526
|
-
throw new UnprocessableException("
|
|
465
|
+
throw new UnprocessableException("006", this.errorMessages.null.replace('{name}', name));
|
|
527
466
|
}
|
|
528
467
|
|
|
529
468
|
let refIndex = 1;
|
|
@@ -531,33 +470,14 @@ export class TableModel {
|
|
|
531
470
|
const datas = await this.clientQuery(sql, refValues);
|
|
532
471
|
if (datas.rows[0].count == "0") {
|
|
533
472
|
const name = ref.columns.map(col => this.getColumn(col.target).alias ?? this.getColumn(col.target).columnName).join(',');
|
|
534
|
-
throw new DbConflictException("
|
|
473
|
+
throw new DbConflictException("007", this.errorMessages.fk.replace('{name}', name));
|
|
535
474
|
}
|
|
536
475
|
}
|
|
537
476
|
}
|
|
538
477
|
}
|
|
539
478
|
|
|
540
|
-
|
|
541
|
-
for (const key in this.Columns) {
|
|
542
|
-
const column = this.getColumn(key);
|
|
543
|
-
const name = (column.alias === undefined || column.alias === '') ? key : column.alias;
|
|
544
|
-
if (options[key] === undefined || options[key] === null) {
|
|
545
|
-
// Null許容されていないカラムにNULLを入れようとしているか?
|
|
546
|
-
if (column.attribute === "primary" || column.attribute === "noDefault") {
|
|
547
|
-
this.throwException("101", "notInput", key, options[key]);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
protected async validateUpdate(options: {[key: string]: any}) : Promise<void> { }
|
|
554
|
-
protected async validateUpdateId(id: any, options: {[key: string]: any}) : Promise<void> { }
|
|
555
|
-
protected async validateDelete() : Promise<void> { }
|
|
556
|
-
protected async validateDeleteId(id: any) : Promise<void> { }
|
|
557
|
-
|
|
558
|
-
public async executeInsert(options: {[key: string]: any}) : Promise<void> {
|
|
479
|
+
public async insert(options: {[key: string]: any}) : Promise<void> {
|
|
559
480
|
await this.validateOptions(options, true);
|
|
560
|
-
await this.validateInsert(options);
|
|
561
481
|
|
|
562
482
|
const columns: Array<string> = [];
|
|
563
483
|
const vars: Array<any> = [];
|
|
@@ -576,9 +496,43 @@ export class TableModel {
|
|
|
576
496
|
await this.executeQuery(sql, vars);
|
|
577
497
|
}
|
|
578
498
|
|
|
499
|
+
public async update(pkOrId: string | number | boolean | {[key: string]: any}, options: {[key: string]: any}) : Promise<void> {
|
|
500
|
+
await this.validateOptions(options, false);
|
|
501
|
+
|
|
502
|
+
const updateSetQuery = UpdateExpression.createUpdateSet(this, options);
|
|
503
|
+
let whereQuery: TQuery;
|
|
504
|
+
if (typeof pkOrId === 'string' || typeof pkOrId === 'number' || typeof pkOrId === 'boolean') {
|
|
505
|
+
ValidateValueUtil.validateId(this.Columns, pkOrId);
|
|
506
|
+
whereQuery = WhereExpression.createConditionPk(this, {id: pkOrId}, updateSetQuery.vars);
|
|
507
|
+
} else {
|
|
508
|
+
whereQuery = WhereExpression.createConditionPk(this, pkOrId, updateSetQuery.vars);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
|
|
512
|
+
const data = await this.executeQuery(sql, whereQuery.vars);
|
|
513
|
+
if (data.rowCount !== 1) {
|
|
514
|
+
throw new UnprocessableException("201", this.errorMessages.find.replace('{pks}', (whereQuery.vars ?? []).join(',')));
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
public async delete(pkOrId: string | number | boolean | {[key: string]: any}) : Promise<void> {
|
|
519
|
+
let whereQuery: TQuery;
|
|
520
|
+
if (typeof pkOrId === 'string' || typeof pkOrId === 'number' || typeof pkOrId === 'boolean') {
|
|
521
|
+
ValidateValueUtil.validateId(this.Columns, pkOrId);
|
|
522
|
+
whereQuery = WhereExpression.createConditionPk(this, {id: pkOrId});
|
|
523
|
+
} else {
|
|
524
|
+
whereQuery = WhereExpression.createConditionPk(this, pkOrId);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const sql = `DELETE FROM ${this.TableName} WHERE ${whereQuery.expression}`;
|
|
528
|
+
const data = await this.executeQuery(sql, whereQuery.vars);
|
|
529
|
+
if (data.rowCount !== 1) {
|
|
530
|
+
throw new UnprocessableException("301", this.errorMessages.find.replace('{pks}', (whereQuery.vars ?? []).join(',')));
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
579
534
|
public async executeUpdate(options: {[key: string]: any}) : Promise<number> {
|
|
580
535
|
await this.validateOptions(options, false);
|
|
581
|
-
await this.validateUpdate(options);
|
|
582
536
|
|
|
583
537
|
const updateExpressions: Array<string> = [];
|
|
584
538
|
for (const [key, value] of Object.entries(options)) {
|
|
@@ -612,41 +566,7 @@ export class TableModel {
|
|
|
612
566
|
return data.rowCount;
|
|
613
567
|
}
|
|
614
568
|
|
|
615
|
-
public async executeUpdateId(id: any, options: {[key: string]: any}) : Promise<void> {
|
|
616
|
-
ValidateValueUtil.validateId(this.Columns, id);
|
|
617
|
-
await this.validateOptions(options, false);
|
|
618
|
-
await this.validateUpdateId(id, options);
|
|
619
|
-
await this.validateUpdate(options);
|
|
620
|
-
|
|
621
|
-
const updateSetQuery = UpdateExpression.createUpdateSet(this, options);
|
|
622
|
-
const whereQuery = WhereExpression.createConditionPk(this, {id: id}, updateSetQuery.vars);
|
|
623
|
-
|
|
624
|
-
const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
|
|
625
|
-
|
|
626
|
-
const data = await this.executeQuery(sql, whereQuery.vars);
|
|
627
|
-
if (data.rowCount !== 1) {
|
|
628
|
-
throw new UnprocessableException("201", this.errorMessages.find.replace('{pks}', (whereQuery.vars ?? []).join(',')));
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
public async executeUpdateByPk(pk: {[key: string]: any}, options: {[key: string]: any}) : Promise<void> {
|
|
633
|
-
await this.validateOptions(options, false);
|
|
634
|
-
// await this.validateUpdateId(id, options);
|
|
635
|
-
await this.validateUpdate(options);
|
|
636
|
-
|
|
637
|
-
const updateSetQuery = UpdateExpression.createUpdateSet(this, options);
|
|
638
|
-
const whereQuery = WhereExpression.createConditionPk(this, pk, updateSetQuery.vars);
|
|
639
|
-
|
|
640
|
-
const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
|
|
641
|
-
|
|
642
|
-
const data = await this.executeQuery(sql, whereQuery.vars);
|
|
643
|
-
if (data.rowCount !== 1) {
|
|
644
|
-
throw new UnprocessableException("401", this.errorMessages.find.replace('{pks}', (whereQuery.vars ?? []).join(',')));
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
|
|
648
569
|
public async executeDelete() : Promise<number> {
|
|
649
|
-
this.validateDelete();
|
|
650
570
|
let sql = `DELETE FROM ${this.TableName} "${this.TableAlias}" `;
|
|
651
571
|
|
|
652
572
|
if (this.joinConditions.length > 0) {
|
|
@@ -671,17 +591,6 @@ export class TableModel {
|
|
|
671
591
|
return datas.rowCount;
|
|
672
592
|
}
|
|
673
593
|
|
|
674
|
-
public async executeDeleteId(id: any) : Promise<void> {
|
|
675
|
-
ValidateValueUtil.validateId(this.Columns, id);
|
|
676
|
-
await this.validateDeleteId(id);
|
|
677
|
-
let sql = `DELETE FROM ${this.TableName} WHERE id = $1`;
|
|
678
|
-
|
|
679
|
-
const datas = await this.executeQuery(sql, [id]);
|
|
680
|
-
if (datas.rowCount !== 1) {
|
|
681
|
-
throw new UnprocessableException("301", this.errorMessages.idNotExist.replace('{id}', id));
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
|
|
685
594
|
protected executeQuery(param1: string, vars?: Array<any>) : Promise<any>;
|
|
686
595
|
protected executeQuery(param1: TQuery) : Promise<any>;
|
|
687
596
|
protected async executeQuery(param1: string | TQuery, vars?: Array<any>) : Promise<any> {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { TColumnArrayType, TColumnType } from "../Type"
|
|
2
|
+
|
|
3
|
+
export type TOptionErrorMessage = Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'find', string>;
|
|
4
|
+
|
|
5
|
+
export default class MessageUtil {
|
|
6
|
+
public static readonly optionErrorMessageEnglish: TOptionErrorMessage = {
|
|
7
|
+
'string': '{name} should be entered as a string or number type.',
|
|
8
|
+
'string[]': '{name} should be entered as an array of string or number types.',
|
|
9
|
+
'uuid': '{name} should be entered as a UUID.',
|
|
10
|
+
'uuid[]': '{name} should be entered as an array of UUIDs.',
|
|
11
|
+
'integer': '{name} should be entered as a number.',
|
|
12
|
+
'integer[]': '{name} should be entered as an array of numbers.',
|
|
13
|
+
'real': '{name} should be entered as a number.',
|
|
14
|
+
'real[]': '{name} should be entered as an array of numbers.',
|
|
15
|
+
'bool': '{name} should be entered as a bool type, "true", "false", 0, or 1.',
|
|
16
|
+
'bool[]': '{name} should be entered as an array of bool types, "true", "false", 0, or 1.',
|
|
17
|
+
'date': '{name} should be entered in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as a Date type.',
|
|
18
|
+
'date[]': '{name} should be entered as an array of dates in "YYYY-MM-DD" or "YYYY-MM-DD hh:mi:ss" format or as Date types.',
|
|
19
|
+
'time': '{name} should be entered in "hh:mi" format or "hh:mi:ss" format.',
|
|
20
|
+
'time[]': '{name} should be entered as an array of times in "hh:mi" format or "hh:mi:ss" format.',
|
|
21
|
+
'timestamp': '{name} should be entered in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as a Date type.',
|
|
22
|
+
'timestamp[]': '{name} should be entered as an array of timestamps in "YYYY-MM-DD" format, "YYYY-MM-DD hh:mi:ss" format, "YYYY-MM-DDThh:mi:ss" format, or as Date types.',
|
|
23
|
+
'json': '{name} should be entered as an Object or JSON string.',
|
|
24
|
+
'json[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
25
|
+
'jsonb': '{name} should be entered as an Object or JSON string.',
|
|
26
|
+
'jsonb[]': '{name} should be entered as an array of Objects or JSON strings.',
|
|
27
|
+
'length': '{name} should be entered within {length} characters.',
|
|
28
|
+
'null': '{name} is not allowed to be null.',
|
|
29
|
+
'notInput': 'Please enter {name}.',
|
|
30
|
+
'fk': 'The value of {name} does not exist in the table.',
|
|
31
|
+
'find': 'The specified data does not exist in the table. ({pks})'
|
|
32
|
+
}
|
|
33
|
+
public static readonly optionErrorMessageJapan: TOptionErrorMessage = {
|
|
34
|
+
'string': '{name}はstringかnumberで入力してください。',
|
|
35
|
+
'string[]': '{name}はstringかnumberの配列で入力してください。',
|
|
36
|
+
'uuid': '{name}はuuidで入力してください。',
|
|
37
|
+
'uuid[]': '{name}はuuidの配列で入力してください。',
|
|
38
|
+
'integer': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
39
|
+
'integer[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
40
|
+
'real': '{name}はnumberか半角数字のstring型で入力してください。',
|
|
41
|
+
'real[]': '{name}はnumberか半角数字のstring型の配列で入力してください。',
|
|
42
|
+
'bool': '{name}はbool型、"true"、"false"、0、または1で入力してください。',
|
|
43
|
+
'bool[]': '{name}はbool型、"true"、"false"、0、または1の配列で入力してください。',
|
|
44
|
+
'date': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型で入力してください。',
|
|
45
|
+
'date[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
46
|
+
'time': '{name}は"hh:mi"形式または"hh:mi:ss"形式で入力してください。',
|
|
47
|
+
'time[]': '{name}は"hh:mi"形式または"hh:mi:ss"形式の配列で入力してください。',
|
|
48
|
+
'timestamp': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型で入力してください。',
|
|
49
|
+
'timestamp[]': '{name}は"YYYY-MM-DD"形式、"YYYY-MM-DD hh:mi:ss"形式、"YYYY-MM-DDThh:mi:ss"形式、またはDate型の配列で入力してください。',
|
|
50
|
+
'json': '{name}はObject形またはJSON文字列で入力してください。',
|
|
51
|
+
'json[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
52
|
+
'jsonb': '{name}はObject形またはJSON文字列で入力してください。',
|
|
53
|
+
'jsonb[]': '{name}はObject形またはJSON文字列の配列で入力してください。',
|
|
54
|
+
'length': '{name}は{length}文字以内で入力してください。',
|
|
55
|
+
'null': '{name}はnullを許可されていません。',
|
|
56
|
+
'notInput': '{name}を入力してください。',
|
|
57
|
+
'fk': '{name}の値がテーブルに存在しません。',
|
|
58
|
+
'find': '指定されたデータはテーブルに存在しません。({pks})'
|
|
59
|
+
}
|
|
60
|
+
}
|