pg-mvc-service 1.0.26 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class UpdateExpression {
4
+ static createUpdateSet(model, options) {
5
+ const expressions = [];
6
+ const vars = [];
7
+ for (const [key, value] of Object.entries(options)) {
8
+ if (value === undefined) {
9
+ throw new Error(`The update option ${key} is undefined.`);
10
+ }
11
+ const column = model.getColumn(key);
12
+ if (column.attribute === 'primary') {
13
+ throw new Error(`The primary key ${model.TableName}.${key} cannot be changed.`);
14
+ }
15
+ vars.push(value);
16
+ expressions.push(`${key} = $${vars.length}`);
17
+ }
18
+ return {
19
+ expression: `UPDATE ${model.TableName} SET ${expressions.join(',')}`,
20
+ vars: vars
21
+ };
22
+ }
23
+ }
24
+ exports.default = UpdateExpression;
@@ -5,6 +5,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const ValidateValueUtil_1 = __importDefault(require("./ValidateValueUtil"));
7
7
  class WhereExpression {
8
+ static createConditionPk(model, pk, vars = null, isSetAlias = false) {
9
+ const conditions = [];
10
+ const newVars = vars === null ? [] : [...vars];
11
+ for (const [keyColumn, column] of Object.entries(model.Columns)) {
12
+ if (column.attribute !== 'primary') {
13
+ continue;
14
+ }
15
+ if (pk[keyColumn] === undefined || pk[keyColumn] === null) {
16
+ throw new Error(`No value is set for the primary key "${model.TableName}".${keyColumn}.`);
17
+ }
18
+ ValidateValueUtil_1.default.validateValue(column, pk[keyColumn]);
19
+ newVars.push(pk[keyColumn]);
20
+ conditions.push(`${isSetAlias ? `"${model.TableAlias}".` : ''}${keyColumn} = $${newVars.length}`);
21
+ }
22
+ return {
23
+ expression: conditions.join(' AND '),
24
+ vars: newVars
25
+ };
26
+ }
8
27
  /**
9
28
  * Helper method to create OR conditions
10
29
  * @param conditions Array of conditions that make up the OR condition
@@ -12,12 +31,12 @@ class WhereExpression {
12
31
  */
13
32
  static createCondition(conditions, model, varLength) {
14
33
  if (conditions.length === 0) {
15
- return { sql: '' };
34
+ return { expression: '' };
16
35
  }
17
36
  let logicalOperator = 'AND';
18
37
  if (conditions[0] === 'AND' || conditions[0] === 'OR') {
19
38
  if (conditions.length === 1) {
20
- return { sql: '' };
39
+ return { expression: '' };
21
40
  }
22
41
  logicalOperator = conditions[0];
23
42
  conditions.shift();
@@ -28,7 +47,7 @@ class WhereExpression {
28
47
  if (Array.isArray(condition)) {
29
48
  // If it's an array, it's a nested condition, so call this function recursively
30
49
  const query = this.createCondition(condition, model, varLength + vars.length);
31
- expression.push(query.sql);
50
+ expression.push(query.expression);
32
51
  if (query.vars !== undefined) {
33
52
  vars = [...vars, ...query.vars];
34
53
  }
@@ -41,20 +60,20 @@ class WhereExpression {
41
60
  }
42
61
  if (typeof condition.l === 'string') {
43
62
  const query = this.create({ model: model, name: condition.l }, condition.o, condition.r, varLength + vars.length);
44
- expression.push(query.sql);
63
+ expression.push(query.expression);
45
64
  if (query.vars !== undefined) {
46
65
  vars = [...vars, ...query.vars];
47
66
  }
48
67
  continue;
49
68
  }
50
69
  const query = this.create(condition.l, condition.o, condition.r, varLength + vars.length);
51
- expression.push(query.sql);
70
+ expression.push(query.expression);
52
71
  if (query.vars !== undefined) {
53
72
  vars = [...vars, ...query.vars];
54
73
  }
55
74
  }
56
75
  return {
57
- sql: `(${expression.filter(condition => condition !== null && condition !== void 0 ? condition : '' !== '').join(` ${logicalOperator} `)})`,
76
+ expression: `(${expression.filter(condition => condition !== null && condition !== void 0 ? condition : '' !== '').join(` ${logicalOperator} `)})`,
58
77
  vars: vars
59
78
  };
60
79
  }
@@ -93,12 +112,12 @@ class WhereExpression {
93
112
  }
94
113
  if (operator == "=") {
95
114
  return {
96
- sql: `${leftColumn.expression} is null`
115
+ expression: `${leftColumn.expression} is null`
97
116
  };
98
117
  }
99
118
  else if (operator == "!=") {
100
119
  return {
101
- sql: `${leftColumn.expression} is not null`
120
+ expression: `${leftColumn.expression} is not null`
102
121
  };
103
122
  }
104
123
  else {
@@ -120,14 +139,14 @@ class WhereExpression {
120
139
  }
121
140
  if (right.length == 0) {
122
141
  // 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
123
- return { sql: '' };
142
+ return { expression: '' };
124
143
  }
125
144
  // Validate values
126
145
  for (const value of right) {
127
146
  ValidateValueUtil_1.default.validateValue(leftColumn, value);
128
147
  }
129
148
  return {
130
- sql: `${leftColumn.expression} ${operator === 'in' ? '=' : '!='} ANY($${varLength})`,
149
+ expression: `${leftColumn.expression} ${operator === 'in' ? '=' : '!='} ANY($${varLength})`,
131
150
  vars: [right]
132
151
  };
133
152
  }
@@ -145,16 +164,16 @@ class WhereExpression {
145
164
  case 'like':
146
165
  case 'ilike':
147
166
  return {
148
- sql: `${leftColumn.expression} ${operator} '%' || ${rightColumn.expression} || '%'`
167
+ expression: `${leftColumn.expression} ${operator} '%' || ${rightColumn.expression} || '%'`
149
168
  };
150
169
  case 'h2f_like': // half to full like
151
170
  case 'h2f_ilike': // half to full ilike
152
171
  return {
153
- sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`'%' || ${rightColumn.expression} || '%'`)}`
172
+ expression: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`'%' || ${rightColumn.expression} || '%'`)}`
154
173
  };
155
174
  }
156
175
  return {
157
- sql: `${leftColumn.expression} ${operator} ${rightColumn.expression}`
176
+ expression: `${leftColumn.expression} ${operator} ${rightColumn.expression}`
158
177
  };
159
178
  }
