pg-mvc-service 2.1.0 → 2.1.2
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/PoolManager.d.ts +7 -0
- package/dist/PoolManager.d.ts.map +1 -0
- package/dist/Service.d.ts +79 -0
- package/dist/Service.d.ts.map +1 -0
- package/dist/Service.js +0 -8
- package/dist/Utils/DateTimeUtil.d.ts +58 -0
- package/dist/Utils/DateTimeUtil.d.ts.map +1 -0
- package/dist/Utils/NumberUtil.d.ts +10 -0
- package/dist/Utils/NumberUtil.d.ts.map +1 -0
- package/dist/Utils/StringUtil.d.ts +16 -0
- package/dist/Utils/StringUtil.d.ts.map +1 -0
- package/dist/clients/AwsS3Client.d.ts +34 -0
- package/dist/clients/AwsS3Client.d.ts.map +1 -0
- package/dist/clients/AwsS3Client.js +13 -28
- package/dist/clients/EncryptClient.d.ts +18 -0
- package/dist/clients/EncryptClient.d.ts.map +1 -0
- package/dist/clients/StringClient.d.ts +6 -0
- package/dist/clients/StringClient.d.ts.map +1 -0
- package/dist/cron/BaseCron.d.ts +32 -0
- package/dist/cron/BaseCron.d.ts.map +1 -0
- package/dist/cron/BaseCron.js +0 -7
- package/dist/cron/CronExecuter.d.ts +2 -0
- package/dist/cron/CronExecuter.d.ts.map +1 -0
- package/dist/cron/CronType.d.ts +6 -0
- package/dist/cron/CronType.d.ts.map +1 -0
- package/dist/documents/Swagger.d.ts +10 -0
- package/dist/documents/Swagger.d.ts.map +1 -0
- package/dist/exceptions/Exception.d.ts +31 -0
- package/dist/exceptions/Exception.d.ts.map +1 -0
- package/{src/index.ts → dist/index.d.ts} +3 -7
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -3
- package/dist/models/ExpressionClient.d.ts +12 -0
- package/dist/models/ExpressionClient.d.ts.map +1 -0
- package/dist/models/MigrateDatabase.d.ts +19 -0
- package/dist/models/MigrateDatabase.d.ts.map +1 -0
- package/dist/models/MigrateRollback.d.ts +18 -0
- package/dist/models/MigrateRollback.d.ts.map +1 -0
- package/dist/models/MigrateTable.d.ts +13 -0
- package/dist/models/MigrateTable.d.ts.map +1 -0
- package/dist/models/SqlUtils/SelectExpression.d.ts +31 -0
- package/dist/models/SqlUtils/SelectExpression.d.ts.map +1 -0
- package/dist/models/SqlUtils/UpdateExpression.d.ts +8 -0
- package/dist/models/SqlUtils/UpdateExpression.d.ts.map +1 -0
- package/dist/models/SqlUtils/ValidateValueUtil.d.ts +19 -0
- package/dist/models/SqlUtils/ValidateValueUtil.d.ts.map +1 -0
- package/dist/models/SqlUtils/WhereExpression.d.ts +30 -0
- package/dist/models/SqlUtils/WhereExpression.d.ts.map +1 -0
- package/dist/models/TableDoc.d.ts +3 -0
- package/dist/models/TableDoc.d.ts.map +1 -0
- package/dist/models/TableModel.d.ts +196 -0
- package/dist/models/TableModel.d.ts.map +1 -0
- package/dist/models/Type.d.ts +64 -0
- package/dist/models/Type.d.ts.map +1 -0
- package/dist/models/Utils/MessageUtil.d.ts +7 -0
- package/dist/models/Utils/MessageUtil.d.ts.map +1 -0
- package/dist/models/ValidateClient.d.ts +27 -0
- package/dist/models/ValidateClient.d.ts.map +1 -0
- package/dist/reqestResponse/ReqResType.d.ts +113 -0
- package/dist/reqestResponse/ReqResType.d.ts.map +1 -0
- package/dist/reqestResponse/RequestType.d.ts +247 -0
- package/dist/reqestResponse/RequestType.d.ts.map +1 -0
- package/dist/reqestResponse/ResponseType.d.ts +85 -0
- package/dist/reqestResponse/ResponseType.d.ts.map +1 -0
- package/package.json +7 -2
- package/dist/clients/Base64Client.js +0 -292
- package/index.d.ts +0 -192
- package/src/PoolManager.ts +0 -48
- package/src/Service.ts +0 -307
- package/src/Utils/DateTimeUtil.ts +0 -146
- package/src/Utils/NumberUtil.ts +0 -23
- package/src/Utils/StringUtil.ts +0 -33
- package/src/clients/AwsS3Client.ts +0 -310
- package/src/clients/Base64Client.ts +0 -305
- package/src/clients/EncryptClient.ts +0 -100
- package/src/clients/StringClient.ts +0 -19
- package/src/cron/BaseCron.ts +0 -122
- package/src/cron/CronExecuter.ts +0 -34
- package/src/cron/CronType.ts +0 -25
- package/src/documents/Swagger.ts +0 -106
- package/src/exceptions/Exception.ts +0 -72
- package/src/models/ExpressionClient.ts +0 -72
- package/src/models/MigrateDatabase.ts +0 -135
- package/src/models/MigrateRollback.ts +0 -151
- package/src/models/MigrateTable.ts +0 -56
- package/src/models/SqlUtils/SelectExpression.ts +0 -102
- package/src/models/SqlUtils/UpdateExpression.ts +0 -29
- package/src/models/SqlUtils/ValidateValueUtil.ts +0 -354
- package/src/models/SqlUtils/WhereExpression.ts +0 -455
- package/src/models/TableDoc.ts +0 -372
- package/src/models/TableModel.ts +0 -749
- package/src/models/Type.ts +0 -62
- package/src/models/Utils/MessageUtil.ts +0 -60
- package/src/models/ValidateClient.ts +0 -182
- package/src/reqestResponse/ReqResType.ts +0 -241
- package/src/reqestResponse/RequestType.ts +0 -1619
- package/src/reqestResponse/ResponseType.ts +0 -549
- package/tsconfig.json +0 -14
|
@@ -1,455 +0,0 @@
|
|
|
1
|
-
import { TableModel } from "../TableModel";
|
|
2
|
-
import { TColumnArrayType, TColumnDetail, TColumnInfo, TColumnType, TNestedCondition, TOperator, TQuery } from "../Type";
|
|
3
|
-
import ValidateValueUtil from "./ValidateValueUtil";
|
|
4
|
-
|
|
5
|
-
export class WhereExpression {
|
|
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
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Helper method to create OR conditions
|
|
33
|
-
* @param conditions Array of conditions that make up the OR condition
|
|
34
|
-
* @returns SQL query string representing the OR condition
|
|
35
|
-
*/
|
|
36
|
-
public static createCondition(conditions: Array<TNestedCondition>, model: TableModel, varLength: number): TQuery {
|
|
37
|
-
|
|
38
|
-
if (conditions.length === 0) {
|
|
39
|
-
return { expression: '' };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let logicalOperator = 'AND';
|
|
43
|
-
if (conditions[0] === 'AND' || conditions[0] === 'OR') {
|
|
44
|
-
if (conditions.length === 1) {
|
|
45
|
-
return { expression: '' };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
logicalOperator = conditions[0];
|
|
49
|
-
conditions.shift();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const expression: string[] = [];
|
|
53
|
-
let vars: any[] = []
|
|
54
|
-
for (let condition of conditions) {
|
|
55
|
-
if (Array.isArray(condition)) {
|
|
56
|
-
// If it's an array, it's a nested condition, so call this function recursively
|
|
57
|
-
const query = this.createCondition(condition, model, varLength + vars.length);
|
|
58
|
-
expression.push(query.expression);
|
|
59
|
-
if (query.vars !== undefined) {
|
|
60
|
-
vars = [...vars, ...query.vars];
|
|
61
|
-
}
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (typeof condition === 'string') {
|
|
66
|
-
// If specified directly as a string, it becomes a query, so insert as is
|
|
67
|
-
expression.push(condition);
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (typeof condition.l === 'string') {
|
|
72
|
-
const query = this.create({ model: model, name: condition.l}, condition.o, condition.r, varLength + vars.length);
|
|
73
|
-
expression.push(query.expression);
|
|
74
|
-
if (query.vars !== undefined) {
|
|
75
|
-
vars = [...vars, ...query.vars];
|
|
76
|
-
}
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const query = this.create(condition.l, condition.o, condition.r, varLength + vars.length);
|
|
81
|
-
expression.push(query.expression);
|
|
82
|
-
if (query.vars !== undefined) {
|
|
83
|
-
vars = [...vars, ...query.vars];
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
expression: `(${expression.filter(condition => condition ?? '' !== '').join(` ${logicalOperator} `)})`,
|
|
89
|
-
vars: vars
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public static create(left: TColumnInfo, operator: TOperator, right: TColumnInfo | any, varLength: number) : TQuery {
|
|
94
|
-
|
|
95
|
-
// Check if the specified ColumnInfo exists
|
|
96
|
-
const leftColumn = left.model.getColumn(left.name);
|
|
97
|
-
|
|
98
|
-
// Are the operators correct?
|
|
99
|
-
const useableOperator: { [key in TColumnType | TColumnArrayType]: TOperator[] } = {
|
|
100
|
-
integer: ["=", "!=", ">", ">=", "<", "<=", "in", "not in"],
|
|
101
|
-
'integer[]': ["=", "any", "@>", "&&"],
|
|
102
|
-
real: ["=", "!=", ">", ">=", "<", "<="],
|
|
103
|
-
'real[]': ["=", "any", "@>", "&&"],
|
|
104
|
-
string: ["=", "!=", "like", "ilike", "h2f_like", "h2f_ilike", "in", "not in"],
|
|
105
|
-
'string[]': ["=", "any", "@>", "&&"],
|
|
106
|
-
uuid: ["=", "!=", "in", "not in"],
|
|
107
|
-
'uuid[]': ["=", "any", "@>", "&&"],
|
|
108
|
-
bool: ["=", "!=", "in", "not in"],
|
|
109
|
-
'bool[]': ["=", "any", "@>", "&&"],
|
|
110
|
-
date: ["=", "!=", ">", ">=", "<", "<="],
|
|
111
|
-
'date[]': ["=", "any", "@>", "&&"],
|
|
112
|
-
time: ["=", "!=", ">", ">=", "<", "<="],
|
|
113
|
-
'time[]': ["=", "any", "@>", "&&"],
|
|
114
|
-
timestamp: ["=", "!=", ">", ">=", "<", "<="],
|
|
115
|
-
'timestamp[]': ["=", "any", "@>", "&&"],
|
|
116
|
-
json: [],
|
|
117
|
-
'json[]': [],
|
|
118
|
-
jsonb: [],
|
|
119
|
-
'jsonb[]': []
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
if (useableOperator[leftColumn.type].includes(operator) == false) {
|
|
123
|
-
throw new Error(`The ${operator} operator cannot be used for ${leftColumn.tableName}.${leftColumn.columnName}. (${leftColumn.type})`);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (right === null) {
|
|
127
|
-
if (leftColumn.attribute !== "nullable") {
|
|
128
|
-
throw new Error(`You cannot use conditions with null values unless the attribute is nullable.`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (operator == "=") {
|
|
132
|
-
return {
|
|
133
|
-
expression: `${leftColumn.expression} is null`
|
|
134
|
-
}
|
|
135
|
-
} else if (operator == "!=") {
|
|
136
|
-
return {
|
|
137
|
-
expression: `${leftColumn.expression} is not null`
|
|
138
|
-
}
|
|
139
|
-
} else {
|
|
140
|
-
throw new Error(`When comparing with null, operators other than =, != cannot be used. (${operator})`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const isColumnRight = right !== null && typeof right === 'object' && 'model' in right && 'name' in right;
|
|
145
|
-
const isArrayColumnLeft = leftColumn.type.endsWith("[]");
|
|
146
|
-
if (isArrayColumnLeft) {
|
|
147
|
-
if (isColumnRight) {
|
|
148
|
-
return this.createExpressionArrayColumn(leftColumn, operator, right, varLength);
|
|
149
|
-
} else {
|
|
150
|
-
return this.createExpressionArrayValue(leftColumn, operator, right, varLength);
|
|
151
|
-
}
|
|
152
|
-
} else {
|
|
153
|
-
return this.createExpression(leftColumn, operator, right, varLength);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
private static createExpression(leftColumn: TColumnDetail, operator: TOperator, right: TColumnInfo | any, varLength: number) : TQuery {
|
|
158
|
-
// IN NOT IN clause
|
|
159
|
-
if (["in", "not in"].includes(operator)) {
|
|
160
|
-
if (Array.isArray(right) == false) {
|
|
161
|
-
throw new Error(`For the 'in' operator, you cannot input anything other than an array on the right side.`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (right.length == 0) {
|
|
165
|
-
// 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
|
|
166
|
-
return { expression: '' };
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Validate values
|
|
170
|
-
for (const value of right) {
|
|
171
|
-
ValidateValueUtil.validateValue(leftColumn, value);
|
|
172
|
-
}
|
|
173
|
-
return {
|
|
174
|
-
expression: `${leftColumn.expression} ${operator === 'in' ? '=' : '!='} ANY($${varLength})`,
|
|
175
|
-
vars: [right]
|
|
176
|
-
}
|
|
177
|
-
} else if (Array.isArray(right)) {
|
|
178
|
-
throw new Error(`For operators other than 'in', you cannot input an array on the right side.`);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// If the right side value is a column specification
|
|
182
|
-
if (right !== null && typeof right === 'object' && 'model' in right && 'name' in right) {
|
|
183
|
-
const rightColumn = right.model.getColumn(right.name);
|
|
184
|
-
|
|
185
|
-
// 型の不一致エラーメッセージを改善
|
|
186
|
-
if (leftColumn.type !== rightColumn.type) {
|
|
187
|
-
throw new Error(`Type mismatch: column [${leftColumn.tableName}].[${leftColumn.columnName}] (${leftColumn.type}) and [${rightColumn.tableName}].[${rightColumn.columnName}] (${rightColumn.type}) must be the same type.`);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// LIKE operators are different, so handle separately
|
|
191
|
-
switch (operator) {
|
|
192
|
-
case 'like':
|
|
193
|
-
case 'ilike':
|
|
194
|
-
return {
|
|
195
|
-
expression: `${leftColumn.expression} ${operator} '%' || ${rightColumn.expression} || '%'`
|
|
196
|
-
}
|
|
197
|
-
case 'h2f_like': // half to full like
|
|
198
|
-
case 'h2f_ilike': // half to full ilike
|
|
199
|
-
return {
|
|
200
|
-
expression: `${this.makeSqlNormalizeCharVariants(leftColumn.expression, {halfToFull: true})} ${operator.replace("h2f_", "")} ${this.makeSqlNormalizeCharVariants(`'%' || ${rightColumn.expression} || '%'`, {halfToFull: true})}`
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return {
|
|
205
|
-
expression: `${leftColumn.expression} ${operator} ${rightColumn.expression}`
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
ValidateValueUtil.validateValue(leftColumn, right);
|
|
210
|
-
// LIKE operators are different, so handle separately
|
|
211
|
-
switch (operator) {
|
|
212
|
-
case 'like':
|
|
213
|
-
case 'ilike':
|
|
214
|
-
return {
|
|
215
|
-
expression: `${leftColumn.expression} ${operator} $${varLength}`,
|
|
216
|
-
vars: [`%${right}%`]
|
|
217
|
-
}
|
|
218
|
-
case 'h2f_like': // half to full like
|
|
219
|
-
case 'h2f_ilike': // half to full ilike
|
|
220
|
-
return {
|
|
221
|
-
expression: `${this.makeSqlNormalizeCharVariants(leftColumn.expression, {halfToFull: true})} ${operator.replace("h2f_", "")} ${this.makeSqlNormalizeCharVariants(`$${varLength}`, {halfToFull: true})}`,
|
|
222
|
-
vars: [`%${right}%`]
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return {
|
|
227
|
-
expression: `${leftColumn.expression} ${operator} $${varLength}`,
|
|
228
|
-
vars: [right]
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
private static createExpressionArrayValue(leftColumn: TColumnDetail, operator: TOperator, right: any, varLength: number) : TQuery {
|
|
233
|
-
|
|
234
|
-
// バリデーションチェック
|
|
235
|
-
switch (operator) {
|
|
236
|
-
case 'any':
|
|
237
|
-
switch (leftColumn.type) {
|
|
238
|
-
case 'integer[]':
|
|
239
|
-
if (ValidateValueUtil.isErrorInteger(right)) {
|
|
240
|
-
throw new Error(`Expected integer value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
241
|
-
}
|
|
242
|
-
break;
|
|
243
|
-
case 'real[]':
|
|
244
|
-
if (ValidateValueUtil.isErrorReal(right)) {
|
|
245
|
-
throw new Error(`Expected numeric value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
246
|
-
}
|
|
247
|
-
break;
|
|
248
|
-
case 'string[]':
|
|
249
|
-
if (ValidateValueUtil.isErrorString(right)) {
|
|
250
|
-
throw new Error(`Expected string value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
251
|
-
}
|
|
252
|
-
break;
|
|
253
|
-
case 'uuid[]':
|
|
254
|
-
if (ValidateValueUtil.isErrorUUID(right)) {
|
|
255
|
-
throw new Error(`Expected UUID value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
256
|
-
}
|
|
257
|
-
break;
|
|
258
|
-
case 'bool[]':
|
|
259
|
-
if (ValidateValueUtil.isErrorBool(right)) {
|
|
260
|
-
throw new Error(`Expected boolean value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
261
|
-
}
|
|
262
|
-
break;
|
|
263
|
-
case 'date[]':
|
|
264
|
-
if (ValidateValueUtil.isErrorDate(right)) {
|
|
265
|
-
throw new Error(`Expected date value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
266
|
-
}
|
|
267
|
-
break;
|
|
268
|
-
case 'time[]':
|
|
269
|
-
if (ValidateValueUtil.isErrorTime(right)) {
|
|
270
|
-
throw new Error(`Expected time value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
271
|
-
}
|
|
272
|
-
break;
|
|
273
|
-
case 'timestamp[]':
|
|
274
|
-
if (ValidateValueUtil.isErrorTimestamp(right)) {
|
|
275
|
-
throw new Error(`Expected timestamp value for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
276
|
-
}
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
break;
|
|
280
|
-
case '=':
|
|
281
|
-
case '@>':
|
|
282
|
-
case '&&':
|
|
283
|
-
if (Array.isArray(right) === false) {
|
|
284
|
-
throw new Error(`Expected array format for array column (${leftColumn.type}), but received: ${JSON.stringify(right)}`);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
for (const value of right) {
|
|
288
|
-
switch (leftColumn.type) {
|
|
289
|
-
case 'integer[]':
|
|
290
|
-
if (ValidateValueUtil.isErrorInteger(value)) {
|
|
291
|
-
throw new Error(`Expected integer value in array element, but received: ${JSON.stringify(value)}`);
|
|
292
|
-
}
|
|
293
|
-
break;
|
|
294
|
-
case 'real[]':
|
|
295
|
-
if (ValidateValueUtil.isErrorReal(value)) {
|
|
296
|
-
throw new Error(`Expected numeric value in array element, but received: ${JSON.stringify(value)}`);
|
|
297
|
-
}
|
|
298
|
-
break;
|
|
299
|
-
case 'string[]':
|
|
300
|
-
if (ValidateValueUtil.isErrorString(value)) {
|
|
301
|
-
throw new Error(`Expected string value in array element, but received: ${JSON.stringify(value)}`);
|
|
302
|
-
}
|
|
303
|
-
break;
|
|
304
|
-
case 'uuid[]':
|
|
305
|
-
if (ValidateValueUtil.isErrorUUID(value)) {
|
|
306
|
-
throw new Error(`Expected UUID value in array element, but received: ${JSON.stringify(value)}`);
|
|
307
|
-
}
|
|
308
|
-
break;
|
|
309
|
-
case 'bool[]':
|
|
310
|
-
if (ValidateValueUtil.isErrorBool(value)) {
|
|
311
|
-
throw new Error(`Expected boolean value in array element, but received: ${JSON.stringify(value)}`);
|
|
312
|
-
}
|
|
313
|
-
break;
|
|
314
|
-
case 'date[]':
|
|
315
|
-
if (ValidateValueUtil.isErrorDate(value)) {
|
|
316
|
-
throw new Error(`Expected date value in array element, but received: ${JSON.stringify(value)}`);
|
|
317
|
-
}
|
|
318
|
-
break;
|
|
319
|
-
case 'time[]':
|
|
320
|
-
if (ValidateValueUtil.isErrorTime(value)) {
|
|
321
|
-
throw new Error(`Expected time value in array element, but received: ${JSON.stringify(value)}`);
|
|
322
|
-
}
|
|
323
|
-
break;
|
|
324
|
-
case 'timestamp[]':
|
|
325
|
-
if (ValidateValueUtil.isErrorTimestamp(value)) {
|
|
326
|
-
throw new Error(`Expected timestamp value in array element, but received: ${JSON.stringify(value)}`);
|
|
327
|
-
}
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
break;
|
|
332
|
-
default:
|
|
333
|
-
throw new Error(`Unsupported operator '${operator}' for array column operations.`);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
switch (operator) {
|
|
337
|
-
case '=':
|
|
338
|
-
// =で検索すると順番まで一致させないといけないので、順番不一致でも中身があってれば一致とするようにする
|
|
339
|
-
return {
|
|
340
|
-
expression: `(${leftColumn.expression} @> $${varLength} AND $${varLength} @> ${leftColumn.expression})`,
|
|
341
|
-
vars: [right]
|
|
342
|
-
}
|
|
343
|
-
case '@>':
|
|
344
|
-
case '&&':
|
|
345
|
-
return {
|
|
346
|
-
expression: `${leftColumn.expression} ${operator} $${varLength}`,
|
|
347
|
-
vars: [right]
|
|
348
|
-
}
|
|
349
|
-
case 'any':
|
|
350
|
-
return {
|
|
351
|
-
expression: `$${varLength} = ANY(${leftColumn.expression})`,
|
|
352
|
-
vars: [right]
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
private static createExpressionArrayColumn(leftColumn: TColumnDetail, operator: TOperator, right: TColumnInfo, varLength: number) : TQuery {
|
|
358
|
-
|
|
359
|
-
const rightColumn = right.model.getColumn(right.name);
|
|
360
|
-
|
|
361
|
-
// バリデーションチェック
|
|
362
|
-
switch (operator) {
|
|
363
|
-
case 'any':
|
|
364
|
-
// any演算子の場合
|
|
365
|
-
if (leftColumn.type !== rightColumn.type.replace('[]', '')) {
|
|
366
|
-
throw new Error(`Type mismatch: array column [${leftColumn.tableName}].[${leftColumn.columnName}] (${leftColumn.type}) and scalar column [${rightColumn.tableName}].[${rightColumn.columnName}] (${rightColumn.type}) are incompatible for ANY operation.`);
|
|
367
|
-
}
|
|
368
|
-
break;
|
|
369
|
-
case '=':
|
|
370
|
-
case '@>':
|
|
371
|
-
case '&&':
|
|
372
|
-
// 配列演算子の場合
|
|
373
|
-
if (leftColumn.type !== rightColumn.type) {
|
|
374
|
-
throw new Error(`Type mismatch: array columns [${leftColumn.tableName}].[${leftColumn.columnName}] (${leftColumn.type}) and [${rightColumn.tableName}].[${rightColumn.columnName}] (${rightColumn.type}) must be the same type.`);
|
|
375
|
-
}
|
|
376
|
-
break;
|
|
377
|
-
default:
|
|
378
|
-
// サポートされていない演算子
|
|
379
|
-
throw new Error(`Operator '${operator}' is not supported for array column operations. Supported operators: =, @>, &&, ANY`);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
switch (operator) {
|
|
383
|
-
case '=':
|
|
384
|
-
// =で検索すると順番まで一致させないといけないので、順番不一致でも中身があってれば一致とするようにする
|
|
385
|
-
return {
|
|
386
|
-
expression: `(${leftColumn.expression} @> ${rightColumn.expression} AND ${rightColumn.expression} @> ${leftColumn.expression})`,
|
|
387
|
-
vars: []
|
|
388
|
-
}
|
|
389
|
-
case '@>':
|
|
390
|
-
case '&&':
|
|
391
|
-
return {
|
|
392
|
-
expression: `${leftColumn.expression} ${operator} $${rightColumn.expression}`,
|
|
393
|
-
vars: []
|
|
394
|
-
}
|
|
395
|
-
case 'any':
|
|
396
|
-
return {
|
|
397
|
-
expression: `$${rightColumn.expression} = ANY(${leftColumn.expression})`,
|
|
398
|
-
vars: []
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* SQL statement to convert half-width characters to full-width
|
|
405
|
-
* @param {string} columnName Column name
|
|
406
|
-
* @returns SQL statement
|
|
407
|
-
*/
|
|
408
|
-
public static makeSqlNormalizeCharVariants(expression: string, replaceOption?: true | {
|
|
409
|
-
halfToFull?: boolean; hiraganaToKatakana?: boolean;
|
|
410
|
-
numeric?: true | { japanese?: boolean; }
|
|
411
|
-
}) {
|
|
412
|
-
if (replaceOption === true) {
|
|
413
|
-
replaceOption = {
|
|
414
|
-
halfToFull: true,
|
|
415
|
-
hiraganaToKatakana: true,
|
|
416
|
-
numeric: true
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (replaceOption?.numeric === true) {
|
|
421
|
-
replaceOption.numeric = {
|
|
422
|
-
japanese: true
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
let sql = expression;
|
|
427
|
-
// 1. ひらがな → カタカナ (TRANSLATEを使用)
|
|
428
|
-
// NORMALIZEはひらがなをカタカナにはしないので、これは残します
|
|
429
|
-
if (replaceOption?.hiraganaToKatakana === true) {
|
|
430
|
-
const from = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんゔがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぁぃぅぇぉゃゅょっー、。・「」゛゜';
|
|
431
|
-
const to = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンヴガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポァィゥェォャュョッー、。・「」゛゜';
|
|
432
|
-
sql = `TRANSLATE(${sql}, '${from}', '${to}')`;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// 2. 漢数字 → 算用数字 (TRANSLATEを使用)
|
|
436
|
-
// これもNORMALIZEの管轄外なので残しますが、1つのTRANSLATEにまとめます(SQLが速くなります)
|
|
437
|
-
if (replaceOption?.numeric?.japanese === true) {
|
|
438
|
-
const from = '零〇一壱弌二弐三参四肆五伍六陸七漆八捌九玖';
|
|
439
|
-
const to = '001112233445566778899';
|
|
440
|
-
sql = `TRANSLATE(${sql}, '${from}', '${to}')`;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// 3. 全角半角の統一 (ここを NORMALIZE に変更!)
|
|
444
|
-
// 元の halfToFull ブロックを削除し、この処理に置き換えます
|
|
445
|
-
if (replaceOption?.halfToFull === true) {
|
|
446
|
-
// NORMALIZE(..., NFKC) は以下の処理を自動で行います
|
|
447
|
-
// - 全角英数字 → 半角英数字 (例: A → A)
|
|
448
|
-
// - 半角カナ → 全角カナ (例: ア → ア)
|
|
449
|
-
// - 濁点の結合 (例: カ + ゙ → ガ)
|
|
450
|
-
sql = `NORMALIZE(${sql}, NFKC)`;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
return sql;
|
|
454
|
-
}
|
|
455
|
-
}
|