@berthojoris/mcp-mysql-server 1.10.2 → 1.10.4
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/CHANGELOG.md +25 -7
- package/DOCUMENTATIONS.md +2 -2
- package/README.md +1 -1
- package/dist/index.d.ts +0 -99
- package/dist/mcp-server.js +0 -21
- package/dist/tools/backupRestoreTools.d.ts +1 -6
- package/dist/tools/backupRestoreTools.js +99 -97
- package/dist/tools/constraintTools.d.ts +4 -11
- package/dist/tools/constraintTools.js +114 -115
- package/dist/tools/crudTools.d.ts +2 -6
- package/dist/tools/crudTools.js +186 -189
- package/dist/tools/dataExportTools.d.ts +0 -7
- package/dist/tools/dataExportTools.js +0 -15
- package/dist/tools/databaseTools.d.ts +1 -4
- package/dist/tools/databaseTools.js +29 -33
- package/dist/tools/ddlTools.d.ts +1 -5
- package/dist/tools/ddlTools.js +68 -53
- package/dist/tools/functionTools.d.ts +3 -9
- package/dist/tools/functionTools.js +111 -104
- package/dist/tools/indexTools.d.ts +3 -8
- package/dist/tools/indexTools.js +99 -95
- package/dist/tools/maintenanceTools.d.ts +2 -10
- package/dist/tools/maintenanceTools.js +66 -80
- package/dist/tools/migrationTools.d.ts +0 -5
- package/dist/tools/migrationTools.js +56 -24
- package/dist/tools/performanceTools.d.ts +1 -11
- package/dist/tools/performanceTools.js +278 -267
- package/dist/tools/processTools.d.ts +4 -13
- package/dist/tools/processTools.js +78 -80
- package/dist/tools/queryTools.d.ts +0 -2
- package/dist/tools/queryTools.js +0 -4
- package/dist/tools/schemaVersioningTools.d.ts +0 -9
- package/dist/tools/schemaVersioningTools.js +167 -166
- package/dist/tools/storedProcedureTools.d.ts +2 -4
- package/dist/tools/storedProcedureTools.js +143 -134
- package/dist/tools/transactionTools.d.ts +2 -3
- package/dist/tools/transactionTools.js +28 -29
- package/dist/tools/triggerTools.d.ts +3 -8
- package/dist/tools/triggerTools.js +98 -85
- package/dist/tools/utilityTools.d.ts +0 -1
- package/dist/tools/utilityTools.js +0 -2
- package/dist/tools/viewTools.d.ts +7 -13
- package/dist/tools/viewTools.js +100 -93
- package/package.json +1 -1
package/dist/tools/crudTools.js
CHANGED
|
@@ -18,8 +18,8 @@ class CrudTools {
|
|
|
18
18
|
// Validate input schema
|
|
19
19
|
if (!(0, schemas_1.validateCreateRecord)(params)) {
|
|
20
20
|
return {
|
|
21
|
-
status:
|
|
22
|
-
error:
|
|
21
|
+
status: "error",
|
|
22
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateCreateRecord.errors),
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
@@ -28,8 +28,8 @@ class CrudTools {
|
|
|
28
28
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
29
29
|
if (!tableValidation.valid) {
|
|
30
30
|
return {
|
|
31
|
-
status:
|
|
32
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
31
|
+
status: "error",
|
|
32
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
// Validate column names
|
|
@@ -38,8 +38,8 @@ class CrudTools {
|
|
|
38
38
|
const columnValidation = this.security.validateIdentifier(column);
|
|
39
39
|
if (!columnValidation.valid) {
|
|
40
40
|
return {
|
|
41
|
-
status:
|
|
42
|
-
error: `Invalid column name '${column}': ${columnValidation.error}
|
|
41
|
+
status: "error",
|
|
42
|
+
error: `Invalid column name '${column}': ${columnValidation.error}`,
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -48,31 +48,29 @@ class CrudTools {
|
|
|
48
48
|
const paramValidation = this.security.validateParameters(values);
|
|
49
49
|
if (!paramValidation.valid) {
|
|
50
50
|
return {
|
|
51
|
-
status:
|
|
52
|
-
error: `Invalid parameter values: ${paramValidation.error}
|
|
51
|
+
status: "error",
|
|
52
|
+
error: `Invalid parameter values: ${paramValidation.error}`,
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
// Build the query with escaped identifiers
|
|
56
56
|
const escapedTableName = this.security.escapeIdentifier(table_name);
|
|
57
|
-
const escapedColumns = columns.map(col => this.security.escapeIdentifier(col));
|
|
58
|
-
const placeholders = columns.map(() =>
|
|
59
|
-
const query = `INSERT INTO ${escapedTableName} (${escapedColumns.join(
|
|
57
|
+
const escapedColumns = columns.map((col) => this.security.escapeIdentifier(col));
|
|
58
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
59
|
+
const query = `INSERT INTO ${escapedTableName} (${escapedColumns.join(", ")}) VALUES (${placeholders})`;
|
|
60
60
|
// Execute the query with sanitized parameters
|
|
61
61
|
const result = await this.db.query(query, paramValidation.sanitizedParams);
|
|
62
62
|
return {
|
|
63
|
-
status:
|
|
63
|
+
status: "success",
|
|
64
64
|
data: {
|
|
65
65
|
insertId: result.insertId,
|
|
66
|
-
affectedRows: result.affectedRows
|
|
66
|
+
affectedRows: result.affectedRows,
|
|
67
67
|
},
|
|
68
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
69
68
|
};
|
|
70
69
|
}
|
|
71
70
|
catch (error) {
|
|
72
71
|
return {
|
|
73
|
-
status:
|
|
72
|
+
status: "error",
|
|
74
73
|
error: error.message,
|
|
75
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
76
74
|
};
|
|
77
75
|
}
|
|
78
76
|
}
|
|
@@ -83,8 +81,8 @@ class CrudTools {
|
|
|
83
81
|
// Validate input schema
|
|
84
82
|
if (!(0, schemas_1.validateReadRecords)(params)) {
|
|
85
83
|
return {
|
|
86
|
-
status:
|
|
87
|
-
error:
|
|
84
|
+
status: "error",
|
|
85
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateReadRecords.errors),
|
|
88
86
|
};
|
|
89
87
|
}
|
|
90
88
|
try {
|
|
@@ -93,8 +91,8 @@ class CrudTools {
|
|
|
93
91
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
94
92
|
if (!tableValidation.valid) {
|
|
95
93
|
return {
|
|
96
|
-
status:
|
|
97
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
94
|
+
status: "error",
|
|
95
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
98
96
|
};
|
|
99
97
|
}
|
|
100
98
|
// Validate sorting field if provided
|
|
@@ -102,8 +100,8 @@ class CrudTools {
|
|
|
102
100
|
const sortFieldValidation = this.security.validateIdentifier(sorting.field);
|
|
103
101
|
if (!sortFieldValidation.valid) {
|
|
104
102
|
return {
|
|
105
|
-
status:
|
|
106
|
-
error: `Invalid sorting field: ${sortFieldValidation.error}
|
|
103
|
+
status: "error",
|
|
104
|
+
error: `Invalid sorting field: ${sortFieldValidation.error}`,
|
|
107
105
|
};
|
|
108
106
|
}
|
|
109
107
|
}
|
|
@@ -113,69 +111,69 @@ class CrudTools {
|
|
|
113
111
|
const fieldValidation = this.security.validateIdentifier(filter.field);
|
|
114
112
|
if (!fieldValidation.valid) {
|
|
115
113
|
return {
|
|
116
|
-
status:
|
|
117
|
-
error: `Invalid filter field '${filter.field}': ${fieldValidation.error}
|
|
114
|
+
status: "error",
|
|
115
|
+
error: `Invalid filter field '${filter.field}': ${fieldValidation.error}`,
|
|
118
116
|
};
|
|
119
117
|
}
|
|
120
118
|
}
|
|
121
119
|
}
|
|
122
120
|
// Build the WHERE clause if filters are provided
|
|
123
|
-
let whereClause =
|
|
121
|
+
let whereClause = "";
|
|
124
122
|
let queryParams = [];
|
|
125
123
|
if (filters && filters.length > 0) {
|
|
126
|
-
const conditions = filters.map(filter => {
|
|
124
|
+
const conditions = filters.map((filter) => {
|
|
127
125
|
const escapedField = this.security.escapeIdentifier(filter.field);
|
|
128
126
|
switch (filter.operator) {
|
|
129
|
-
case
|
|
127
|
+
case "eq":
|
|
130
128
|
queryParams.push(filter.value);
|
|
131
129
|
return `${escapedField} = ?`;
|
|
132
|
-
case
|
|
130
|
+
case "neq":
|
|
133
131
|
queryParams.push(filter.value);
|
|
134
132
|
return `${escapedField} != ?`;
|
|
135
|
-
case
|
|
133
|
+
case "gt":
|
|
136
134
|
queryParams.push(filter.value);
|
|
137
135
|
return `${escapedField} > ?`;
|
|
138
|
-
case
|
|
136
|
+
case "gte":
|
|
139
137
|
queryParams.push(filter.value);
|
|
140
138
|
return `${escapedField} >= ?`;
|
|
141
|
-
case
|
|
139
|
+
case "lt":
|
|
142
140
|
queryParams.push(filter.value);
|
|
143
141
|
return `${escapedField} < ?`;
|
|
144
|
-
case
|
|
142
|
+
case "lte":
|
|
145
143
|
queryParams.push(filter.value);
|
|
146
144
|
return `${escapedField} <= ?`;
|
|
147
|
-
case
|
|
145
|
+
case "like":
|
|
148
146
|
queryParams.push(`%${filter.value}%`);
|
|
149
147
|
return `${escapedField} LIKE ?`;
|
|
150
|
-
case
|
|
148
|
+
case "in":
|
|
151
149
|
if (Array.isArray(filter.value)) {
|
|
152
|
-
const placeholders = filter.value.map(() =>
|
|
150
|
+
const placeholders = filter.value.map(() => "?").join(", ");
|
|
153
151
|
queryParams.push(...filter.value);
|
|
154
152
|
return `${escapedField} IN (${placeholders})`;
|
|
155
153
|
}
|
|
156
|
-
return
|
|
154
|
+
return "1=1"; // Default true condition if value is not an array
|
|
157
155
|
default:
|
|
158
|
-
return
|
|
156
|
+
return "1=1"; // Default true condition
|
|
159
157
|
}
|
|
160
158
|
});
|
|
161
|
-
whereClause =
|
|
159
|
+
whereClause = "WHERE " + conditions.join(" AND ");
|
|
162
160
|
}
|
|
163
161
|
// Validate all query parameters
|
|
164
162
|
const paramValidation = this.security.validateParameters(queryParams);
|
|
165
163
|
if (!paramValidation.valid) {
|
|
166
164
|
return {
|
|
167
|
-
status:
|
|
168
|
-
error: `Invalid query parameters: ${paramValidation.error}
|
|
165
|
+
status: "error",
|
|
166
|
+
error: `Invalid query parameters: ${paramValidation.error}`,
|
|
169
167
|
};
|
|
170
168
|
}
|
|
171
169
|
// Build the ORDER BY clause if sorting is provided
|
|
172
|
-
let orderByClause =
|
|
170
|
+
let orderByClause = "";
|
|
173
171
|
if (sorting) {
|
|
174
172
|
const escapedSortField = this.security.escapeIdentifier(sorting.field);
|
|
175
173
|
orderByClause = `ORDER BY ${escapedSortField} ${sorting.direction.toUpperCase()}`;
|
|
176
174
|
}
|
|
177
175
|
// Build the LIMIT clause if pagination is provided
|
|
178
|
-
let limitClause =
|
|
176
|
+
let limitClause = "";
|
|
179
177
|
const escapedTableName = this.security.escapeIdentifier(table_name);
|
|
180
178
|
if (pagination) {
|
|
181
179
|
const offset = (pagination.page - 1) * pagination.limit;
|
|
@@ -188,10 +186,9 @@ class CrudTools {
|
|
|
188
186
|
const query = `SELECT * FROM ${escapedTableName} ${whereClause} ${orderByClause} ${limitClause}`;
|
|
189
187
|
const results = await this.db.query(query, paramValidation.sanitizedParams);
|
|
190
188
|
return {
|
|
191
|
-
status:
|
|
189
|
+
status: "success",
|
|
192
190
|
data: results,
|
|
193
191
|
total,
|
|
194
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
195
192
|
};
|
|
196
193
|
}
|
|
197
194
|
else {
|
|
@@ -199,18 +196,16 @@ class CrudTools {
|
|
|
199
196
|
const query = `SELECT * FROM ${escapedTableName} ${whereClause} ${orderByClause}`;
|
|
200
197
|
const results = await this.db.query(query, paramValidation.sanitizedParams);
|
|
201
198
|
return {
|
|
202
|
-
status:
|
|
199
|
+
status: "success",
|
|
203
200
|
data: results,
|
|
204
201
|
total: results.length,
|
|
205
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
206
202
|
};
|
|
207
203
|
}
|
|
208
204
|
}
|
|
209
205
|
catch (error) {
|
|
210
206
|
return {
|
|
211
|
-
status:
|
|
207
|
+
status: "error",
|
|
212
208
|
error: error.message,
|
|
213
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
214
209
|
};
|
|
215
210
|
}
|
|
216
211
|
}
|
|
@@ -221,8 +216,8 @@ class CrudTools {
|
|
|
221
216
|
// Validate input schema
|
|
222
217
|
if (!(0, schemas_1.validateUpdateRecord)(params)) {
|
|
223
218
|
return {
|
|
224
|
-
status:
|
|
225
|
-
error:
|
|
219
|
+
status: "error",
|
|
220
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateUpdateRecord.errors),
|
|
226
221
|
};
|
|
227
222
|
}
|
|
228
223
|
try {
|
|
@@ -231,8 +226,8 @@ class CrudTools {
|
|
|
231
226
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
232
227
|
if (!tableValidation.valid) {
|
|
233
228
|
return {
|
|
234
|
-
status:
|
|
235
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
229
|
+
status: "error",
|
|
230
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
236
231
|
};
|
|
237
232
|
}
|
|
238
233
|
// Validate column names in data
|
|
@@ -241,8 +236,8 @@ class CrudTools {
|
|
|
241
236
|
const columnValidation = this.security.validateIdentifier(column);
|
|
242
237
|
if (!columnValidation.valid) {
|
|
243
238
|
return {
|
|
244
|
-
status:
|
|
245
|
-
error: `Invalid column name '${column}': ${columnValidation.error}
|
|
239
|
+
status: "error",
|
|
240
|
+
error: `Invalid column name '${column}': ${columnValidation.error}`,
|
|
246
241
|
};
|
|
247
242
|
}
|
|
248
243
|
}
|
|
@@ -251,53 +246,53 @@ class CrudTools {
|
|
|
251
246
|
const fieldValidation = this.security.validateIdentifier(condition.field);
|
|
252
247
|
if (!fieldValidation.valid) {
|
|
253
248
|
return {
|
|
254
|
-
status:
|
|
255
|
-
error: `Invalid condition field '${condition.field}': ${fieldValidation.error}
|
|
249
|
+
status: "error",
|
|
250
|
+
error: `Invalid condition field '${condition.field}': ${fieldValidation.error}`,
|
|
256
251
|
};
|
|
257
252
|
}
|
|
258
253
|
}
|
|
259
254
|
// Build SET clause with escaped identifiers
|
|
260
255
|
const setClause = Object.entries(data)
|
|
261
256
|
.map(([column, _]) => `${this.security.escapeIdentifier(column)} = ?`)
|
|
262
|
-
.join(
|
|
257
|
+
.join(", ");
|
|
263
258
|
const setValues = Object.values(data);
|
|
264
259
|
// Build the WHERE clause
|
|
265
260
|
const whereConditions = [];
|
|
266
261
|
const whereValues = [];
|
|
267
|
-
conditions.forEach(condition => {
|
|
262
|
+
conditions.forEach((condition) => {
|
|
268
263
|
const escapedField = this.security.escapeIdentifier(condition.field);
|
|
269
264
|
switch (condition.operator) {
|
|
270
|
-
case
|
|
265
|
+
case "eq":
|
|
271
266
|
whereConditions.push(`${escapedField} = ?`);
|
|
272
267
|
whereValues.push(condition.value);
|
|
273
268
|
break;
|
|
274
|
-
case
|
|
269
|
+
case "neq":
|
|
275
270
|
whereConditions.push(`${escapedField} != ?`);
|
|
276
271
|
whereValues.push(condition.value);
|
|
277
272
|
break;
|
|
278
|
-
case
|
|
273
|
+
case "gt":
|
|
279
274
|
whereConditions.push(`${escapedField} > ?`);
|
|
280
275
|
whereValues.push(condition.value);
|
|
281
276
|
break;
|
|
282
|
-
case
|
|
277
|
+
case "gte":
|
|
283
278
|
whereConditions.push(`${escapedField} >= ?`);
|
|
284
279
|
whereValues.push(condition.value);
|
|
285
280
|
break;
|
|
286
|
-
case
|
|
281
|
+
case "lt":
|
|
287
282
|
whereConditions.push(`${escapedField} < ?`);
|
|
288
283
|
whereValues.push(condition.value);
|
|
289
284
|
break;
|
|
290
|
-
case
|
|
285
|
+
case "lte":
|
|
291
286
|
whereConditions.push(`${escapedField} <= ?`);
|
|
292
287
|
whereValues.push(condition.value);
|
|
293
288
|
break;
|
|
294
|
-
case
|
|
289
|
+
case "like":
|
|
295
290
|
whereConditions.push(`${escapedField} LIKE ?`);
|
|
296
291
|
whereValues.push(`%${condition.value}%`);
|
|
297
292
|
break;
|
|
298
|
-
case
|
|
293
|
+
case "in":
|
|
299
294
|
if (Array.isArray(condition.value)) {
|
|
300
|
-
const placeholders = condition.value.map(() =>
|
|
295
|
+
const placeholders = condition.value.map(() => "?").join(", ");
|
|
301
296
|
whereConditions.push(`${escapedField} IN (${placeholders})`);
|
|
302
297
|
whereValues.push(...condition.value);
|
|
303
298
|
}
|
|
@@ -305,15 +300,15 @@ class CrudTools {
|
|
|
305
300
|
}
|
|
306
301
|
});
|
|
307
302
|
const whereClause = whereConditions.length > 0
|
|
308
|
-
?
|
|
309
|
-
:
|
|
303
|
+
? "WHERE " + whereConditions.join(" AND ")
|
|
304
|
+
: "";
|
|
310
305
|
// Validate all parameters
|
|
311
306
|
const allParams = [...setValues, ...whereValues];
|
|
312
307
|
const paramValidation = this.security.validateParameters(allParams);
|
|
313
308
|
if (!paramValidation.valid) {
|
|
314
309
|
return {
|
|
315
|
-
status:
|
|
316
|
-
error: `Invalid parameters: ${paramValidation.error}
|
|
310
|
+
status: "error",
|
|
311
|
+
error: `Invalid parameters: ${paramValidation.error}`,
|
|
317
312
|
};
|
|
318
313
|
}
|
|
319
314
|
// Build the query with escaped table name
|
|
@@ -322,18 +317,16 @@ class CrudTools {
|
|
|
322
317
|
// Execute the query with sanitized parameters
|
|
323
318
|
const result = await this.db.query(query, paramValidation.sanitizedParams);
|
|
324
319
|
return {
|
|
325
|
-
status:
|
|
320
|
+
status: "success",
|
|
326
321
|
data: {
|
|
327
|
-
affectedRows: result.affectedRows
|
|
322
|
+
affectedRows: result.affectedRows,
|
|
328
323
|
},
|
|
329
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
330
324
|
};
|
|
331
325
|
}
|
|
332
326
|
catch (error) {
|
|
333
327
|
return {
|
|
334
|
-
status:
|
|
328
|
+
status: "error",
|
|
335
329
|
error: error.message,
|
|
336
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
337
330
|
};
|
|
338
331
|
}
|
|
339
332
|
}
|
|
@@ -344,8 +337,8 @@ class CrudTools {
|
|
|
344
337
|
// Validate input schema
|
|
345
338
|
if (!(0, schemas_1.validateDeleteRecord)(params)) {
|
|
346
339
|
return {
|
|
347
|
-
status:
|
|
348
|
-
error:
|
|
340
|
+
status: "error",
|
|
341
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateDeleteRecord.errors),
|
|
349
342
|
};
|
|
350
343
|
}
|
|
351
344
|
try {
|
|
@@ -354,15 +347,15 @@ class CrudTools {
|
|
|
354
347
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
355
348
|
if (!tableValidation.valid) {
|
|
356
349
|
return {
|
|
357
|
-
status:
|
|
358
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
350
|
+
status: "error",
|
|
351
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
359
352
|
};
|
|
360
353
|
}
|
|
361
354
|
// Ensure there are conditions for safety
|
|
362
355
|
if (!conditions || conditions.length === 0) {
|
|
363
356
|
return {
|
|
364
|
-
status:
|
|
365
|
-
error:
|
|
357
|
+
status: "error",
|
|
358
|
+
error: "DELETE operations require at least one condition for safety",
|
|
366
359
|
};
|
|
367
360
|
}
|
|
368
361
|
// Validate condition fields
|
|
@@ -370,61 +363,61 @@ class CrudTools {
|
|
|
370
363
|
const fieldValidation = this.security.validateIdentifier(condition.field);
|
|
371
364
|
if (!fieldValidation.valid) {
|
|
372
365
|
return {
|
|
373
|
-
status:
|
|
374
|
-
error: `Invalid condition field '${condition.field}': ${fieldValidation.error}
|
|
366
|
+
status: "error",
|
|
367
|
+
error: `Invalid condition field '${condition.field}': ${fieldValidation.error}`,
|
|
375
368
|
};
|
|
376
369
|
}
|
|
377
370
|
}
|
|
378
371
|
// Build the WHERE clause
|
|
379
372
|
const whereConditions = [];
|
|
380
373
|
const whereValues = [];
|
|
381
|
-
conditions.forEach(condition => {
|
|
374
|
+
conditions.forEach((condition) => {
|
|
382
375
|
const escapedField = this.security.escapeIdentifier(condition.field);
|
|
383
376
|
switch (condition.operator) {
|
|
384
|
-
case
|
|
377
|
+
case "eq":
|
|
385
378
|
whereConditions.push(`${escapedField} = ?`);
|
|
386
379
|
whereValues.push(condition.value);
|
|
387
380
|
break;
|
|
388
|
-
case
|
|
381
|
+
case "neq":
|
|
389
382
|
whereConditions.push(`${escapedField} != ?`);
|
|
390
383
|
whereValues.push(condition.value);
|
|
391
384
|
break;
|
|
392
|
-
case
|
|
385
|
+
case "gt":
|
|
393
386
|
whereConditions.push(`${escapedField} > ?`);
|
|
394
387
|
whereValues.push(condition.value);
|
|
395
388
|
break;
|
|
396
|
-
case
|
|
389
|
+
case "gte":
|
|
397
390
|
whereConditions.push(`${escapedField} >= ?`);
|
|
398
391
|
whereValues.push(condition.value);
|
|
399
392
|
break;
|
|
400
|
-
case
|
|
393
|
+
case "lt":
|
|
401
394
|
whereConditions.push(`${escapedField} < ?`);
|
|
402
395
|
whereValues.push(condition.value);
|
|
403
396
|
break;
|
|
404
|
-
case
|
|
397
|
+
case "lte":
|
|
405
398
|
whereConditions.push(`${escapedField} <= ?`);
|
|
406
399
|
whereValues.push(condition.value);
|
|
407
400
|
break;
|
|
408
|
-
case
|
|
401
|
+
case "like":
|
|
409
402
|
whereConditions.push(`${escapedField} LIKE ?`);
|
|
410
403
|
whereValues.push(`%${condition.value}%`);
|
|
411
404
|
break;
|
|
412
|
-
case
|
|
405
|
+
case "in":
|
|
413
406
|
if (Array.isArray(condition.value)) {
|
|
414
|
-
const placeholders = condition.value.map(() =>
|
|
407
|
+
const placeholders = condition.value.map(() => "?").join(", ");
|
|
415
408
|
whereConditions.push(`${escapedField} IN (${placeholders})`);
|
|
416
409
|
whereValues.push(...condition.value);
|
|
417
410
|
}
|
|
418
411
|
break;
|
|
419
412
|
}
|
|
420
413
|
});
|
|
421
|
-
const whereClause =
|
|
414
|
+
const whereClause = "WHERE " + whereConditions.join(" AND ");
|
|
422
415
|
// Validate all parameters
|
|
423
416
|
const paramValidation = this.security.validateParameters(whereValues);
|
|
424
417
|
if (!paramValidation.valid) {
|
|
425
418
|
return {
|
|
426
|
-
status:
|
|
427
|
-
error: `Invalid parameters: ${paramValidation.error}
|
|
419
|
+
status: "error",
|
|
420
|
+
error: `Invalid parameters: ${paramValidation.error}`,
|
|
428
421
|
};
|
|
429
422
|
}
|
|
430
423
|
// Build the query with escaped table name
|
|
@@ -433,18 +426,16 @@ class CrudTools {
|
|
|
433
426
|
// Execute the query with sanitized parameters
|
|
434
427
|
const result = await this.db.query(query, paramValidation.sanitizedParams);
|
|
435
428
|
return {
|
|
436
|
-
status:
|
|
429
|
+
status: "success",
|
|
437
430
|
data: {
|
|
438
|
-
affectedRows: result.affectedRows
|
|
431
|
+
affectedRows: result.affectedRows,
|
|
439
432
|
},
|
|
440
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
441
433
|
};
|
|
442
434
|
}
|
|
443
435
|
catch (error) {
|
|
444
436
|
return {
|
|
445
|
-
status:
|
|
437
|
+
status: "error",
|
|
446
438
|
error: error.message,
|
|
447
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
448
439
|
};
|
|
449
440
|
}
|
|
450
441
|
}
|
|
@@ -455,8 +446,8 @@ class CrudTools {
|
|
|
455
446
|
// Validate input schema
|
|
456
447
|
if (!(0, schemas_1.validateBulkInsert)(params)) {
|
|
457
448
|
return {
|
|
458
|
-
status:
|
|
459
|
-
error:
|
|
449
|
+
status: "error",
|
|
450
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateBulkInsert.errors),
|
|
460
451
|
};
|
|
461
452
|
}
|
|
462
453
|
try {
|
|
@@ -465,15 +456,15 @@ class CrudTools {
|
|
|
465
456
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
466
457
|
if (!tableValidation.valid) {
|
|
467
458
|
return {
|
|
468
|
-
status:
|
|
469
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
459
|
+
status: "error",
|
|
460
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
470
461
|
};
|
|
471
462
|
}
|
|
472
463
|
// Ensure data is not empty
|
|
473
464
|
if (!data || data.length === 0) {
|
|
474
465
|
return {
|
|
475
|
-
status:
|
|
476
|
-
error:
|
|
466
|
+
status: "error",
|
|
467
|
+
error: "Data array cannot be empty",
|
|
477
468
|
};
|
|
478
469
|
}
|
|
479
470
|
// Validate that all records have the same columns
|
|
@@ -482,10 +473,10 @@ class CrudTools {
|
|
|
482
473
|
for (let i = 1; i < data.length; i++) {
|
|
483
474
|
const recordColumns = Object.keys(data[i]);
|
|
484
475
|
if (recordColumns.length !== columns.length ||
|
|
485
|
-
!recordColumns.every(col => columns.includes(col))) {
|
|
476
|
+
!recordColumns.every((col) => columns.includes(col))) {
|
|
486
477
|
return {
|
|
487
|
-
status:
|
|
488
|
-
error: `All records must have the same columns. Record ${i + 1} has different columns
|
|
478
|
+
status: "error",
|
|
479
|
+
error: `All records must have the same columns. Record ${i + 1} has different columns.`,
|
|
489
480
|
};
|
|
490
481
|
}
|
|
491
482
|
}
|
|
@@ -494,8 +485,8 @@ class CrudTools {
|
|
|
494
485
|
const columnValidation = this.security.validateIdentifier(column);
|
|
495
486
|
if (!columnValidation.valid) {
|
|
496
487
|
return {
|
|
497
|
-
status:
|
|
498
|
-
error: `Invalid column name '${column}': ${columnValidation.error}
|
|
488
|
+
status: "error",
|
|
489
|
+
error: `Invalid column name '${column}': ${columnValidation.error}`,
|
|
499
490
|
};
|
|
500
491
|
}
|
|
501
492
|
}
|
|
@@ -507,46 +498,48 @@ class CrudTools {
|
|
|
507
498
|
// Prepare batch values
|
|
508
499
|
const batchValues = [];
|
|
509
500
|
for (const record of batch) {
|
|
510
|
-
const values = columns.map(col => record[col]);
|
|
501
|
+
const values = columns.map((col) => record[col]);
|
|
511
502
|
// Validate and sanitize parameter values for this record
|
|
512
503
|
const paramValidation = this.security.validateParameters(values);
|
|
513
504
|
if (!paramValidation.valid) {
|
|
514
505
|
return {
|
|
515
|
-
status:
|
|
516
|
-
error: `Invalid parameter values in record ${i + batchValues.length / columns.length + 1}: ${paramValidation.error}
|
|
506
|
+
status: "error",
|
|
507
|
+
error: `Invalid parameter values in record ${i + batchValues.length / columns.length + 1}: ${paramValidation.error}`,
|
|
517
508
|
};
|
|
518
509
|
}
|
|
519
510
|
batchValues.push(...paramValidation.sanitizedParams);
|
|
520
511
|
}
|
|
521
512
|
// Build the query with escaped identifiers
|
|
522
513
|
const escapedTableName = this.security.escapeIdentifier(table_name);
|
|
523
|
-
const escapedColumns = columns.map(col => this.security.escapeIdentifier(col));
|
|
524
|
-
const valueGroups = batch
|
|
525
|
-
|
|
514
|
+
const escapedColumns = columns.map((col) => this.security.escapeIdentifier(col));
|
|
515
|
+
const valueGroups = batch
|
|
516
|
+
.map(() => `(${columns.map(() => "?").join(", ")})`)
|
|
517
|
+
.join(", ");
|
|
518
|
+
const query = `INSERT INTO ${escapedTableName} (${escapedColumns.join(", ")}) VALUES ${valueGroups}`;
|
|
526
519
|
// Execute the batch query
|
|
527
520
|
const result = await this.db.query(query, batchValues);
|
|
528
521
|
results.push({
|
|
529
522
|
batchNumber: Math.floor(i / batch_size) + 1,
|
|
530
523
|
recordsInserted: batch.length,
|
|
531
524
|
firstInsertId: result.insertId,
|
|
532
|
-
affectedRows: result.affectedRows
|
|
525
|
+
affectedRows: result.affectedRows,
|
|
533
526
|
});
|
|
534
527
|
totalInserted += result.affectedRows;
|
|
535
528
|
}
|
|
536
529
|
return {
|
|
537
|
-
status:
|
|
530
|
+
status: "success",
|
|
538
531
|
data: {
|
|
539
532
|
totalRecords: data.length,
|
|
540
533
|
totalInserted,
|
|
541
534
|
batches: results.length,
|
|
542
|
-
batchResults: results
|
|
543
|
-
}
|
|
535
|
+
batchResults: results,
|
|
536
|
+
},
|
|
544
537
|
};
|
|
545
538
|
}
|
|
546
539
|
catch (error) {
|
|
547
540
|
return {
|
|
548
|
-
status:
|
|
549
|
-
error: error.message
|
|
541
|
+
status: "error",
|
|
542
|
+
error: error.message,
|
|
550
543
|
};
|
|
551
544
|
}
|
|
552
545
|
}
|
|
@@ -557,8 +550,8 @@ class CrudTools {
|
|
|
557
550
|
// Validate input schema
|
|
558
551
|
if (!(0, schemas_1.validateBulkUpdate)(params)) {
|
|
559
552
|
return {
|
|
560
|
-
status:
|
|
561
|
-
error:
|
|
553
|
+
status: "error",
|
|
554
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateBulkUpdate.errors),
|
|
562
555
|
};
|
|
563
556
|
}
|
|
564
557
|
try {
|
|
@@ -567,15 +560,15 @@ class CrudTools {
|
|
|
567
560
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
568
561
|
if (!tableValidation.valid) {
|
|
569
562
|
return {
|
|
570
|
-
status:
|
|
571
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
563
|
+
status: "error",
|
|
564
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
572
565
|
};
|
|
573
566
|
}
|
|
574
567
|
// Ensure updates is not empty
|
|
575
568
|
if (!updates || updates.length === 0) {
|
|
576
569
|
return {
|
|
577
|
-
status:
|
|
578
|
-
error:
|
|
570
|
+
status: "error",
|
|
571
|
+
error: "Updates array cannot be empty",
|
|
579
572
|
};
|
|
580
573
|
}
|
|
581
574
|
// Validate each update operation
|
|
@@ -587,8 +580,8 @@ class CrudTools {
|
|
|
587
580
|
const columnValidation = this.security.validateIdentifier(column);
|
|
588
581
|
if (!columnValidation.valid) {
|
|
589
582
|
return {
|
|
590
|
-
status:
|
|
591
|
-
error: `Invalid column name '${column}' in update ${i + 1}: ${columnValidation.error}
|
|
583
|
+
status: "error",
|
|
584
|
+
error: `Invalid column name '${column}' in update ${i + 1}: ${columnValidation.error}`,
|
|
592
585
|
};
|
|
593
586
|
}
|
|
594
587
|
}
|
|
@@ -597,8 +590,8 @@ class CrudTools {
|
|
|
597
590
|
const fieldValidation = this.security.validateIdentifier(condition.field);
|
|
598
591
|
if (!fieldValidation.valid) {
|
|
599
592
|
return {
|
|
600
|
-
status:
|
|
601
|
-
error: `Invalid condition field '${condition.field}' in update ${i + 1}: ${fieldValidation.error}
|
|
593
|
+
status: "error",
|
|
594
|
+
error: `Invalid condition field '${condition.field}' in update ${i + 1}: ${fieldValidation.error}`,
|
|
602
595
|
};
|
|
603
596
|
}
|
|
604
597
|
}
|
|
@@ -609,52 +602,54 @@ class CrudTools {
|
|
|
609
602
|
for (let i = 0; i < updates.length; i += batch_size) {
|
|
610
603
|
const batch = updates.slice(i, i + batch_size);
|
|
611
604
|
// Start a transaction for this batch
|
|
612
|
-
await this.db.query(
|
|
605
|
+
await this.db.query("START TRANSACTION");
|
|
613
606
|
try {
|
|
614
607
|
const batchResults = [];
|
|
615
608
|
for (const update of batch) {
|
|
616
609
|
// Build SET clause
|
|
617
610
|
const setClause = Object.entries(update.data)
|
|
618
611
|
.map(([column, _]) => `${this.security.escapeIdentifier(column)} = ?`)
|
|
619
|
-
.join(
|
|
612
|
+
.join(", ");
|
|
620
613
|
const setValues = Object.values(update.data);
|
|
621
614
|
// Build WHERE clause
|
|
622
615
|
const whereConditions = [];
|
|
623
616
|
const whereValues = [];
|
|
624
|
-
update.conditions.forEach(condition => {
|
|
617
|
+
update.conditions.forEach((condition) => {
|
|
625
618
|
const escapedField = this.security.escapeIdentifier(condition.field);
|
|
626
619
|
switch (condition.operator) {
|
|
627
|
-
case
|
|
620
|
+
case "eq":
|
|
628
621
|
whereConditions.push(`${escapedField} = ?`);
|
|
629
622
|
whereValues.push(condition.value);
|
|
630
623
|
break;
|
|
631
|
-
case
|
|
624
|
+
case "neq":
|
|
632
625
|
whereConditions.push(`${escapedField} != ?`);
|
|
633
626
|
whereValues.push(condition.value);
|
|
634
627
|
break;
|
|
635
|
-
case
|
|
628
|
+
case "gt":
|
|
636
629
|
whereConditions.push(`${escapedField} > ?`);
|
|
637
630
|
whereValues.push(condition.value);
|
|
638
631
|
break;
|
|
639
|
-
case
|
|
632
|
+
case "gte":
|
|
640
633
|
whereConditions.push(`${escapedField} >= ?`);
|
|
641
634
|
whereValues.push(condition.value);
|
|
642
635
|
break;
|
|
643
|
-
case
|
|
636
|
+
case "lt":
|
|
644
637
|
whereConditions.push(`${escapedField} < ?`);
|
|
645
638
|
whereValues.push(condition.value);
|
|
646
639
|
break;
|
|
647
|
-
case
|
|
640
|
+
case "lte":
|
|
648
641
|
whereConditions.push(`${escapedField} <= ?`);
|
|
649
642
|
whereValues.push(condition.value);
|
|
650
643
|
break;
|
|
651
|
-
case
|
|
644
|
+
case "like":
|
|
652
645
|
whereConditions.push(`${escapedField} LIKE ?`);
|
|
653
646
|
whereValues.push(`%${condition.value}%`);
|
|
654
647
|
break;
|
|
655
|
-
case
|
|
648
|
+
case "in":
|
|
656
649
|
if (Array.isArray(condition.value)) {
|
|
657
|
-
const placeholders = condition.value
|
|
650
|
+
const placeholders = condition.value
|
|
651
|
+
.map(() => "?")
|
|
652
|
+
.join(", ");
|
|
658
653
|
whereConditions.push(`${escapedField} IN (${placeholders})`);
|
|
659
654
|
whereValues.push(...condition.value);
|
|
660
655
|
}
|
|
@@ -662,8 +657,8 @@ class CrudTools {
|
|
|
662
657
|
}
|
|
663
658
|
});
|
|
664
659
|
const whereClause = whereConditions.length > 0
|
|
665
|
-
?
|
|
666
|
-
:
|
|
660
|
+
? "WHERE " + whereConditions.join(" AND ")
|
|
661
|
+
: "";
|
|
667
662
|
// Validate all parameters
|
|
668
663
|
const allParams = [...setValues, ...whereValues];
|
|
669
664
|
const paramValidation = this.security.validateParameters(allParams);
|
|
@@ -675,38 +670,38 @@ class CrudTools {
|
|
|
675
670
|
const query = `UPDATE ${escapedTableName} SET ${setClause} ${whereClause}`;
|
|
676
671
|
const result = await this.db.query(query, paramValidation.sanitizedParams);
|
|
677
672
|
batchResults.push({
|
|
678
|
-
affectedRows: result.affectedRows
|
|
673
|
+
affectedRows: result.affectedRows,
|
|
679
674
|
});
|
|
680
675
|
totalAffected += result.affectedRows;
|
|
681
676
|
}
|
|
682
677
|
// Commit the transaction
|
|
683
|
-
await this.db.query(
|
|
678
|
+
await this.db.query("COMMIT");
|
|
684
679
|
results.push({
|
|
685
680
|
batchNumber: Math.floor(i / batch_size) + 1,
|
|
686
681
|
updatesProcessed: batch.length,
|
|
687
|
-
results: batchResults
|
|
682
|
+
results: batchResults,
|
|
688
683
|
});
|
|
689
684
|
}
|
|
690
685
|
catch (error) {
|
|
691
686
|
// Rollback on error
|
|
692
|
-
await this.db.query(
|
|
687
|
+
await this.db.query("ROLLBACK");
|
|
693
688
|
throw error;
|
|
694
689
|
}
|
|
695
690
|
}
|
|
696
691
|
return {
|
|
697
|
-
status:
|
|
692
|
+
status: "success",
|
|
698
693
|
data: {
|
|
699
694
|
totalUpdates: updates.length,
|
|
700
695
|
totalAffectedRows: totalAffected,
|
|
701
696
|
batches: results.length,
|
|
702
|
-
batchResults: results
|
|
703
|
-
}
|
|
697
|
+
batchResults: results,
|
|
698
|
+
},
|
|
704
699
|
};
|
|
705
700
|
}
|
|
706
701
|
catch (error) {
|
|
707
702
|
return {
|
|
708
|
-
status:
|
|
709
|
-
error: error.message
|
|
703
|
+
status: "error",
|
|
704
|
+
error: error.message,
|
|
710
705
|
};
|
|
711
706
|
}
|
|
712
707
|
}
|
|
@@ -717,8 +712,8 @@ class CrudTools {
|
|
|
717
712
|
// Validate input schema
|
|
718
713
|
if (!(0, schemas_1.validateBulkDelete)(params)) {
|
|
719
714
|
return {
|
|
720
|
-
status:
|
|
721
|
-
error:
|
|
715
|
+
status: "error",
|
|
716
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateBulkDelete.errors),
|
|
722
717
|
};
|
|
723
718
|
}
|
|
724
719
|
try {
|
|
@@ -727,15 +722,15 @@ class CrudTools {
|
|
|
727
722
|
const tableValidation = this.security.validateIdentifier(table_name);
|
|
728
723
|
if (!tableValidation.valid) {
|
|
729
724
|
return {
|
|
730
|
-
status:
|
|
731
|
-
error: `Invalid table name: ${tableValidation.error}
|
|
725
|
+
status: "error",
|
|
726
|
+
error: `Invalid table name: ${tableValidation.error}`,
|
|
732
727
|
};
|
|
733
728
|
}
|
|
734
729
|
// Ensure condition_sets is not empty
|
|
735
730
|
if (!condition_sets || condition_sets.length === 0) {
|
|
736
731
|
return {
|
|
737
|
-
status:
|
|
738
|
-
error:
|
|
732
|
+
status: "error",
|
|
733
|
+
error: "Condition sets array cannot be empty",
|
|
739
734
|
};
|
|
740
735
|
}
|
|
741
736
|
// Validate each condition set
|
|
@@ -744,8 +739,8 @@ class CrudTools {
|
|
|
744
739
|
// Ensure there are conditions for safety
|
|
745
740
|
if (!conditions || conditions.length === 0) {
|
|
746
741
|
return {
|
|
747
|
-
status:
|
|
748
|
-
error: `DELETE operations require at least one condition for safety. Condition set ${i + 1} is empty
|
|
742
|
+
status: "error",
|
|
743
|
+
error: `DELETE operations require at least one condition for safety. Condition set ${i + 1} is empty.`,
|
|
749
744
|
};
|
|
750
745
|
}
|
|
751
746
|
// Validate condition fields
|
|
@@ -753,8 +748,8 @@ class CrudTools {
|
|
|
753
748
|
const fieldValidation = this.security.validateIdentifier(condition.field);
|
|
754
749
|
if (!fieldValidation.valid) {
|
|
755
750
|
return {
|
|
756
|
-
status:
|
|
757
|
-
error: `Invalid condition field '${condition.field}' in condition set ${i + 1}: ${fieldValidation.error}
|
|
751
|
+
status: "error",
|
|
752
|
+
error: `Invalid condition field '${condition.field}' in condition set ${i + 1}: ${fieldValidation.error}`,
|
|
758
753
|
};
|
|
759
754
|
}
|
|
760
755
|
}
|
|
@@ -765,54 +760,56 @@ class CrudTools {
|
|
|
765
760
|
for (let i = 0; i < condition_sets.length; i += batch_size) {
|
|
766
761
|
const batch = condition_sets.slice(i, i + batch_size);
|
|
767
762
|
// Start a transaction for this batch
|
|
768
|
-
await this.db.query(
|
|
763
|
+
await this.db.query("START TRANSACTION");
|
|
769
764
|
try {
|
|
770
765
|
const batchResults = [];
|
|
771
766
|
for (const conditions of batch) {
|
|
772
767
|
// Build WHERE clause
|
|
773
768
|
const whereConditions = [];
|
|
774
769
|
const whereValues = [];
|
|
775
|
-
conditions.forEach(condition => {
|
|
770
|
+
conditions.forEach((condition) => {
|
|
776
771
|
const escapedField = this.security.escapeIdentifier(condition.field);
|
|
777
772
|
switch (condition.operator) {
|
|
778
|
-
case
|
|
773
|
+
case "eq":
|
|
779
774
|
whereConditions.push(`${escapedField} = ?`);
|
|
780
775
|
whereValues.push(condition.value);
|
|
781
776
|
break;
|
|
782
|
-
case
|
|
777
|
+
case "neq":
|
|
783
778
|
whereConditions.push(`${escapedField} != ?`);
|
|
784
779
|
whereValues.push(condition.value);
|
|
785
780
|
break;
|
|
786
|
-
case
|
|
781
|
+
case "gt":
|
|
787
782
|
whereConditions.push(`${escapedField} > ?`);
|
|
788
783
|
whereValues.push(condition.value);
|
|
789
784
|
break;
|
|
790
|
-
case
|
|
785
|
+
case "gte":
|
|
791
786
|
whereConditions.push(`${escapedField} >= ?`);
|
|
792
787
|
whereValues.push(condition.value);
|
|
793
788
|
break;
|
|
794
|
-
case
|
|
789
|
+
case "lt":
|
|
795
790
|
whereConditions.push(`${escapedField} < ?`);
|
|
796
791
|
whereValues.push(condition.value);
|
|
797
792
|
break;
|
|
798
|
-
case
|
|
793
|
+
case "lte":
|
|
799
794
|
whereConditions.push(`${escapedField} <= ?`);
|
|
800
795
|
whereValues.push(condition.value);
|
|
801
796
|
break;
|
|
802
|
-
case
|
|
797
|
+
case "like":
|
|
803
798
|
whereConditions.push(`${escapedField} LIKE ?`);
|
|
804
799
|
whereValues.push(`%${condition.value}%`);
|
|
805
800
|
break;
|
|
806
|
-
case
|
|
801
|
+
case "in":
|
|
807
802
|
if (Array.isArray(condition.value)) {
|
|
808
|
-
const placeholders = condition.value
|
|
803
|
+
const placeholders = condition.value
|
|
804
|
+
.map(() => "?")
|
|
805
|
+
.join(", ");
|
|
809
806
|
whereConditions.push(`${escapedField} IN (${placeholders})`);
|
|
810
807
|
whereValues.push(...condition.value);
|
|
811
808
|
}
|
|
812
809
|
break;
|
|
813
810
|
}
|
|
814
811
|
});
|
|
815
|
-
const whereClause =
|
|
812
|
+
const whereClause = "WHERE " + whereConditions.join(" AND ");
|
|
816
813
|
// Validate all parameters
|
|
817
814
|
const paramValidation = this.security.validateParameters(whereValues);
|
|
818
815
|
if (!paramValidation.valid) {
|
|
@@ -823,38 +820,38 @@ class CrudTools {
|
|
|
823
820
|
const query = `DELETE FROM ${escapedTableName} ${whereClause}`;
|
|
824
821
|
const result = await this.db.query(query, paramValidation.sanitizedParams);
|
|
825
822
|
batchResults.push({
|
|
826
|
-
affectedRows: result.affectedRows
|
|
823
|
+
affectedRows: result.affectedRows,
|
|
827
824
|
});
|
|
828
825
|
totalDeleted += result.affectedRows;
|
|
829
826
|
}
|
|
830
827
|
// Commit the transaction
|
|
831
|
-
await this.db.query(
|
|
828
|
+
await this.db.query("COMMIT");
|
|
832
829
|
results.push({
|
|
833
830
|
batchNumber: Math.floor(i / batch_size) + 1,
|
|
834
831
|
deletesProcessed: batch.length,
|
|
835
|
-
results: batchResults
|
|
832
|
+
results: batchResults,
|
|
836
833
|
});
|
|
837
834
|
}
|
|
838
835
|
catch (error) {
|
|
839
836
|
// Rollback on error
|
|
840
|
-
await this.db.query(
|
|
837
|
+
await this.db.query("ROLLBACK");
|
|
841
838
|
throw error;
|
|
842
839
|
}
|
|
843
840
|
}
|
|
844
841
|
return {
|
|
845
|
-
status:
|
|
842
|
+
status: "success",
|
|
846
843
|
data: {
|
|
847
844
|
totalDeletes: condition_sets.length,
|
|
848
845
|
totalDeletedRows: totalDeleted,
|
|
849
846
|
batches: results.length,
|
|
850
|
-
batchResults: results
|
|
851
|
-
}
|
|
847
|
+
batchResults: results,
|
|
848
|
+
},
|
|
852
849
|
};
|
|
853
850
|
}
|
|
854
851
|
catch (error) {
|
|
855
852
|
return {
|
|
856
|
-
status:
|
|
857
|
-
error: error.message
|
|
853
|
+
status: "error",
|
|
854
|
+
error: error.message,
|
|
858
855
|
};
|
|
859
856
|
}
|
|
860
857
|
}
|