@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SecurityLayer } from
|
|
1
|
+
import { SecurityLayer } from "../security/securityLayer";
|
|
2
2
|
export declare class StoredProcedureTools {
|
|
3
3
|
private db;
|
|
4
4
|
private security;
|
|
@@ -16,7 +16,6 @@ export declare class StoredProcedureTools {
|
|
|
16
16
|
status: string;
|
|
17
17
|
data?: any[];
|
|
18
18
|
error?: string;
|
|
19
|
-
queryLog?: string;
|
|
20
19
|
}>;
|
|
21
20
|
/**
|
|
22
21
|
* Get detailed information about a specific stored procedure
|
|
@@ -28,7 +27,6 @@ export declare class StoredProcedureTools {
|
|
|
28
27
|
status: string;
|
|
29
28
|
data?: any;
|
|
30
29
|
error?: string;
|
|
31
|
-
queryLog?: string;
|
|
32
30
|
}>;
|
|
33
31
|
/**
|
|
34
32
|
* Execute a stored procedure with parameters
|
|
@@ -49,7 +47,7 @@ export declare class StoredProcedureTools {
|
|
|
49
47
|
procedure_name: string;
|
|
50
48
|
parameters?: Array<{
|
|
51
49
|
name: string;
|
|
52
|
-
mode:
|
|
50
|
+
mode: "IN" | "OUT" | "INOUT";
|
|
53
51
|
data_type: string;
|
|
54
52
|
}>;
|
|
55
53
|
body: string;
|
|
@@ -20,28 +20,28 @@ class StoredProcedureTools {
|
|
|
20
20
|
if (!connectedDatabase) {
|
|
21
21
|
return {
|
|
22
22
|
valid: false,
|
|
23
|
-
database:
|
|
24
|
-
error:
|
|
23
|
+
database: "",
|
|
24
|
+
error: "No database specified in connection string. Cannot access any database.",
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
// If no database is requested, use the connected database
|
|
28
28
|
if (!requestedDatabase) {
|
|
29
29
|
return {
|
|
30
30
|
valid: true,
|
|
31
|
-
database: connectedDatabase
|
|
31
|
+
database: connectedDatabase,
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
// If a specific database is requested, ensure it matches the connected database
|
|
35
35
|
if (requestedDatabase !== connectedDatabase) {
|
|
36
36
|
return {
|
|
37
37
|
valid: false,
|
|
38
|
-
database:
|
|
39
|
-
error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed
|
|
38
|
+
database: "",
|
|
39
|
+
error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed.`,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
return {
|
|
43
43
|
valid: true,
|
|
44
|
-
database: connectedDatabase
|
|
44
|
+
database: connectedDatabase,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
@@ -52,47 +52,46 @@ class StoredProcedureTools {
|
|
|
52
52
|
// Validate input
|
|
53
53
|
if (!(0, schemas_1.validateListStoredProcedures)(params)) {
|
|
54
54
|
return {
|
|
55
|
-
status:
|
|
56
|
-
error:
|
|
55
|
+
status: "error",
|
|
56
|
+
error: "Invalid parameters: " +
|
|
57
|
+
JSON.stringify(schemas_1.validateListStoredProcedures.errors),
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
// Validate database access
|
|
60
61
|
const dbValidation = this.validateDatabaseAccess(params.database);
|
|
61
62
|
if (!dbValidation.valid) {
|
|
62
63
|
return {
|
|
63
|
-
status:
|
|
64
|
-
error: dbValidation.error
|
|
64
|
+
status: "error",
|
|
65
|
+
error: dbValidation.error,
|
|
65
66
|
};
|
|
66
67
|
}
|
|
67
68
|
const database = dbValidation.database;
|
|
68
|
-
const query = `
|
|
69
|
-
SELECT
|
|
70
|
-
ROUTINE_NAME as name,
|
|
71
|
-
ROUTINE_TYPE as type,
|
|
72
|
-
DATA_TYPE as return_type,
|
|
73
|
-
ROUTINE_DEFINITION as definition,
|
|
74
|
-
CREATED,
|
|
75
|
-
LAST_ALTERED,
|
|
76
|
-
ROUTINE_COMMENT as comment,
|
|
77
|
-
DEFINER,
|
|
78
|
-
SQL_MODE,
|
|
79
|
-
SECURITY_TYPE
|
|
80
|
-
FROM INFORMATION_SCHEMA.ROUTINES
|
|
81
|
-
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_TYPE = 'PROCEDURE'
|
|
82
|
-
ORDER BY ROUTINE_NAME
|
|
69
|
+
const query = `
|
|
70
|
+
SELECT
|
|
71
|
+
ROUTINE_NAME as name,
|
|
72
|
+
ROUTINE_TYPE as type,
|
|
73
|
+
DATA_TYPE as return_type,
|
|
74
|
+
ROUTINE_DEFINITION as definition,
|
|
75
|
+
CREATED,
|
|
76
|
+
LAST_ALTERED,
|
|
77
|
+
ROUTINE_COMMENT as comment,
|
|
78
|
+
DEFINER,
|
|
79
|
+
SQL_MODE,
|
|
80
|
+
SECURITY_TYPE
|
|
81
|
+
FROM INFORMATION_SCHEMA.ROUTINES
|
|
82
|
+
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_TYPE = 'PROCEDURE'
|
|
83
|
+
ORDER BY ROUTINE_NAME
|
|
83
84
|
`;
|
|
84
85
|
const results = await this.db.query(query, [database]);
|
|
85
86
|
return {
|
|
86
|
-
status:
|
|
87
|
+
status: "success",
|
|
87
88
|
data: results,
|
|
88
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
92
92
|
return {
|
|
93
|
-
status:
|
|
93
|
+
status: "error",
|
|
94
94
|
error: error.message,
|
|
95
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
96
95
|
};
|
|
97
96
|
}
|
|
98
97
|
}
|
|
@@ -104,76 +103,74 @@ class StoredProcedureTools {
|
|
|
104
103
|
// Validate input
|
|
105
104
|
if (!(0, schemas_1.validateGetStoredProcedureInfo)(params)) {
|
|
106
105
|
return {
|
|
107
|
-
status:
|
|
108
|
-
error:
|
|
106
|
+
status: "error",
|
|
107
|
+
error: "Invalid parameters: " +
|
|
108
|
+
JSON.stringify(schemas_1.validateGetStoredProcedureInfo.errors),
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
111
|
// Validate database access
|
|
112
112
|
const dbValidation = this.validateDatabaseAccess(params.database);
|
|
113
113
|
if (!dbValidation.valid) {
|
|
114
114
|
return {
|
|
115
|
-
status:
|
|
116
|
-
error: dbValidation.error
|
|
115
|
+
status: "error",
|
|
116
|
+
error: dbValidation.error,
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
const { procedure_name } = params;
|
|
120
120
|
const database = dbValidation.database;
|
|
121
121
|
// Get procedure information
|
|
122
|
-
const procedureQuery = `
|
|
123
|
-
SELECT
|
|
124
|
-
ROUTINE_NAME as name,
|
|
125
|
-
ROUTINE_TYPE as type,
|
|
126
|
-
DATA_TYPE as return_type,
|
|
127
|
-
ROUTINE_DEFINITION as definition,
|
|
128
|
-
CREATED,
|
|
129
|
-
LAST_ALTERED,
|
|
130
|
-
ROUTINE_COMMENT as comment,
|
|
131
|
-
DEFINER,
|
|
132
|
-
SQL_MODE,
|
|
133
|
-
SECURITY_TYPE,
|
|
134
|
-
IS_DETERMINISTIC,
|
|
135
|
-
SQL_DATA_ACCESS,
|
|
136
|
-
ROUTINE_BODY
|
|
137
|
-
FROM INFORMATION_SCHEMA.ROUTINES
|
|
138
|
-
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ? AND ROUTINE_TYPE = 'PROCEDURE'
|
|
122
|
+
const procedureQuery = `
|
|
123
|
+
SELECT
|
|
124
|
+
ROUTINE_NAME as name,
|
|
125
|
+
ROUTINE_TYPE as type,
|
|
126
|
+
DATA_TYPE as return_type,
|
|
127
|
+
ROUTINE_DEFINITION as definition,
|
|
128
|
+
CREATED,
|
|
129
|
+
LAST_ALTERED,
|
|
130
|
+
ROUTINE_COMMENT as comment,
|
|
131
|
+
DEFINER,
|
|
132
|
+
SQL_MODE,
|
|
133
|
+
SECURITY_TYPE,
|
|
134
|
+
IS_DETERMINISTIC,
|
|
135
|
+
SQL_DATA_ACCESS,
|
|
136
|
+
ROUTINE_BODY
|
|
137
|
+
FROM INFORMATION_SCHEMA.ROUTINES
|
|
138
|
+
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ? AND ROUTINE_TYPE = 'PROCEDURE'
|
|
139
139
|
`;
|
|
140
140
|
// Get procedure parameters
|
|
141
|
-
const parametersQuery = `
|
|
142
|
-
SELECT
|
|
143
|
-
PARAMETER_NAME as name,
|
|
144
|
-
PARAMETER_MODE as mode,
|
|
145
|
-
DATA_TYPE as data_type,
|
|
146
|
-
CHARACTER_MAXIMUM_LENGTH as max_length,
|
|
147
|
-
ORDINAL_POSITION as position
|
|
148
|
-
FROM INFORMATION_SCHEMA.PARAMETERS
|
|
149
|
-
WHERE SPECIFIC_SCHEMA = ? AND SPECIFIC_NAME = ?
|
|
150
|
-
ORDER BY ORDINAL_POSITION
|
|
141
|
+
const parametersQuery = `
|
|
142
|
+
SELECT
|
|
143
|
+
PARAMETER_NAME as name,
|
|
144
|
+
PARAMETER_MODE as mode,
|
|
145
|
+
DATA_TYPE as data_type,
|
|
146
|
+
CHARACTER_MAXIMUM_LENGTH as max_length,
|
|
147
|
+
ORDINAL_POSITION as position
|
|
148
|
+
FROM INFORMATION_SCHEMA.PARAMETERS
|
|
149
|
+
WHERE SPECIFIC_SCHEMA = ? AND SPECIFIC_NAME = ?
|
|
150
|
+
ORDER BY ORDINAL_POSITION
|
|
151
151
|
`;
|
|
152
152
|
const [procedureInfo, parameters] = await Promise.all([
|
|
153
153
|
this.db.query(procedureQuery, [database, procedure_name]),
|
|
154
|
-
this.db.query(parametersQuery, [database, procedure_name])
|
|
154
|
+
this.db.query(parametersQuery, [database, procedure_name]),
|
|
155
155
|
]);
|
|
156
156
|
if (procedureInfo.length === 0) {
|
|
157
157
|
return {
|
|
158
|
-
status:
|
|
158
|
+
status: "error",
|
|
159
159
|
error: `Stored procedure '${procedure_name}' not found in database '${database}'`,
|
|
160
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
161
160
|
};
|
|
162
161
|
}
|
|
163
162
|
return {
|
|
164
|
-
status:
|
|
163
|
+
status: "success",
|
|
165
164
|
data: {
|
|
166
165
|
...procedureInfo[0],
|
|
167
|
-
parameters: parameters
|
|
166
|
+
parameters: parameters,
|
|
168
167
|
},
|
|
169
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
170
168
|
};
|
|
171
169
|
}
|
|
172
170
|
catch (error) {
|
|
173
171
|
return {
|
|
174
|
-
status:
|
|
172
|
+
status: "error",
|
|
175
173
|
error: error.message,
|
|
176
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
177
174
|
};
|
|
178
175
|
}
|
|
179
176
|
}
|
|
@@ -184,8 +181,9 @@ class StoredProcedureTools {
|
|
|
184
181
|
// Validate input schema
|
|
185
182
|
if (!(0, schemas_1.validateStoredProcedureExecution)(params)) {
|
|
186
183
|
return {
|
|
187
|
-
status:
|
|
188
|
-
error:
|
|
184
|
+
status: "error",
|
|
185
|
+
error: "Invalid parameters: " +
|
|
186
|
+
JSON.stringify(schemas_1.validateStoredProcedureExecution.errors),
|
|
189
187
|
};
|
|
190
188
|
}
|
|
191
189
|
try {
|
|
@@ -193,8 +191,8 @@ class StoredProcedureTools {
|
|
|
193
191
|
const dbValidation = this.validateDatabaseAccess(params.database);
|
|
194
192
|
if (!dbValidation.valid) {
|
|
195
193
|
return {
|
|
196
|
-
status:
|
|
197
|
-
error: dbValidation.error
|
|
194
|
+
status: "error",
|
|
195
|
+
error: dbValidation.error,
|
|
198
196
|
};
|
|
199
197
|
}
|
|
200
198
|
const { procedure_name, parameters = [] } = params;
|
|
@@ -203,32 +201,35 @@ class StoredProcedureTools {
|
|
|
203
201
|
const identifierValidation = this.security.validateIdentifier(procedure_name);
|
|
204
202
|
if (!identifierValidation.valid) {
|
|
205
203
|
return {
|
|
206
|
-
status:
|
|
207
|
-
error: identifierValidation.error ||
|
|
204
|
+
status: "error",
|
|
205
|
+
error: identifierValidation.error || "Invalid procedure name",
|
|
208
206
|
};
|
|
209
207
|
}
|
|
210
208
|
// Get procedure parameter information to handle OUT/INOUT parameters
|
|
211
|
-
const procInfo = await this.getStoredProcedureInfo({
|
|
212
|
-
|
|
209
|
+
const procInfo = await this.getStoredProcedureInfo({
|
|
210
|
+
procedure_name,
|
|
211
|
+
database,
|
|
212
|
+
});
|
|
213
|
+
if (procInfo.status !== "success" || !procInfo.data) {
|
|
213
214
|
return {
|
|
214
|
-
status:
|
|
215
|
-
error: `Could not retrieve procedure information: ${procInfo.error ||
|
|
215
|
+
status: "error",
|
|
216
|
+
error: `Could not retrieve procedure information: ${procInfo.error || "Unknown error"}`,
|
|
216
217
|
};
|
|
217
218
|
}
|
|
218
219
|
const procedureParams = procInfo.data.parameters || [];
|
|
219
220
|
// Validate parameter count
|
|
220
221
|
if (parameters.length > procedureParams.length) {
|
|
221
222
|
return {
|
|
222
|
-
status:
|
|
223
|
-
error: `Too many parameters provided. Expected ${procedureParams.length}, got ${parameters.length}
|
|
223
|
+
status: "error",
|
|
224
|
+
error: `Too many parameters provided. Expected ${procedureParams.length}, got ${parameters.length}`,
|
|
224
225
|
};
|
|
225
226
|
}
|
|
226
227
|
// Validate parameters
|
|
227
228
|
const paramValidation = this.security.validateParameters(parameters);
|
|
228
229
|
if (!paramValidation.valid) {
|
|
229
230
|
return {
|
|
230
|
-
status:
|
|
231
|
-
error: `Parameter validation failed: ${paramValidation.error}
|
|
231
|
+
status: "error",
|
|
232
|
+
error: `Parameter validation failed: ${paramValidation.error}`,
|
|
232
233
|
};
|
|
233
234
|
}
|
|
234
235
|
// Build parameter list for CALL statement
|
|
@@ -237,57 +238,59 @@ class StoredProcedureTools {
|
|
|
237
238
|
let paramIndex = 0;
|
|
238
239
|
for (let i = 0; i < procedureParams.length; i++) {
|
|
239
240
|
const procParam = procedureParams[i];
|
|
240
|
-
if (procParam.mode ===
|
|
241
|
+
if (procParam.mode === "IN") {
|
|
241
242
|
// IN parameters use provided values or NULL if not provided
|
|
242
243
|
if (paramIndex < parameters.length) {
|
|
243
|
-
callParams.push(
|
|
244
|
+
callParams.push("?");
|
|
244
245
|
paramIndex++;
|
|
245
246
|
}
|
|
246
247
|
else {
|
|
247
|
-
callParams.push(
|
|
248
|
+
callParams.push("NULL");
|
|
248
249
|
}
|
|
249
250
|
}
|
|
250
|
-
else if (procParam.mode ===
|
|
251
|
+
else if (procParam.mode === "OUT" || procParam.mode === "INOUT") {
|
|
251
252
|
// OUT/INOUT parameters use session variables
|
|
252
253
|
const varName = `@${procParam.name}_${Date.now()}_${i}`;
|
|
253
254
|
sessionVars.push(varName);
|
|
254
|
-
if (procParam.mode ===
|
|
255
|
+
if (procParam.mode === "INOUT" && paramIndex < parameters.length) {
|
|
255
256
|
// For INOUT, set the session variable to the input value first
|
|
256
|
-
await this.db.query(`SET ${varName} = ?`, [
|
|
257
|
+
await this.db.query(`SET ${varName} = ?`, [
|
|
258
|
+
paramValidation.sanitizedParams[paramIndex],
|
|
259
|
+
]);
|
|
257
260
|
paramIndex++;
|
|
258
261
|
}
|
|
259
262
|
callParams.push(varName);
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
// Build and execute CALL statement
|
|
263
|
-
const callQuery = `CALL \`${database}\`.\`${procedure_name}\`(${callParams.join(
|
|
266
|
+
const callQuery = `CALL \`${database}\`.\`${procedure_name}\`(${callParams.join(", ")})`;
|
|
264
267
|
const callResults = await this.db.query(callQuery, paramValidation.sanitizedParams.slice(0, paramIndex));
|
|
265
268
|
// Get OUT/INOUT parameter values
|
|
266
269
|
const outputValues = {};
|
|
267
270
|
if (sessionVars.length > 0) {
|
|
268
|
-
const selectQuery = `SELECT ${sessionVars.join(
|
|
271
|
+
const selectQuery = `SELECT ${sessionVars.join(", ")}`;
|
|
269
272
|
const outputResults = await this.db.query(selectQuery);
|
|
270
273
|
if (outputResults && outputResults.length > 0) {
|
|
271
274
|
const outputRow = outputResults[0];
|
|
272
275
|
sessionVars.forEach((varName, index) => {
|
|
273
|
-
const paramName = procedureParams.find((p) => (p.mode ===
|
|
276
|
+
const paramName = procedureParams.find((p) => (p.mode === "OUT" || p.mode === "INOUT") &&
|
|
274
277
|
varName.includes(p.name))?.name || `param_${index}`;
|
|
275
278
|
outputValues[paramName] = outputRow[varName];
|
|
276
279
|
});
|
|
277
280
|
}
|
|
278
281
|
}
|
|
279
282
|
return {
|
|
280
|
-
status:
|
|
283
|
+
status: "success",
|
|
281
284
|
data: {
|
|
282
285
|
results: callResults,
|
|
283
|
-
outputParameters: Object.keys(outputValues).length > 0 ? outputValues : undefined
|
|
284
|
-
}
|
|
286
|
+
outputParameters: Object.keys(outputValues).length > 0 ? outputValues : undefined,
|
|
287
|
+
},
|
|
285
288
|
};
|
|
286
289
|
}
|
|
287
290
|
catch (error) {
|
|
288
291
|
return {
|
|
289
|
-
status:
|
|
290
|
-
error: error.message
|
|
292
|
+
status: "error",
|
|
293
|
+
error: error.message,
|
|
291
294
|
};
|
|
292
295
|
}
|
|
293
296
|
}
|
|
@@ -298,8 +301,9 @@ class StoredProcedureTools {
|
|
|
298
301
|
// Validate input schema
|
|
299
302
|
if (!(0, schemas_1.validateStoredProcedureCreation)(params)) {
|
|
300
303
|
return {
|
|
301
|
-
status:
|
|
302
|
-
error:
|
|
304
|
+
status: "error",
|
|
305
|
+
error: "Invalid parameters: " +
|
|
306
|
+
JSON.stringify(schemas_1.validateStoredProcedureCreation.errors),
|
|
303
307
|
};
|
|
304
308
|
}
|
|
305
309
|
try {
|
|
@@ -307,8 +311,8 @@ class StoredProcedureTools {
|
|
|
307
311
|
const dbValidation = this.validateDatabaseAccess(params.database);
|
|
308
312
|
if (!dbValidation.valid) {
|
|
309
313
|
return {
|
|
310
|
-
status:
|
|
311
|
-
error: dbValidation.error
|
|
314
|
+
status: "error",
|
|
315
|
+
error: dbValidation.error,
|
|
312
316
|
};
|
|
313
317
|
}
|
|
314
318
|
const { procedure_name, parameters = [], body, comment } = params;
|
|
@@ -317,26 +321,29 @@ class StoredProcedureTools {
|
|
|
317
321
|
const identifierValidation = this.security.validateIdentifier(procedure_name);
|
|
318
322
|
if (!identifierValidation.valid) {
|
|
319
323
|
return {
|
|
320
|
-
status:
|
|
321
|
-
error: identifierValidation.error ||
|
|
324
|
+
status: "error",
|
|
325
|
+
error: identifierValidation.error || "Invalid procedure name",
|
|
322
326
|
};
|
|
323
327
|
}
|
|
324
328
|
// Build parameter list
|
|
325
|
-
const parameterList = parameters
|
|
329
|
+
const parameterList = parameters
|
|
330
|
+
.map((param) => {
|
|
326
331
|
if (!this.security.validateIdentifier(param.name).valid) {
|
|
327
332
|
throw new Error(`Invalid parameter name: ${param.name}`);
|
|
328
333
|
}
|
|
329
334
|
return `${param.mode} \`${param.name}\` ${param.data_type}`;
|
|
330
|
-
})
|
|
335
|
+
})
|
|
336
|
+
.join(", ");
|
|
331
337
|
// Build CREATE PROCEDURE statement
|
|
332
338
|
let createQuery = `CREATE PROCEDURE \`${database}\`.\`${procedure_name}\`(${parameterList})\n`;
|
|
333
339
|
if (comment) {
|
|
334
|
-
createQuery += `COMMENT '${comment.replace(/'/g, "''")}'
|
|
340
|
+
createQuery += `COMMENT '${comment.replace(/'/g, "''")}'
|
|
335
341
|
`;
|
|
336
342
|
}
|
|
337
343
|
// Check if body already contains BEGIN/END, if not add them
|
|
338
344
|
const trimmedBody = body.trim();
|
|
339
|
-
if (trimmedBody.toUpperCase().startsWith(
|
|
345
|
+
if (trimmedBody.toUpperCase().startsWith("BEGIN") &&
|
|
346
|
+
trimmedBody.toUpperCase().endsWith("END")) {
|
|
340
347
|
createQuery += `\n${body}`;
|
|
341
348
|
}
|
|
342
349
|
else {
|
|
@@ -345,18 +352,18 @@ class StoredProcedureTools {
|
|
|
345
352
|
// Execute the CREATE PROCEDURE statement
|
|
346
353
|
await this.db.query(createQuery);
|
|
347
354
|
return {
|
|
348
|
-
status:
|
|
355
|
+
status: "success",
|
|
349
356
|
data: {
|
|
350
357
|
message: `Stored procedure '${procedure_name}' created successfully`,
|
|
351
358
|
procedure_name,
|
|
352
|
-
database
|
|
353
|
-
}
|
|
359
|
+
database,
|
|
360
|
+
},
|
|
354
361
|
};
|
|
355
362
|
}
|
|
356
363
|
catch (error) {
|
|
357
364
|
return {
|
|
358
|
-
status:
|
|
359
|
-
error: error.message
|
|
365
|
+
status: "error",
|
|
366
|
+
error: error.message,
|
|
360
367
|
};
|
|
361
368
|
}
|
|
362
369
|
}
|
|
@@ -368,16 +375,17 @@ class StoredProcedureTools {
|
|
|
368
375
|
// Validate input
|
|
369
376
|
if (!(0, schemas_1.validateDropStoredProcedure)(params)) {
|
|
370
377
|
return {
|
|
371
|
-
status:
|
|
372
|
-
error:
|
|
378
|
+
status: "error",
|
|
379
|
+
error: "Invalid parameters: " +
|
|
380
|
+
JSON.stringify(schemas_1.validateDropStoredProcedure.errors),
|
|
373
381
|
};
|
|
374
382
|
}
|
|
375
383
|
// Validate database access
|
|
376
384
|
const dbValidation = this.validateDatabaseAccess(params.database);
|
|
377
385
|
if (!dbValidation.valid) {
|
|
378
386
|
return {
|
|
379
|
-
status:
|
|
380
|
-
error: dbValidation.error
|
|
387
|
+
status: "error",
|
|
388
|
+
error: dbValidation.error,
|
|
381
389
|
};
|
|
382
390
|
}
|
|
383
391
|
const { procedure_name, if_exists = false } = params;
|
|
@@ -386,23 +394,23 @@ class StoredProcedureTools {
|
|
|
386
394
|
const identifierValidation = this.security.validateIdentifier(procedure_name);
|
|
387
395
|
if (!identifierValidation.valid) {
|
|
388
396
|
return {
|
|
389
|
-
status:
|
|
390
|
-
error: identifierValidation.error ||
|
|
397
|
+
status: "error",
|
|
398
|
+
error: identifierValidation.error || "Invalid procedure name",
|
|
391
399
|
};
|
|
392
400
|
}
|
|
393
401
|
// Build DROP PROCEDURE statement
|
|
394
|
-
const dropQuery = `DROP PROCEDURE ${if_exists ?
|
|
402
|
+
const dropQuery = `DROP PROCEDURE ${if_exists ? "IF EXISTS" : ""} \`${database}\`.\`${procedure_name}\``;
|
|
395
403
|
// Execute the DROP PROCEDURE statement
|
|
396
404
|
await this.db.query(dropQuery);
|
|
397
405
|
return {
|
|
398
|
-
status:
|
|
399
|
-
message: `Stored procedure '${procedure_name}' dropped successfully
|
|
406
|
+
status: "success",
|
|
407
|
+
message: `Stored procedure '${procedure_name}' dropped successfully`,
|
|
400
408
|
};
|
|
401
409
|
}
|
|
402
410
|
catch (error) {
|
|
403
411
|
return {
|
|
404
|
-
status:
|
|
405
|
-
error: error.message
|
|
412
|
+
status: "error",
|
|
413
|
+
error: error.message,
|
|
406
414
|
};
|
|
407
415
|
}
|
|
408
416
|
}
|
|
@@ -414,16 +422,17 @@ class StoredProcedureTools {
|
|
|
414
422
|
// Validate input
|
|
415
423
|
if (!(0, schemas_1.validateShowCreateProcedure)(params)) {
|
|
416
424
|
return {
|
|
417
|
-
status:
|
|
418
|
-
error:
|
|
425
|
+
status: "error",
|
|
426
|
+
error: "Invalid parameters: " +
|
|
427
|
+
JSON.stringify(schemas_1.validateShowCreateProcedure.errors),
|
|
419
428
|
};
|
|
420
429
|
}
|
|
421
430
|
// Validate database access
|
|
422
431
|
const dbValidation = this.validateDatabaseAccess(params.database);
|
|
423
432
|
if (!dbValidation.valid) {
|
|
424
433
|
return {
|
|
425
|
-
status:
|
|
426
|
-
error: dbValidation.error
|
|
434
|
+
status: "error",
|
|
435
|
+
error: dbValidation.error,
|
|
427
436
|
};
|
|
428
437
|
}
|
|
429
438
|
const { procedure_name } = params;
|
|
@@ -432,27 +441,27 @@ class StoredProcedureTools {
|
|
|
432
441
|
const identifierValidation = this.security.validateIdentifier(procedure_name);
|
|
433
442
|
if (!identifierValidation.valid) {
|
|
434
443
|
return {
|
|
435
|
-
status:
|
|
436
|
-
error: identifierValidation.error ||
|
|
444
|
+
status: "error",
|
|
445
|
+
error: identifierValidation.error || "Invalid procedure name",
|
|
437
446
|
};
|
|
438
447
|
}
|
|
439
448
|
const query = `SHOW CREATE PROCEDURE \`${database}\`.\`${procedure_name}\``;
|
|
440
449
|
const results = await this.db.query(query);
|
|
441
450
|
if (results.length === 0) {
|
|
442
451
|
return {
|
|
443
|
-
status:
|
|
444
|
-
error: `Stored procedure '${procedure_name}' not found
|
|
452
|
+
status: "error",
|
|
453
|
+
error: `Stored procedure '${procedure_name}' not found`,
|
|
445
454
|
};
|
|
446
455
|
}
|
|
447
456
|
return {
|
|
448
|
-
status:
|
|
449
|
-
data: results[0]
|
|
457
|
+
status: "success",
|
|
458
|
+
data: results[0],
|
|
450
459
|
};
|
|
451
460
|
}
|
|
452
461
|
catch (error) {
|
|
453
462
|
return {
|
|
454
|
-
status:
|
|
455
|
-
error: error.message
|
|
463
|
+
status: "error",
|
|
464
|
+
error: error.message,
|
|
456
465
|
};
|
|
457
466
|
}
|
|
458
467
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface TransactionResult {
|
|
2
|
-
status:
|
|
2
|
+
status: "success" | "error";
|
|
3
3
|
transactionId?: string;
|
|
4
4
|
message?: string;
|
|
5
5
|
activeTransactions?: string[];
|
|
@@ -38,9 +38,8 @@ export declare class TransactionTools {
|
|
|
38
38
|
query: string;
|
|
39
39
|
params?: any[];
|
|
40
40
|
}): Promise<{
|
|
41
|
-
status:
|
|
41
|
+
status: "success" | "error";
|
|
42
42
|
data?: any;
|
|
43
43
|
error?: string;
|
|
44
|
-
queryLog?: string;
|
|
45
44
|
}>;
|
|
46
45
|
}
|