@berthojoris/mcp-mysql-server 1.10.3 → 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 +18 -7
- package/DOCUMENTATIONS.md +2 -2
- 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 FunctionTools {
|
|
3
3
|
private db;
|
|
4
4
|
private security;
|
|
@@ -16,7 +16,6 @@ export declare class FunctionTools {
|
|
|
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 function
|
|
@@ -28,7 +27,6 @@ export declare class FunctionTools {
|
|
|
28
27
|
status: string;
|
|
29
28
|
data?: any;
|
|
30
29
|
error?: string;
|
|
31
|
-
queryLog?: string;
|
|
32
30
|
}>;
|
|
33
31
|
/**
|
|
34
32
|
* Create a new function
|
|
@@ -42,15 +40,14 @@ export declare class FunctionTools {
|
|
|
42
40
|
returns: string;
|
|
43
41
|
body: string;
|
|
44
42
|
deterministic?: boolean;
|
|
45
|
-
data_access?:
|
|
46
|
-
security?:
|
|
43
|
+
data_access?: "CONTAINS SQL" | "NO SQL" | "READS SQL DATA" | "MODIFIES SQL DATA";
|
|
44
|
+
security?: "DEFINER" | "INVOKER";
|
|
47
45
|
comment?: string;
|
|
48
46
|
database?: string;
|
|
49
47
|
}): Promise<{
|
|
50
48
|
status: string;
|
|
51
49
|
data?: any;
|
|
52
50
|
error?: string;
|
|
53
|
-
queryLog?: string;
|
|
54
51
|
}>;
|
|
55
52
|
/**
|
|
56
53
|
* Drop a function
|
|
@@ -63,7 +60,6 @@ export declare class FunctionTools {
|
|
|
63
60
|
status: string;
|
|
64
61
|
message?: string;
|
|
65
62
|
error?: string;
|
|
66
|
-
queryLog?: string;
|
|
67
63
|
}>;
|
|
68
64
|
/**
|
|
69
65
|
* Show the CREATE statement for a function
|
|
@@ -75,7 +71,6 @@ export declare class FunctionTools {
|
|
|
75
71
|
status: string;
|
|
76
72
|
data?: any;
|
|
77
73
|
error?: string;
|
|
78
|
-
queryLog?: string;
|
|
79
74
|
}>;
|
|
80
75
|
/**
|
|
81
76
|
* Execute a function and return its result
|
|
@@ -88,6 +83,5 @@ export declare class FunctionTools {
|
|
|
88
83
|
status: string;
|
|
89
84
|
data?: any;
|
|
90
85
|
error?: string;
|
|
91
|
-
queryLog?: string;
|
|
92
86
|
}>;
|
|
93
87
|
}
|
|
@@ -19,26 +19,26 @@ class FunctionTools {
|
|
|
19
19
|
if (!connectedDatabase) {
|
|
20
20
|
return {
|
|
21
21
|
valid: false,
|
|
22
|
-
database:
|
|
23
|
-
error:
|
|
22
|
+
database: "",
|
|
23
|
+
error: "No database specified in connection string. Cannot access any database.",
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
if (!requestedDatabase) {
|
|
27
27
|
return {
|
|
28
28
|
valid: true,
|
|
29
|
-
database: connectedDatabase
|
|
29
|
+
database: connectedDatabase,
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
if (requestedDatabase !== connectedDatabase) {
|
|
33
33
|
return {
|
|
34
34
|
valid: false,
|
|
35
|
-
database:
|
|
36
|
-
error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed
|
|
35
|
+
database: "",
|
|
36
|
+
error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed.`,
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
return {
|
|
40
40
|
valid: true,
|
|
41
|
-
database: connectedDatabase
|
|
41
|
+
database: connectedDatabase,
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
@@ -48,38 +48,36 @@ class FunctionTools {
|
|
|
48
48
|
try {
|
|
49
49
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
50
50
|
if (!dbValidation.valid) {
|
|
51
|
-
return { status:
|
|
51
|
+
return { status: "error", error: dbValidation.error };
|
|
52
52
|
}
|
|
53
53
|
const database = dbValidation.database;
|
|
54
|
-
const query = `
|
|
55
|
-
SELECT
|
|
56
|
-
ROUTINE_NAME as function_name,
|
|
57
|
-
DATA_TYPE as return_type,
|
|
58
|
-
DTD_IDENTIFIER as return_type_full,
|
|
59
|
-
ROUTINE_DEFINITION as definition,
|
|
60
|
-
IS_DETERMINISTIC as is_deterministic,
|
|
61
|
-
SQL_DATA_ACCESS as data_access,
|
|
62
|
-
SECURITY_TYPE as security_type,
|
|
63
|
-
DEFINER as definer,
|
|
64
|
-
CREATED as created,
|
|
65
|
-
LAST_ALTERED as last_altered,
|
|
66
|
-
ROUTINE_COMMENT as comment
|
|
67
|
-
FROM INFORMATION_SCHEMA.ROUTINES
|
|
68
|
-
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_TYPE = 'FUNCTION'
|
|
69
|
-
ORDER BY ROUTINE_NAME
|
|
54
|
+
const query = `
|
|
55
|
+
SELECT
|
|
56
|
+
ROUTINE_NAME as function_name,
|
|
57
|
+
DATA_TYPE as return_type,
|
|
58
|
+
DTD_IDENTIFIER as return_type_full,
|
|
59
|
+
ROUTINE_DEFINITION as definition,
|
|
60
|
+
IS_DETERMINISTIC as is_deterministic,
|
|
61
|
+
SQL_DATA_ACCESS as data_access,
|
|
62
|
+
SECURITY_TYPE as security_type,
|
|
63
|
+
DEFINER as definer,
|
|
64
|
+
CREATED as created,
|
|
65
|
+
LAST_ALTERED as last_altered,
|
|
66
|
+
ROUTINE_COMMENT as comment
|
|
67
|
+
FROM INFORMATION_SCHEMA.ROUTINES
|
|
68
|
+
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_TYPE = 'FUNCTION'
|
|
69
|
+
ORDER BY ROUTINE_NAME
|
|
70
70
|
`;
|
|
71
71
|
const results = await this.db.query(query, [database]);
|
|
72
72
|
return {
|
|
73
|
-
status:
|
|
73
|
+
status: "success",
|
|
74
74
|
data: results,
|
|
75
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
76
75
|
};
|
|
77
76
|
}
|
|
78
77
|
catch (error) {
|
|
79
78
|
return {
|
|
80
|
-
status:
|
|
79
|
+
status: "error",
|
|
81
80
|
error: error.message,
|
|
82
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
83
81
|
};
|
|
84
82
|
}
|
|
85
83
|
}
|
|
@@ -90,75 +88,75 @@ class FunctionTools {
|
|
|
90
88
|
try {
|
|
91
89
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
92
90
|
if (!dbValidation.valid) {
|
|
93
|
-
return { status:
|
|
91
|
+
return { status: "error", error: dbValidation.error };
|
|
94
92
|
}
|
|
95
93
|
const { function_name } = params;
|
|
96
94
|
const database = dbValidation.database;
|
|
97
95
|
// Validate function name
|
|
98
96
|
const identifierValidation = this.security.validateIdentifier(function_name);
|
|
99
97
|
if (!identifierValidation.valid) {
|
|
100
|
-
return {
|
|
98
|
+
return {
|
|
99
|
+
status: "error",
|
|
100
|
+
error: identifierValidation.error || "Invalid function name",
|
|
101
|
+
};
|
|
101
102
|
}
|
|
102
103
|
// Get function information
|
|
103
|
-
const functionQuery = `
|
|
104
|
-
SELECT
|
|
105
|
-
ROUTINE_NAME as function_name,
|
|
106
|
-
DATA_TYPE as return_type,
|
|
107
|
-
DTD_IDENTIFIER as return_type_full,
|
|
108
|
-
ROUTINE_DEFINITION as definition,
|
|
109
|
-
IS_DETERMINISTIC as is_deterministic,
|
|
110
|
-
SQL_DATA_ACCESS as data_access,
|
|
111
|
-
SECURITY_TYPE as security_type,
|
|
112
|
-
DEFINER as definer,
|
|
113
|
-
CREATED as created,
|
|
114
|
-
LAST_ALTERED as last_altered,
|
|
115
|
-
ROUTINE_COMMENT as comment,
|
|
116
|
-
SQL_MODE as sql_mode,
|
|
117
|
-
CHARACTER_SET_CLIENT as charset,
|
|
118
|
-
COLLATION_CONNECTION as collation,
|
|
119
|
-
DATABASE_COLLATION as db_collation
|
|
120
|
-
FROM INFORMATION_SCHEMA.ROUTINES
|
|
121
|
-
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ? AND ROUTINE_TYPE = 'FUNCTION'
|
|
104
|
+
const functionQuery = `
|
|
105
|
+
SELECT
|
|
106
|
+
ROUTINE_NAME as function_name,
|
|
107
|
+
DATA_TYPE as return_type,
|
|
108
|
+
DTD_IDENTIFIER as return_type_full,
|
|
109
|
+
ROUTINE_DEFINITION as definition,
|
|
110
|
+
IS_DETERMINISTIC as is_deterministic,
|
|
111
|
+
SQL_DATA_ACCESS as data_access,
|
|
112
|
+
SECURITY_TYPE as security_type,
|
|
113
|
+
DEFINER as definer,
|
|
114
|
+
CREATED as created,
|
|
115
|
+
LAST_ALTERED as last_altered,
|
|
116
|
+
ROUTINE_COMMENT as comment,
|
|
117
|
+
SQL_MODE as sql_mode,
|
|
118
|
+
CHARACTER_SET_CLIENT as charset,
|
|
119
|
+
COLLATION_CONNECTION as collation,
|
|
120
|
+
DATABASE_COLLATION as db_collation
|
|
121
|
+
FROM INFORMATION_SCHEMA.ROUTINES
|
|
122
|
+
WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ? AND ROUTINE_TYPE = 'FUNCTION'
|
|
122
123
|
`;
|
|
123
124
|
// Get function parameters
|
|
124
|
-
const parametersQuery = `
|
|
125
|
-
SELECT
|
|
126
|
-
PARAMETER_NAME as name,
|
|
127
|
-
DATA_TYPE as data_type,
|
|
128
|
-
DTD_IDENTIFIER as data_type_full,
|
|
129
|
-
CHARACTER_MAXIMUM_LENGTH as max_length,
|
|
130
|
-
NUMERIC_PRECISION as numeric_precision,
|
|
131
|
-
NUMERIC_SCALE as numeric_scale,
|
|
132
|
-
ORDINAL_POSITION as position
|
|
133
|
-
FROM INFORMATION_SCHEMA.PARAMETERS
|
|
134
|
-
WHERE SPECIFIC_SCHEMA = ? AND SPECIFIC_NAME = ? AND PARAMETER_MODE IS NOT NULL
|
|
135
|
-
ORDER BY ORDINAL_POSITION
|
|
125
|
+
const parametersQuery = `
|
|
126
|
+
SELECT
|
|
127
|
+
PARAMETER_NAME as name,
|
|
128
|
+
DATA_TYPE as data_type,
|
|
129
|
+
DTD_IDENTIFIER as data_type_full,
|
|
130
|
+
CHARACTER_MAXIMUM_LENGTH as max_length,
|
|
131
|
+
NUMERIC_PRECISION as numeric_precision,
|
|
132
|
+
NUMERIC_SCALE as numeric_scale,
|
|
133
|
+
ORDINAL_POSITION as position
|
|
134
|
+
FROM INFORMATION_SCHEMA.PARAMETERS
|
|
135
|
+
WHERE SPECIFIC_SCHEMA = ? AND SPECIFIC_NAME = ? AND PARAMETER_MODE IS NOT NULL
|
|
136
|
+
ORDER BY ORDINAL_POSITION
|
|
136
137
|
`;
|
|
137
138
|
const [functionInfo, parameters] = await Promise.all([
|
|
138
139
|
this.db.query(functionQuery, [database, function_name]),
|
|
139
|
-
this.db.query(parametersQuery, [database, function_name])
|
|
140
|
+
this.db.query(parametersQuery, [database, function_name]),
|
|
140
141
|
]);
|
|
141
142
|
if (functionInfo.length === 0) {
|
|
142
143
|
return {
|
|
143
|
-
status:
|
|
144
|
+
status: "error",
|
|
144
145
|
error: `Function '${function_name}' not found in database '${database}'`,
|
|
145
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
148
|
return {
|
|
149
|
-
status:
|
|
149
|
+
status: "success",
|
|
150
150
|
data: {
|
|
151
151
|
...functionInfo[0],
|
|
152
|
-
parameters: parameters
|
|
152
|
+
parameters: parameters,
|
|
153
153
|
},
|
|
154
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
155
154
|
};
|
|
156
155
|
}
|
|
157
156
|
catch (error) {
|
|
158
157
|
return {
|
|
159
|
-
status:
|
|
158
|
+
status: "error",
|
|
160
159
|
error: error.message,
|
|
161
|
-
queryLog: this.db.getFormattedQueryLogs(2)
|
|
162
160
|
};
|
|
163
161
|
}
|
|
164
162
|
}
|
|
@@ -169,22 +167,27 @@ class FunctionTools {
|
|
|
169
167
|
try {
|
|
170
168
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
171
169
|
if (!dbValidation.valid) {
|
|
172
|
-
return { status:
|
|
170
|
+
return { status: "error", error: dbValidation.error };
|
|
173
171
|
}
|
|
174
|
-
const { function_name, parameters = [], returns, body, deterministic = false, data_access, security, comment } = params;
|
|
172
|
+
const { function_name, parameters = [], returns, body, deterministic = false, data_access, security, comment, } = params;
|
|
175
173
|
const database = dbValidation.database;
|
|
176
174
|
// Validate function name
|
|
177
175
|
const identifierValidation = this.security.validateIdentifier(function_name);
|
|
178
176
|
if (!identifierValidation.valid) {
|
|
179
|
-
return {
|
|
177
|
+
return {
|
|
178
|
+
status: "error",
|
|
179
|
+
error: identifierValidation.error || "Invalid function name",
|
|
180
|
+
};
|
|
180
181
|
}
|
|
181
182
|
// Build parameter list
|
|
182
|
-
const parameterList = parameters
|
|
183
|
+
const parameterList = parameters
|
|
184
|
+
.map((param) => {
|
|
183
185
|
if (!this.security.validateIdentifier(param.name).valid) {
|
|
184
186
|
throw new Error(`Invalid parameter name: ${param.name}`);
|
|
185
187
|
}
|
|
186
188
|
return `\`${param.name}\` ${param.data_type}`;
|
|
187
|
-
})
|
|
189
|
+
})
|
|
190
|
+
.join(", ");
|
|
188
191
|
// Build CREATE FUNCTION statement
|
|
189
192
|
let createQuery = `CREATE FUNCTION \`${database}\`.\`${function_name}\`(${parameterList})\n`;
|
|
190
193
|
createQuery += `RETURNS ${returns}\n`;
|
|
@@ -205,10 +208,11 @@ class FunctionTools {
|
|
|
205
208
|
}
|
|
206
209
|
// Check if body already contains BEGIN/END
|
|
207
210
|
const trimmedBody = body.trim();
|
|
208
|
-
if (trimmedBody.toUpperCase().startsWith(
|
|
211
|
+
if (trimmedBody.toUpperCase().startsWith("BEGIN") &&
|
|
212
|
+
trimmedBody.toUpperCase().endsWith("END")) {
|
|
209
213
|
createQuery += body;
|
|
210
214
|
}
|
|
211
|
-
else if (trimmedBody.toUpperCase().startsWith(
|
|
215
|
+
else if (trimmedBody.toUpperCase().startsWith("RETURN")) {
|
|
212
216
|
// Simple one-liner function
|
|
213
217
|
createQuery += body;
|
|
214
218
|
}
|
|
@@ -217,20 +221,18 @@ class FunctionTools {
|
|
|
217
221
|
}
|
|
218
222
|
await this.db.query(createQuery);
|
|
219
223
|
return {
|
|
220
|
-
status:
|
|
224
|
+
status: "success",
|
|
221
225
|
data: {
|
|
222
226
|
message: `Function '${function_name}' created successfully`,
|
|
223
227
|
function_name,
|
|
224
|
-
database
|
|
228
|
+
database,
|
|
225
229
|
},
|
|
226
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
227
230
|
};
|
|
228
231
|
}
|
|
229
232
|
catch (error) {
|
|
230
233
|
return {
|
|
231
|
-
status:
|
|
234
|
+
status: "error",
|
|
232
235
|
error: error.message,
|
|
233
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
234
236
|
};
|
|
235
237
|
}
|
|
236
238
|
}
|
|
@@ -241,28 +243,29 @@ class FunctionTools {
|
|
|
241
243
|
try {
|
|
242
244
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
243
245
|
if (!dbValidation.valid) {
|
|
244
|
-
return { status:
|
|
246
|
+
return { status: "error", error: dbValidation.error };
|
|
245
247
|
}
|
|
246
248
|
const { function_name, if_exists = false } = params;
|
|
247
249
|
const database = dbValidation.database;
|
|
248
250
|
// Validate function name
|
|
249
251
|
const identifierValidation = this.security.validateIdentifier(function_name);
|
|
250
252
|
if (!identifierValidation.valid) {
|
|
251
|
-
return {
|
|
253
|
+
return {
|
|
254
|
+
status: "error",
|
|
255
|
+
error: identifierValidation.error || "Invalid function name",
|
|
256
|
+
};
|
|
252
257
|
}
|
|
253
|
-
const dropQuery = `DROP FUNCTION ${if_exists ?
|
|
258
|
+
const dropQuery = `DROP FUNCTION ${if_exists ? "IF EXISTS" : ""} \`${database}\`.\`${function_name}\``;
|
|
254
259
|
await this.db.query(dropQuery);
|
|
255
260
|
return {
|
|
256
|
-
status:
|
|
261
|
+
status: "success",
|
|
257
262
|
message: `Function '${function_name}' dropped successfully`,
|
|
258
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
259
263
|
};
|
|
260
264
|
}
|
|
261
265
|
catch (error) {
|
|
262
266
|
return {
|
|
263
|
-
status:
|
|
267
|
+
status: "error",
|
|
264
268
|
error: error.message,
|
|
265
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
266
269
|
};
|
|
267
270
|
}
|
|
268
271
|
}
|
|
@@ -273,35 +276,35 @@ class FunctionTools {
|
|
|
273
276
|
try {
|
|
274
277
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
275
278
|
if (!dbValidation.valid) {
|
|
276
|
-
return { status:
|
|
279
|
+
return { status: "error", error: dbValidation.error };
|
|
277
280
|
}
|
|
278
281
|
const { function_name } = params;
|
|
279
282
|
const database = dbValidation.database;
|
|
280
283
|
// Validate function name
|
|
281
284
|
const identifierValidation = this.security.validateIdentifier(function_name);
|
|
282
285
|
if (!identifierValidation.valid) {
|
|
283
|
-
return {
|
|
286
|
+
return {
|
|
287
|
+
status: "error",
|
|
288
|
+
error: identifierValidation.error || "Invalid function name",
|
|
289
|
+
};
|
|
284
290
|
}
|
|
285
291
|
const query = `SHOW CREATE FUNCTION \`${database}\`.\`${function_name}\``;
|
|
286
292
|
const results = await this.db.query(query);
|
|
287
293
|
if (results.length === 0) {
|
|
288
294
|
return {
|
|
289
|
-
status:
|
|
295
|
+
status: "error",
|
|
290
296
|
error: `Function '${function_name}' not found`,
|
|
291
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
292
297
|
};
|
|
293
298
|
}
|
|
294
299
|
return {
|
|
295
|
-
status:
|
|
300
|
+
status: "success",
|
|
296
301
|
data: results[0],
|
|
297
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
298
302
|
};
|
|
299
303
|
}
|
|
300
304
|
catch (error) {
|
|
301
305
|
return {
|
|
302
|
-
status:
|
|
306
|
+
status: "error",
|
|
303
307
|
error: error.message,
|
|
304
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
305
308
|
};
|
|
306
309
|
}
|
|
307
310
|
}
|
|
@@ -312,38 +315,42 @@ class FunctionTools {
|
|
|
312
315
|
try {
|
|
313
316
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
314
317
|
if (!dbValidation.valid) {
|
|
315
|
-
return { status:
|
|
318
|
+
return { status: "error", error: dbValidation.error };
|
|
316
319
|
}
|
|
317
320
|
const { function_name, parameters = [] } = params;
|
|
318
321
|
const database = dbValidation.database;
|
|
319
322
|
// Validate function name
|
|
320
323
|
const identifierValidation = this.security.validateIdentifier(function_name);
|
|
321
324
|
if (!identifierValidation.valid) {
|
|
322
|
-
return {
|
|
325
|
+
return {
|
|
326
|
+
status: "error",
|
|
327
|
+
error: identifierValidation.error || "Invalid function name",
|
|
328
|
+
};
|
|
323
329
|
}
|
|
324
330
|
// Validate parameters
|
|
325
331
|
const paramValidation = this.security.validateParameters(parameters);
|
|
326
332
|
if (!paramValidation.valid) {
|
|
327
|
-
return {
|
|
333
|
+
return {
|
|
334
|
+
status: "error",
|
|
335
|
+
error: `Parameter validation failed: ${paramValidation.error}`,
|
|
336
|
+
};
|
|
328
337
|
}
|
|
329
338
|
// Build SELECT query to call the function
|
|
330
|
-
const placeholders = parameters.map(() =>
|
|
339
|
+
const placeholders = parameters.map(() => "?").join(", ");
|
|
331
340
|
const selectQuery = `SELECT \`${database}\`.\`${function_name}\`(${placeholders}) AS result`;
|
|
332
341
|
const results = await this.db.query(selectQuery, paramValidation.sanitizedParams);
|
|
333
342
|
return {
|
|
334
|
-
status:
|
|
343
|
+
status: "success",
|
|
335
344
|
data: {
|
|
336
345
|
function_name,
|
|
337
|
-
result: results[0]?.result
|
|
346
|
+
result: results[0]?.result,
|
|
338
347
|
},
|
|
339
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
340
348
|
};
|
|
341
349
|
}
|
|
342
350
|
catch (error) {
|
|
343
351
|
return {
|
|
344
|
-
status:
|
|
352
|
+
status: "error",
|
|
345
353
|
error: error.message,
|
|
346
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
347
354
|
};
|
|
348
355
|
}
|
|
349
356
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SecurityLayer } from
|
|
1
|
+
import { SecurityLayer } from "../security/securityLayer";
|
|
2
2
|
export declare class IndexTools {
|
|
3
3
|
private db;
|
|
4
4
|
private security;
|
|
@@ -17,7 +17,6 @@ export declare class IndexTools {
|
|
|
17
17
|
status: string;
|
|
18
18
|
data?: any[];
|
|
19
19
|
error?: string;
|
|
20
|
-
queryLog?: string;
|
|
21
20
|
}>;
|
|
22
21
|
/**
|
|
23
22
|
* Get detailed information about a specific index
|
|
@@ -30,7 +29,6 @@ export declare class IndexTools {
|
|
|
30
29
|
status: string;
|
|
31
30
|
data?: any;
|
|
32
31
|
error?: string;
|
|
33
|
-
queryLog?: string;
|
|
34
32
|
}>;
|
|
35
33
|
/**
|
|
36
34
|
* Create a new index
|
|
@@ -41,17 +39,16 @@ export declare class IndexTools {
|
|
|
41
39
|
columns: Array<string | {
|
|
42
40
|
column: string;
|
|
43
41
|
length?: number;
|
|
44
|
-
order?:
|
|
42
|
+
order?: "ASC" | "DESC";
|
|
45
43
|
}>;
|
|
46
44
|
unique?: boolean;
|
|
47
|
-
index_type?:
|
|
45
|
+
index_type?: "BTREE" | "HASH" | "FULLTEXT" | "SPATIAL";
|
|
48
46
|
comment?: string;
|
|
49
47
|
database?: string;
|
|
50
48
|
}): Promise<{
|
|
51
49
|
status: string;
|
|
52
50
|
data?: any;
|
|
53
51
|
error?: string;
|
|
54
|
-
queryLog?: string;
|
|
55
52
|
}>;
|
|
56
53
|
/**
|
|
57
54
|
* Drop an index
|
|
@@ -64,7 +61,6 @@ export declare class IndexTools {
|
|
|
64
61
|
status: string;
|
|
65
62
|
message?: string;
|
|
66
63
|
error?: string;
|
|
67
|
-
queryLog?: string;
|
|
68
64
|
}>;
|
|
69
65
|
/**
|
|
70
66
|
* Analyze index usage and statistics
|
|
@@ -76,6 +72,5 @@ export declare class IndexTools {
|
|
|
76
72
|
status: string;
|
|
77
73
|
data?: any;
|
|
78
74
|
error?: string;
|
|
79
|
-
queryLog?: string;
|
|
80
75
|
}>;
|
|
81
76
|
}
|