160
179
  ValidateValueUtil_1.default.validateValue(leftColumn, right);
@@ -163,18 +182,18 @@ class WhereExpression {
163
182
  case 'like':
164
183
  case 'ilike':
165
184
  return {
166
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
185
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
167
186
  vars: [`%${right}%`]
168
187
  };
169
188
  case 'h2f_like': // half to full like
170
189
  case 'h2f_ilike': // half to full ilike
171
190
  return {
172
- sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`$${varLength}`)}`,
191
+ expression: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`$${varLength}`)}`,
173
192
  vars: [`%${right}%`]
174
193
  };
175
194
  }
176
195
  return {
177
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
196
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
178
197
  vars: [right]
179
198
  };
180
199
  }
@@ -199,12 +218,12 @@ class WhereExpression {
199
218
  case '=':
200
219
  // バリデーションチェックをする
201
220
  return {
202
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
221
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
203
222
  vars: [right]
204
223
  };
205
224
  }
206
225
  return {
207
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
226
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
208
227
  vars: [right]
209
228
  };
210
229
  }
@@ -19,6 +19,7 @@ const WhereExpression_1 = __importDefault(require("./SqlUtils/WhereExpression"))
19
19
  const ValidateClient_1 = __importDefault(require("./ValidateClient"));
20
20
  const Exception_1 = require("../exceptions/Exception");
21
21
  const ExpressionClient_1 = __importDefault(require("./ExpressionClient"));
22
+ const UpdateExpression_1 = __importDefault(require("./SqlUtils/UpdateExpression"));
22
23
  class TableModel {
23
24
  get DbName() { return this.dbName; }
24
25
  get TableName() {
@@ -61,7 +62,7 @@ class TableModel {
61
62
  sql += join.type === 'left' ? ' LEFT OUTER JOIN' : ' INNER JOIN';
62
63
  sql += ` ${join.model.TableName} as "${join.model.TableAlias}" ON `;
63
64
  const query = WhereExpression_1.default.createCondition(join.conditions, this, this.vars.length + 1);
64
- sql += query.sql;
65
+ sql += query.expression;
65
66
  if (query.vars !== undefined) {
66
67
  this.vars = [...this.vars, ...query.vars];
67
68
  }
@@ -138,6 +139,7 @@ class TableModel {
138
139
  'notInput': 'Please enter {name}.',
139
140
  'fk': 'The value of {name} does not exist in the table.',
140
141
  'idNotExist': 'The specified ID({id}) does not exist in the table.',
142
+ 'find': 'The specified data does not exist in the table. ({pks})'
141
143
  };
142
144
  this.errorMessageJapan = {
143
145
  'string': '{name}はstringかnumberで入力してください。',
@@ -165,6 +167,7 @@ class TableModel {
165
167
  'notInput': '{name}を入力してください。',
166
168
  'fk': '{name}の値がテーブルに存在しません。',
167
169
  'idNotExist': '指定されたID({id})はテーブルに存在しません。',
170
+ 'find': '指定されたデータはテーブルに存在しません。({pks})'
168
171
  };
169
172
  this.errorMessages = process.env.TZ === 'Asia/Tokyo' ? this.errorMessageJapan : this.errorMessageEnglish;
170
173
  this.client = client;
@@ -214,20 +217,8 @@ class TableModel {
214
217
  selects.push(`${expression.expression} as "${expression.alias}"`);
215
218
  }
216
219
  }
217
- const conditions = [];
218
- const vars = [];
219
- for (const [keyColumn, column] of Object.entries(this.Columns)) {
220
- if (column.attribute !== 'primary') {
221
- continue;
222
- }
223
- if (pk[keyColumn] === undefined || pk[keyColumn] === null) {
224
- throw new Error(`No value is set for the primary key "${this.TableName}".${keyColumn}. Please set it in the first argument.`);
225
- }
226
- ValidateValueUtil_1.default.validateValue(column, pk[keyColumn]);
227
- vars.push(pk[keyColumn]);
228
- conditions.push(`${keyColumn} = $${vars.length}`);
229
- }
230
- const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${conditions.join(' AND ')}`;
220
+ const { expression, vars } = WhereExpression_1.default.createConditionPk(this, pk);
221
+ const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${expression}`;
231
222
  let datas = yield this.executeQuery(sql, vars);
232
223
  return datas.rowCount == 0 ? null : datas.rows[0];
233
224
  });
@@ -299,7 +290,7 @@ class TableModel {
299
290
  }
300
291
  else {
301
292
  const query = WhereExpression_1.default.create({ model: this, name: left }, operator, right, this.vars.length + 1);
302
- this.whereExpressions.push(query.sql);
293
+ this.whereExpressions.push(query.expression);
303
294
  if (query.vars !== undefined) {
304
295
  this.vars = [...this.vars, ...query.vars];
305
296
  }
@@ -312,7 +303,7 @@ class TableModel {
312
303
  }
313
304
  else {
314
305
  const query = WhereExpression_1.default.create(left, operator, right, this.vars.length + 1);
315
- this.whereExpressions.push(query.sql);
306
+ this.whereExpressions.push(query.expression);
316
307
  if (query.vars !== undefined) {
317
308
  this.vars = [...this.vars, ...query.vars];
318
309
  }
@@ -321,7 +312,7 @@ class TableModel {
321
312
  }
322
313
  if (Array.isArray(left)) {
323
314
  const query = WhereExpression_1.default.createCondition(left, this, this.vars.length + 1);
324
- this.whereExpressions.push(query.sql);
315
+ this.whereExpressions.push(query.expression);
325
316
  if (query.vars !== undefined) {
326
317
  this.vars = [...this.vars, ...query.vars];
327
318
  }
@@ -539,7 +530,7 @@ class TableModel {
539
530
  for (const join of this.joinConditions) {
540
531
  tables.push(`${join.model.TableName} as "${join.model.TableAlias}"`);
541
532
  const query = WhereExpression_1.default.createCondition(join.conditions, this, this.vars.length);
542
- this.whereExpressions.push(query.sql);
533
+ this.whereExpressions.push(query.expression);
543
534
  if (query.vars !== undefined) {
544
535
  this.vars = [...this.vars, ...query.vars];
545
536
  }
@@ -555,28 +546,32 @@ class TableModel {
555
546
  }
556
547
  executeUpdateId(id, options) {
557
548
  return __awaiter(this, void 0, void 0, function* () {
549
+ var _a;
558
550
  ValidateValueUtil_1.default.validateId(this.Columns, id);
559
551
  yield this.validateOptions(options, false);
560
552
  yield this.validateUpdateId(id, options);
561
553
  yield this.validateUpdate(options);
562
- const updateExpressions = [];
563
- const vars = [];
564
- for (const [key, value] of Object.entries(options)) {
565
- if (value === undefined) {
566
- throw new Error(`The update option ${key} is undefined.`);
567
- }
568
- const column = this.getColumn(key);
569
- if (column.attribute === 'primary') {
570
- throw new Error(`The primary key ${this.TableName}.${key} cannot be changed.`);
571
- }
572
- vars.push(value);
573
- updateExpressions.push(`${key} = $${vars.length}`);
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(',')));
574
560
  }
575
- vars.push(id);
576
- const sql = `UPDATE ${this.TableName} SET ${updateExpressions.join(',')} WHERE id = $${vars.length}`;
577
- const data = yield this.executeQuery(sql, vars);
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);
578
573
  if (data.rowCount !== 1) {
579
- throw new Exception_1.UnprocessableException("201", this.errorMessages.idNotExist.replace('{id}', id));
574
+ throw new Exception_1.UnprocessableException("401", this.errorMessages.find.replace('{pks}', ((_a = whereQuery.vars) !== null && _a !== void 0 ? _a : []).join(',')));
580
575
  }
581
576
  });
582
577
  }
@@ -589,7 +584,7 @@ class TableModel {
589
584
  for (const join of this.joinConditions) {
590
585
  tables.push(`${join.model.TableName} as "${join.model.TableAlias}"`);
591
586
  const query = WhereExpression_1.default.createCondition(join.conditions, this, this.vars.length);
592
- this.whereExpressions.push(query.sql);
587
+ this.whereExpressions.push(query.expression);
593
588
  if (query.vars !== undefined) {
594
589
  this.vars = [...this.vars, ...query.vars];
595
590
  }
@@ -632,7 +627,7 @@ class TableModel {
632
627
  sql = param1;
633
628
  }
634
629
  else {
635
- sql = param1.sql;
630
+ sql = param1.expression;
636
631
  vars = param1.vars;
637
632
  }
638
633
  return yield this.clientQuery(sql, vars);
@@ -0,0 +1 @@
1
+ "use strict";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pg-mvc-service",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/n-daira/npm-pack_mvc-service#readme",
6
6
  "bugs": {
@@ -0,0 +1,29 @@
1
+ import { TableModel } from "../TableModel";
2
+ import { TQuery } from "../Type";
3
+
4
+ export default class UpdateExpression {
5
+
6
+ static createUpdateSet(model: TableModel, options: {[key: string]: any}): TQuery {
7
+ const expressions = [];
8
+ const vars = [];
9
+ for (const [key, value] of Object.entries(options)) {
10
+ if (value === undefined) {
11
+ throw new Error(`The update option ${key} is undefined.`);
12
+ }
13
+
14
+ const column = model.getColumn(key);
15
+ if (column.attribute === 'primary') {
16
+ throw new Error(`The primary key ${model.TableName}.${key} cannot be changed.`);
17
+ }
18
+
19
+ vars.push(value);
20
+ expressions.push(`${key} = $${vars.length}`);
21
+ }
22
+
23
+ return {
24
+ expression: `UPDATE ${model.TableName} SET ${expressions.join(',')}`,
25
+ vars: vars
26
+ }
27
+ }
28
+
29
+ }
@@ -4,6 +4,30 @@ import ValidateValueUtil from "./ValidateValueUtil";
4
4
 
5
5
  export default class WhereExpression {
6
6
 
7
+ public static createConditionPk(model: TableModel, pk: {[key: string]: any}, vars: Array<any> | null = null, isSetAlias: boolean = false): TQuery {
8
+ const conditions = [];
9
+ const newVars = vars === null ? [] : [...vars];
10
+
11
+ for (const [keyColumn, column] of Object.entries(model.Columns)) {
12
+ if (column.attribute !== 'primary') {
13
+ continue;
14
+ }
15
+
16
+ if (pk[keyColumn] === undefined || pk[keyColumn] === null) {
17
+ throw new Error(`No value is set for the primary key "${model.TableName}".${keyColumn}.`);
18
+ }
19
+
20
+ ValidateValueUtil.validateValue(column, pk[keyColumn]);
21
+ newVars.push(pk[keyColumn]);
22
+ conditions.push(`${isSetAlias ? `"${model.TableAlias}".` : ''}${keyColumn} = $${newVars.length}`);
23
+ }
24
+
25
+ return {
26
+ expression: conditions.join(' AND '),
27
+ vars: newVars
28
+ }
29
+ }
30
+
7
31
  /**
8
32
  * Helper method to create OR conditions
9
33
  * @param conditions Array of conditions that make up the OR condition
@@ -12,13 +36,13 @@ export default class WhereExpression {
12
36
  public static createCondition(conditions: Array<TNestedCondition>, model: TableModel, varLength: number): TQuery {
13
37
 
14
38
  if (conditions.length === 0) {
15
- return { sql: '' };
39
+ return { expression: '' };
16
40
  }
17
41
 
18
42
  let logicalOperator = 'AND';
19
43
  if (conditions[0] === 'AND' || conditions[0] === 'OR') {
20
44
  if (conditions.length === 1) {
21
- return { sql: '' };
45
+ return { expression: '' };
22
46
  }
23
47
 
24
48
  logicalOperator = conditions[0];
@@ -31,7 +55,7 @@ export default class WhereExpression {
31
55
  if (Array.isArray(condition)) {
32
56
  // If it's an array, it's a nested condition, so call this function recursively
33
57
  const query = this.createCondition(condition, model, varLength + vars.length);
34
- expression.push(query.sql);
58
+ expression.push(query.expression);
35
59
  if (query.vars !== undefined) {
36
60
  vars = [...vars, ...query.vars];
37
61
  }
@@ -46,7 +70,7 @@ export default class WhereExpression {
46
70
 
47
71
  if (typeof condition.l === 'string') {
48
72
  const query = this.create({ model: model, name: condition.l}, condition.o, condition.r, varLength + vars.length);
49
- expression.push(query.sql);
73
+ expression.push(query.expression);
50
74
  if (query.vars !== undefined) {
51
75
  vars = [...vars, ...query.vars];
52
76
  }
@@ -54,14 +78,14 @@ export default class WhereExpression {
54
78
  }
55
79
 
56
80
  const query = this.create(condition.l, condition.o, condition.r, varLength + vars.length);
57
- expression.push(query.sql);
81
+ expression.push(query.expression);
58
82
  if (query.vars !== undefined) {
59
83
  vars = [...vars, ...query.vars];
60
84
  }
61
85
  }
62
86
 
63
87
  return {
64
- sql: `(${expression.filter(condition => condition ?? '' !== '').join(` ${logicalOperator} `)})`,
88
+ expression: `(${expression.filter(condition => condition ?? '' !== '').join(` ${logicalOperator} `)})`,
65
89
  vars: vars
66
90
  }
67
91
  }
@@ -106,11 +130,11 @@ export default class WhereExpression {
106
130
 
107
131
  if (operator == "=") {
108
132
  return {
109
- sql: `${leftColumn.expression} is null`
133
+ expression: `${leftColumn.expression} is null`
110
134
  }
111
135
  } else if (operator == "!=") {
112
136
  return {
113
- sql: `${leftColumn.expression} is not null`
137
+ expression: `${leftColumn.expression} is not null`
114
138
  }
115
139
  } else {
116
140
  throw new Error(`When comparing with null, operators other than =, != cannot be used. (${operator})`);
@@ -133,7 +157,7 @@ export default class WhereExpression {
133
157
 
134
158
  if (right.length == 0) {
135
159
  // 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
136
- return { sql: '' };
160
+ return { expression: '' };
137
161
  }
138
162
 
139
163
  // Validate values
@@ -141,7 +165,7 @@ export default class WhereExpression {
141
165
  ValidateValueUtil.validateValue(leftColumn, value);
142
166
  }
143
167
  return {
144
- sql: `${leftColumn.expression} ${operator === 'in' ? '=' : '!='} ANY($${varLength})`,
168
+ expression: `${leftColumn.expression} ${operator === 'in' ? '=' : '!='} ANY($${varLength})`,
145
169
  vars: [right]
146
170
  }
147
171
  } else if (Array.isArray(right)) {
@@ -161,17 +185,17 @@ export default class WhereExpression {
161
185
  case 'like':
162
186
  case 'ilike':
163
187
  return {
164
- sql: `${leftColumn.expression} ${operator} '%' || ${rightColumn.expression} || '%'`
188
+ expression: `${leftColumn.expression} ${operator} '%' || ${rightColumn.expression} || '%'`
165
189
  }
166
190
  case 'h2f_like': // half to full like
167
191
  case 'h2f_ilike': // half to full ilike
168
192
  return {
169
- sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`'%' || ${rightColumn.expression} || '%'`)}`
193
+ expression: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`'%' || ${rightColumn.expression} || '%'`)}`
170
194
  }
171
195
  }
172
196
 
173
197
  return {
174
- sql: `${leftColumn.expression} ${operator} ${rightColumn.expression}`
198
+ expression: `${leftColumn.expression} ${operator} ${rightColumn.expression}`
175
199
  }
176
200
  }
177
201
 
@@ -181,19 +205,19 @@ export default class WhereExpression {
181
205
  case 'like':
182
206
  case 'ilike':
183
207
  return {
184
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
208
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
185
209
  vars: [`%${right}%`]
186
210
  }
187
211
  case 'h2f_like': // half to full like
188
212
  case 'h2f_ilike': // half to full ilike
189
213
  return {
190
- sql: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`$${varLength}`)}`,
214
+ expression: `${this.makeSqlReplaceHalfToFull(leftColumn.expression)} ${operator.replace("h2f_", "")} ${this.makeSqlReplaceHalfToFull(`$${varLength}`)}`,
191
215
  vars: [`%${right}%`]
192
216
  }
193
217
  }
194
218
 
195
219
  return {
196
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
220
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
197
221
  vars: [right]
198
222
  }
199
223
  }
@@ -222,14 +246,14 @@ export default class WhereExpression {
222
246
  // バリデーションチェックをする
223
247
 
224
248
  return {
225
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
249
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
226
250
  vars: [right]
227
251
  }
228
252
  }
229
253
 
230
254
 
231
255
  return {
232
- sql: `${leftColumn.expression} ${operator} $${varLength}`,
256
+ expression: `${leftColumn.expression} ${operator} $${varLength}`,
233
257
  vars: [right]
234
258
  }
235
259
  }
@@ -6,6 +6,7 @@ import WhereExpression from './SqlUtils/WhereExpression';
6
6
  import ValidateClient from './ValidateClient';
7
7
  import { DbConflictException, UnprocessableException } from '../exceptions/Exception';
8
8
  import ExpressionClient from './ExpressionClient';
9
+ import UpdateExpression from './SqlUtils/UpdateExpression';
9
10
 
10
11
  export class TableModel {
11
12
 
@@ -84,7 +85,7 @@ export class TableModel {
84
85
  sql += join.type === 'left' ? ' LEFT OUTER JOIN' : ' INNER JOIN';
85
86
  sql += ` ${join.model.TableName} as "${join.model.TableAlias}" ON `;
86
87
  const query = WhereExpression.createCondition(join.conditions, this, this.vars.length + 1);
87
- sql += query.sql;
88
+ sql += query.expression;
88
89
  if (query.vars !== undefined) {
89
90
  this.vars = [...this.vars, ...query.vars]
90
91
  }
@@ -190,22 +191,9 @@ export class TableModel {
190
191
  }
191
192
  }
192
193
 
193
- const conditions = [];
194
- const vars = [];
195
- for (const [keyColumn, column] of Object.entries(this.Columns)) {
196
- if (column.attribute !== 'primary') {
197
- continue;
198
- }
199
-
200
- if (pk[keyColumn] === undefined || pk[keyColumn] === null) {
201
- throw new Error(`No value is set for the primary key "${this.TableName}".${keyColumn}. Please set it in the first argument.`);
202
- }
203
- ValidateValueUtil.validateValue(column, pk[keyColumn]);
204
- vars.push(pk[keyColumn]);
205
- conditions.push(`${keyColumn} = $${vars.length}`);
206
- }
194
+ const {expression, vars} = WhereExpression.createConditionPk(this, pk);
207
195
 
208
- const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${conditions.join(' AND ')}`;
196
+ const sql = `SELECT ${selects.join(',')} FROM ${this.TableName} WHERE ${expression}`;
209
197
  let datas = await this.executeQuery(sql, vars);
210
198
 
211
199
  return datas.rowCount == 0 ? null : datas.rows[0] as T;
@@ -289,7 +277,7 @@ export class TableModel {
289
277
  this.whereExpressions.push(left);
290
278
  } else {
291
279
  const query = WhereExpression.create({model: this, name: left}, operator, right, this.vars.length + 1);
292
- this.whereExpressions.push(query.sql);
280
+ this.whereExpressions.push(query.expression);
293
281
  if (query.vars !== undefined) {
294
282
  this.vars = [...this.vars, ...query.vars];
295
283
  }
@@ -302,7 +290,7 @@ export class TableModel {
302
290
  throw new Error(`If left is TColumnInfo, please set operator and right.`);
303
291
  } else {
304
292
  const query = WhereExpression.create(left, operator, right, this.vars.length + 1);
305
- this.whereExpressions.push(query.sql);
293
+ this.whereExpressions.push(query.expression);
306
294
  if (query.vars !== undefined) {
307
295
  this.vars = [...this.vars, ...query.vars];
308
296
  }
@@ -312,7 +300,7 @@ export class TableModel {
312
300
 
313
301
  if (Array.isArray(left)) {
314
302
  const query = WhereExpression.createCondition(left, this, this.vars.length + 1);
315
- this.whereExpressions.push(query.sql);
303
+ this.whereExpressions.push(query.expression);
316
304
  if (query.vars !== undefined) {
317
305
  this.vars = [...this.vars, ...query.vars];
318
306
  }
@@ -405,7 +393,7 @@ export class TableModel {
405
393
  return { datas: data.rows as Array<T>, count: Number(countData.rows[0].count), lastPage: Math.ceil(Number(countData.rows[0].count) / this.PageCount)};
406
394
  }
407
395
 
408
- private readonly errorMessageEnglish: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist', string> = {
396
+ private readonly errorMessageEnglish: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist' | 'find', string> = {
409
397
  'string': '{name} should be entered as a string or number type.',
410
398
  'string[]': '{name} should be entered as an array of string or number types.',
411
399
  'uuid': '{name} should be entered as a UUID.',
@@ -431,8 +419,9 @@ export class TableModel {
431
419
  'notInput': 'Please enter {name}.',
432
420
  'fk': 'The value of {name} does not exist in the table.',
433
421
  'idNotExist': 'The specified ID({id}) does not exist in the table.',
422
+ 'find': 'The specified data does not exist in the table. ({pks})'
434
423
  }
435
- private readonly errorMessageJapan: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist', string> = {
424
+ private readonly errorMessageJapan: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist' | 'find', string> = {
436
425
  'string': '{name}はstringかnumberで入力してください。',
437
426
  'string[]': '{name}はstringかnumberの配列で入力してください。',
438
427
  'uuid': '{name}はuuidで入力してください。',
@@ -458,6 +447,7 @@ export class TableModel {
458
447
  'notInput': '{name}を入力してください。',
459
448
  'fk': '{name}の値がテーブルに存在しません。',
460
449
  'idNotExist': '指定されたID({id})はテーブルに存在しません。',
450
+ 'find': '指定されたデータはテーブルに存在しません。({pks})'
461
451
  }
462
452
 
463
453
  private throwException(code: string, type: TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist', columnName: string, vallue: any): never {
@@ -474,7 +464,7 @@ export class TableModel {
474
464
  throw new UnprocessableException(code, message);
475
465
  }
476
466
 
477
- protected readonly errorMessages: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist', string> =
467
+ protected readonly errorMessages: Record<TColumnType | TColumnArrayType | 'length' | 'null' | 'notInput' | 'fk' | 'idNotExist' | 'find', string> =
478
468
  process.env.TZ === 'Asia/Tokyo' ? this.errorMessageJapan : this.errorMessageEnglish;
479
469
 
480
470
  protected async validateOptions(options: {[key: string]: any}, isInsert: boolean): Promise<void> {
@@ -606,7 +596,7 @@ export class TableModel {
606
596
  tables.push(`${join.model.TableName} as "${join.model.TableAlias}"`);
607
597
 
608
598
  const query = WhereExpression.createCondition(join.conditions, this, this.vars.length);
609
- this.whereExpressions.push(query.sql);
599
+ this.whereExpressions.push(query.expression);
610
600
  if (query.vars !== undefined) {
611
601
  this.vars = [...this.vars, ...query.vars]
612
602
  }
@@ -628,28 +618,30 @@ export class TableModel {
628
618
  await this.validateUpdateId(id, options);
629
619
  await this.validateUpdate(options);
630
620
 
631
- const updateExpressions: Array<string> = [];
632
- const vars: Array<any> = [];
621
+ const updateSetQuery = UpdateExpression.createUpdateSet(this, options);
622
+ const whereQuery = WhereExpression.createConditionPk(this, {id: id}, updateSetQuery.vars);
633
623
 
634
- for (const [key, value] of Object.entries(options)) {
635
- if (value === undefined) {
636
- throw new Error(`The update option ${key} is undefined.`);
637
- }
624
+ const sql = updateSetQuery.expression + ' WHERE ' + whereQuery.expression;
638
625
 
639
- const column = this.getColumn(key);
640
- if (column.attribute === 'primary') {
641
- throw new Error(`The primary key ${this.TableName}.${key} cannot be changed.`);
642
- }
643
-
644
- vars.push(value);
645
- updateExpressions.push(`${key} = $${vars.length}`);
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(',')));
646
629
  }
647
- vars.push(id);
648
-
649
- const sql = `UPDATE ${this.TableName} SET ${updateExpressions.join(',')} WHERE id = $${vars.length}`;
650
- const data = await this.executeQuery(sql, vars);
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);
651
643
  if (data.rowCount !== 1) {
652
- throw new UnprocessableException("201", this.errorMessages.idNotExist.replace('{id}', id));
644
+ throw new UnprocessableException("401", this.errorMessages.find.replace('{pks}', (whereQuery.vars ?? []).join(',')));
653
645
  }
654
646
  }
655
647
 
@@ -663,7 +655,7 @@ export class TableModel {
663
655
  tables.push(`${join.model.TableName} as "${join.model.TableAlias}"`);
664
656
 
665
657
  const query = WhereExpression.createCondition(join.conditions, this, this.vars.length);
666
- this.whereExpressions.push(query.sql);
658
+ this.whereExpressions.push(query.expression);
667
659
  if (query.vars !== undefined) {
668
660
  this.vars = [...this.vars, ...query.vars]
669
661
  }
@@ -710,7 +702,7 @@ export class TableModel {
710
702
  if (typeof param1 === 'string') {
711
703
  sql = param1;
712
704
  } else {
713
- sql = param1.sql;
705
+ sql = param1.expression;
714
706
  vars = param1.vars;
715
707
  }
716
708
 
@@ -49,7 +49,7 @@ export type TColumnDetail = TColumn & {
49
49
 
50
50
  export type TOperator = "=" | "!=" | ">" | ">=" | "<" | "<=" | "like" | "ilike" | "h2f_like" | "h2f_ilike" | "in" | "not in";
51
51
  export type TColumnInfo = { model: TableModel, name: string }
52
- export type TQuery = {sql: string, vars?: Array<any>};
52
+ export type TQuery = {expression: string, vars?: Array<any>};
53
53
  export type TSelectExpression = { expression: string, alias: string }
54
54
  export type TAggregateFuncType = 'sum' | 'avg' | 'max' | 'min' | 'count';
55
55
  export type TCondition = string | {
File without changes