@berthojoris/mcp-mysql-server 1.10.3 → 1.10.5
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/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 ConstraintTools {
|
|
3
3
|
private db;
|
|
4
4
|
private security;
|
|
@@ -17,7 +17,6 @@ export declare class ConstraintTools {
|
|
|
17
17
|
status: string;
|
|
18
18
|
data?: any[];
|
|
19
19
|
error?: string;
|
|
20
|
-
queryLog?: string;
|
|
21
20
|
}>;
|
|
22
21
|
/**
|
|
23
22
|
* List all constraints (PK, FK, UNIQUE, CHECK) for a table
|
|
@@ -29,7 +28,6 @@ export declare class ConstraintTools {
|
|
|
29
28
|
status: string;
|
|
30
29
|
data?: any[];
|
|
31
30
|
error?: string;
|
|
32
|
-
queryLog?: string;
|
|
33
31
|
}>;
|
|
34
32
|
/**
|
|
35
33
|
* Add a foreign key constraint
|
|
@@ -40,14 +38,13 @@ export declare class ConstraintTools {
|
|
|
40
38
|
columns: string[];
|
|
41
39
|
referenced_table: string;
|
|
42
40
|
referenced_columns: string[];
|
|
43
|
-
on_delete?:
|
|
44
|
-
on_update?:
|
|
41
|
+
on_delete?: "CASCADE" | "SET NULL" | "RESTRICT" | "NO ACTION" | "SET DEFAULT";
|
|
42
|
+
on_update?: "CASCADE" | "SET NULL" | "RESTRICT" | "NO ACTION" | "SET DEFAULT";
|
|
45
43
|
database?: string;
|
|
46
44
|
}): Promise<{
|
|
47
45
|
status: string;
|
|
48
46
|
data?: any;
|
|
49
47
|
error?: string;
|
|
50
|
-
queryLog?: string;
|
|
51
48
|
}>;
|
|
52
49
|
/**
|
|
53
50
|
* Drop a foreign key constraint
|
|
@@ -60,7 +57,6 @@ export declare class ConstraintTools {
|
|
|
60
57
|
status: string;
|
|
61
58
|
message?: string;
|
|
62
59
|
error?: string;
|
|
63
|
-
queryLog?: string;
|
|
64
60
|
}>;
|
|
65
61
|
/**
|
|
66
62
|
* Add a unique constraint
|
|
@@ -74,7 +70,6 @@ export declare class ConstraintTools {
|
|
|
74
70
|
status: string;
|
|
75
71
|
data?: any;
|
|
76
72
|
error?: string;
|
|
77
|
-
queryLog?: string;
|
|
78
73
|
}>;
|
|
79
74
|
/**
|
|
80
75
|
* Drop a constraint (UNIQUE or CHECK)
|
|
@@ -82,13 +77,12 @@ export declare class ConstraintTools {
|
|
|
82
77
|
dropConstraint(params: {
|
|
83
78
|
table_name: string;
|
|
84
79
|
constraint_name: string;
|
|
85
|
-
constraint_type:
|
|
80
|
+
constraint_type: "UNIQUE" | "CHECK";
|
|
86
81
|
database?: string;
|
|
87
82
|
}): Promise<{
|
|
88
83
|
status: string;
|
|
89
84
|
message?: string;
|
|
90
85
|
error?: string;
|
|
91
|
-
queryLog?: string;
|
|
92
86
|
}>;
|
|
93
87
|
/**
|
|
94
88
|
* Add a check constraint (MySQL 8.0.16+)
|
|
@@ -103,6 +97,5 @@ export declare class ConstraintTools {
|
|
|
103
97
|
status: string;
|
|
104
98
|
data?: any;
|
|
105
99
|
error?: string;
|
|
106
|
-
queryLog?: string;
|
|
107
100
|
}>;
|
|
108
101
|
}
|
|
@@ -19,26 +19,26 @@ class ConstraintTools {
|
|
|
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,32 +48,32 @@ class ConstraintTools {
|
|
|
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 { table_name } = params;
|
|
54
54
|
const database = dbValidation.database;
|
|
55
55
|
// Validate table name
|
|
56
56
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
57
|
-
return { status:
|
|
57
|
+
return { status: "error", error: "Invalid table name" };
|
|
58
58
|
}
|
|
59
|
-
const query = `
|
|
60
|
-
SELECT
|
|
61
|
-
kcu.CONSTRAINT_NAME as constraint_name,
|
|
62
|
-
kcu.COLUMN_NAME as column_name,
|
|
63
|
-
kcu.REFERENCED_TABLE_SCHEMA as referenced_schema,
|
|
64
|
-
kcu.REFERENCED_TABLE_NAME as referenced_table,
|
|
65
|
-
kcu.REFERENCED_COLUMN_NAME as referenced_column,
|
|
66
|
-
kcu.ORDINAL_POSITION as ordinal_position,
|
|
67
|
-
rc.UPDATE_RULE as on_update,
|
|
68
|
-
rc.DELETE_RULE as on_delete
|
|
69
|
-
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
70
|
-
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
|
|
71
|
-
ON kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
|
|
72
|
-
AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
|
|
73
|
-
WHERE kcu.TABLE_SCHEMA = ?
|
|
74
|
-
AND kcu.TABLE_NAME = ?
|
|
75
|
-
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
76
|
-
ORDER BY kcu.CONSTRAINT_NAME, kcu.ORDINAL_POSITION
|
|
59
|
+
const query = `
|
|
60
|
+
SELECT
|
|
61
|
+
kcu.CONSTRAINT_NAME as constraint_name,
|
|
62
|
+
kcu.COLUMN_NAME as column_name,
|
|
63
|
+
kcu.REFERENCED_TABLE_SCHEMA as referenced_schema,
|
|
64
|
+
kcu.REFERENCED_TABLE_NAME as referenced_table,
|
|
65
|
+
kcu.REFERENCED_COLUMN_NAME as referenced_column,
|
|
66
|
+
kcu.ORDINAL_POSITION as ordinal_position,
|
|
67
|
+
rc.UPDATE_RULE as on_update,
|
|
68
|
+
rc.DELETE_RULE as on_delete
|
|
69
|
+
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
70
|
+
JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
|
|
71
|
+
ON kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
|
|
72
|
+
AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
|
|
73
|
+
WHERE kcu.TABLE_SCHEMA = ?
|
|
74
|
+
AND kcu.TABLE_NAME = ?
|
|
75
|
+
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
76
|
+
ORDER BY kcu.CONSTRAINT_NAME, kcu.ORDINAL_POSITION
|
|
77
77
|
`;
|
|
78
78
|
const results = await this.db.query(query, [database, table_name]);
|
|
79
79
|
// Group by constraint name
|
|
@@ -88,26 +88,24 @@ class ConstraintTools {
|
|
|
88
88
|
referenced_table: row.referenced_table,
|
|
89
89
|
on_update: row.on_update,
|
|
90
90
|
on_delete: row.on_delete,
|
|
91
|
-
columns: []
|
|
91
|
+
columns: [],
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
94
|
fkMap.get(constraintName).columns.push({
|
|
95
95
|
column_name: row.column_name,
|
|
96
96
|
referenced_column: row.referenced_column,
|
|
97
|
-
ordinal_position: row.ordinal_position
|
|
97
|
+
ordinal_position: row.ordinal_position,
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
return {
|
|
101
|
-
status:
|
|
101
|
+
status: "success",
|
|
102
102
|
data: Array.from(fkMap.values()),
|
|
103
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
104
103
|
};
|
|
105
104
|
}
|
|
106
105
|
catch (error) {
|
|
107
106
|
return {
|
|
108
|
-
status:
|
|
107
|
+
status: "error",
|
|
109
108
|
error: error.message,
|
|
110
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
111
109
|
};
|
|
112
110
|
}
|
|
113
111
|
}
|
|
@@ -118,50 +116,50 @@ class ConstraintTools {
|
|
|
118
116
|
try {
|
|
119
117
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
120
118
|
if (!dbValidation.valid) {
|
|
121
|
-
return { status:
|
|
119
|
+
return { status: "error", error: dbValidation.error };
|
|
122
120
|
}
|
|
123
121
|
const { table_name } = params;
|
|
124
122
|
const database = dbValidation.database;
|
|
125
123
|
// Validate table name
|
|
126
124
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
127
|
-
return { status:
|
|
125
|
+
return { status: "error", error: "Invalid table name" };
|
|
128
126
|
}
|
|
129
|
-
const query = `
|
|
130
|
-
SELECT
|
|
131
|
-
tc.CONSTRAINT_NAME as constraint_name,
|
|
132
|
-
tc.CONSTRAINT_TYPE as constraint_type,
|
|
133
|
-
GROUP_CONCAT(kcu.COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION) as columns,
|
|
134
|
-
kcu.REFERENCED_TABLE_NAME as referenced_table,
|
|
135
|
-
GROUP_CONCAT(kcu.REFERENCED_COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION) as referenced_columns
|
|
136
|
-
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
|
137
|
-
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
138
|
-
ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
|
139
|
-
AND tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA
|
|
140
|
-
AND tc.TABLE_NAME = kcu.TABLE_NAME
|
|
141
|
-
WHERE tc.TABLE_SCHEMA = ? AND tc.TABLE_NAME = ?
|
|
142
|
-
GROUP BY tc.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.REFERENCED_TABLE_NAME
|
|
143
|
-
ORDER BY tc.CONSTRAINT_TYPE, tc.CONSTRAINT_NAME
|
|
127
|
+
const query = `
|
|
128
|
+
SELECT
|
|
129
|
+
tc.CONSTRAINT_NAME as constraint_name,
|
|
130
|
+
tc.CONSTRAINT_TYPE as constraint_type,
|
|
131
|
+
GROUP_CONCAT(kcu.COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION) as columns,
|
|
132
|
+
kcu.REFERENCED_TABLE_NAME as referenced_table,
|
|
133
|
+
GROUP_CONCAT(kcu.REFERENCED_COLUMN_NAME ORDER BY kcu.ORDINAL_POSITION) as referenced_columns
|
|
134
|
+
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
|
135
|
+
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
136
|
+
ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
|
137
|
+
AND tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA
|
|
138
|
+
AND tc.TABLE_NAME = kcu.TABLE_NAME
|
|
139
|
+
WHERE tc.TABLE_SCHEMA = ? AND tc.TABLE_NAME = ?
|
|
140
|
+
GROUP BY tc.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.REFERENCED_TABLE_NAME
|
|
141
|
+
ORDER BY tc.CONSTRAINT_TYPE, tc.CONSTRAINT_NAME
|
|
144
142
|
`;
|
|
145
143
|
const results = await this.db.query(query, [database, table_name]);
|
|
146
144
|
// Format results
|
|
147
|
-
const constraints = results.map(row => ({
|
|
145
|
+
const constraints = results.map((row) => ({
|
|
148
146
|
constraint_name: row.constraint_name,
|
|
149
147
|
constraint_type: row.constraint_type,
|
|
150
|
-
columns: row.columns ? row.columns.split(
|
|
148
|
+
columns: row.columns ? row.columns.split(",") : [],
|
|
151
149
|
referenced_table: row.referenced_table || null,
|
|
152
|
-
referenced_columns: row.referenced_columns
|
|
150
|
+
referenced_columns: row.referenced_columns
|
|
151
|
+
? row.referenced_columns.split(",")
|
|
152
|
+
: null,
|
|
153
153
|
}));
|
|
154
154
|
return {
|
|
155
|
-
status:
|
|
155
|
+
status: "success",
|
|
156
156
|
data: constraints,
|
|
157
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
158
157
|
};
|
|
159
158
|
}
|
|
160
159
|
catch (error) {
|
|
161
160
|
return {
|
|
162
|
-
status:
|
|
161
|
+
status: "error",
|
|
163
162
|
error: error.message,
|
|
164
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
165
163
|
};
|
|
166
164
|
}
|
|
167
165
|
}
|
|
@@ -172,63 +170,69 @@ class ConstraintTools {
|
|
|
172
170
|
try {
|
|
173
171
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
174
172
|
if (!dbValidation.valid) {
|
|
175
|
-
return { status:
|
|
173
|
+
return { status: "error", error: dbValidation.error };
|
|
176
174
|
}
|
|
177
|
-
const { table_name, constraint_name, columns, referenced_table, referenced_columns, on_delete =
|
|
175
|
+
const { table_name, constraint_name, columns, referenced_table, referenced_columns, on_delete = "RESTRICT", on_update = "RESTRICT", } = params;
|
|
178
176
|
const database = dbValidation.database;
|
|
179
177
|
// Validate names
|
|
180
178
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
181
|
-
return { status:
|
|
179
|
+
return { status: "error", error: "Invalid table name" };
|
|
182
180
|
}
|
|
183
181
|
if (!this.security.validateIdentifier(constraint_name).valid) {
|
|
184
|
-
return { status:
|
|
182
|
+
return { status: "error", error: "Invalid constraint name" };
|
|
185
183
|
}
|
|
186
184
|
if (!this.security.validateIdentifier(referenced_table).valid) {
|
|
187
|
-
return { status:
|
|
185
|
+
return { status: "error", error: "Invalid referenced table name" };
|
|
188
186
|
}
|
|
189
187
|
// Validate column names
|
|
190
188
|
for (const col of columns) {
|
|
191
189
|
if (!this.security.validateIdentifier(col).valid) {
|
|
192
|
-
return { status:
|
|
190
|
+
return { status: "error", error: `Invalid column name: ${col}` };
|
|
193
191
|
}
|
|
194
192
|
}
|
|
195
193
|
for (const col of referenced_columns) {
|
|
196
194
|
if (!this.security.validateIdentifier(col).valid) {
|
|
197
|
-
return {
|
|
195
|
+
return {
|
|
196
|
+
status: "error",
|
|
197
|
+
error: `Invalid referenced column name: ${col}`,
|
|
198
|
+
};
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
201
|
// Column counts must match
|
|
201
202
|
if (columns.length !== referenced_columns.length) {
|
|
202
|
-
return {
|
|
203
|
+
return {
|
|
204
|
+
status: "error",
|
|
205
|
+
error: "Column count must match referenced column count",
|
|
206
|
+
};
|
|
203
207
|
}
|
|
204
|
-
const columnList = columns.map(c => `\`${c}\``).join(
|
|
205
|
-
const refColumnList = referenced_columns
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
const columnList = columns.map((c) => `\`${c}\``).join(", ");
|
|
209
|
+
const refColumnList = referenced_columns
|
|
210
|
+
.map((c) => `\`${c}\``)
|
|
211
|
+
.join(", ");
|
|
212
|
+
const alterQuery = `
|
|
213
|
+
ALTER TABLE \`${database}\`.\`${table_name}\`
|
|
214
|
+
ADD CONSTRAINT \`${constraint_name}\`
|
|
215
|
+
FOREIGN KEY (${columnList})
|
|
216
|
+
REFERENCES \`${database}\`.\`${referenced_table}\` (${refColumnList})
|
|
217
|
+
ON DELETE ${on_delete}
|
|
218
|
+
ON UPDATE ${on_update}
|
|
213
219
|
`;
|
|
214
220
|
await this.db.query(alterQuery);
|
|
215
221
|
return {
|
|
216
|
-
status:
|
|
222
|
+
status: "success",
|
|
217
223
|
data: {
|
|
218
224
|
message: `Foreign key '${constraint_name}' added successfully`,
|
|
219
225
|
constraint_name,
|
|
220
226
|
table_name,
|
|
221
227
|
referenced_table,
|
|
222
|
-
database
|
|
228
|
+
database,
|
|
223
229
|
},
|
|
224
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
225
230
|
};
|
|
226
231
|
}
|
|
227
232
|
catch (error) {
|
|
228
233
|
return {
|
|
229
|
-
status:
|
|
234
|
+
status: "error",
|
|
230
235
|
error: error.message,
|
|
231
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
232
236
|
};
|
|
233
237
|
}
|
|
234
238
|
}
|
|
@@ -239,30 +243,28 @@ class ConstraintTools {
|
|
|
239
243
|
try {
|
|
240
244
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
241
245
|
if (!dbValidation.valid) {
|
|
242
|
-
return { status:
|
|
246
|
+
return { status: "error", error: dbValidation.error };
|
|
243
247
|
}
|
|
244
248
|
const { table_name, constraint_name } = params;
|
|
245
249
|
const database = dbValidation.database;
|
|
246
250
|
// Validate names
|
|
247
251
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
248
|
-
return { status:
|
|
252
|
+
return { status: "error", error: "Invalid table name" };
|
|
249
253
|
}
|
|
250
254
|
if (!this.security.validateIdentifier(constraint_name).valid) {
|
|
251
|
-
return { status:
|
|
255
|
+
return { status: "error", error: "Invalid constraint name" };
|
|
252
256
|
}
|
|
253
257
|
const alterQuery = `ALTER TABLE \`${database}\`.\`${table_name}\` DROP FOREIGN KEY \`${constraint_name}\``;
|
|
254
258
|
await this.db.query(alterQuery);
|
|
255
259
|
return {
|
|
256
|
-
status:
|
|
260
|
+
status: "success",
|
|
257
261
|
message: `Foreign key '${constraint_name}' dropped successfully from table '${table_name}'`,
|
|
258
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
259
262
|
};
|
|
260
263
|
}
|
|
261
264
|
catch (error) {
|
|
262
265
|
return {
|
|
263
|
-
status:
|
|
266
|
+
status: "error",
|
|
264
267
|
error: error.message,
|
|
265
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
266
268
|
};
|
|
267
269
|
}
|
|
268
270
|
}
|
|
@@ -273,43 +275,41 @@ class ConstraintTools {
|
|
|
273
275
|
try {
|
|
274
276
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
275
277
|
if (!dbValidation.valid) {
|
|
276
|
-
return { status:
|
|
278
|
+
return { status: "error", error: dbValidation.error };
|
|
277
279
|
}
|
|
278
280
|
const { table_name, constraint_name, columns } = params;
|
|
279
281
|
const database = dbValidation.database;
|
|
280
282
|
// Validate names
|
|
281
283
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
282
|
-
return { status:
|
|
284
|
+
return { status: "error", error: "Invalid table name" };
|
|
283
285
|
}
|
|
284
286
|
if (!this.security.validateIdentifier(constraint_name).valid) {
|
|
285
|
-
return { status:
|
|
287
|
+
return { status: "error", error: "Invalid constraint name" };
|
|
286
288
|
}
|
|
287
289
|
// Validate column names
|
|
288
290
|
for (const col of columns) {
|
|
289
291
|
if (!this.security.validateIdentifier(col).valid) {
|
|
290
|
-
return { status:
|
|
292
|
+
return { status: "error", error: `Invalid column name: ${col}` };
|
|
291
293
|
}
|
|
292
294
|
}
|
|
293
|
-
const columnList = columns.map(c => `\`${c}\``).join(
|
|
295
|
+
const columnList = columns.map((c) => `\`${c}\``).join(", ");
|
|
294
296
|
const alterQuery = `ALTER TABLE \`${database}\`.\`${table_name}\` ADD CONSTRAINT \`${constraint_name}\` UNIQUE (${columnList})`;
|
|
295
297
|
await this.db.query(alterQuery);
|
|
296
298
|
return {
|
|
297
|
-
status:
|
|
299
|
+
status: "success",
|
|
298
300
|
data: {
|
|
299
301
|
message: `Unique constraint '${constraint_name}' added successfully`,
|
|
300
302
|
constraint_name,
|
|
301
303
|
table_name,
|
|
302
304
|
columns,
|
|
303
|
-
database
|
|
305
|
+
database,
|
|
304
306
|
},
|
|
305
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
306
307
|
};
|
|
307
308
|
}
|
|
308
309
|
catch (error) {
|
|
309
310
|
return {
|
|
310
|
-
status:
|
|
311
|
+
status: "error",
|
|
311
312
|
error: error.message,
|
|
312
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
313
313
|
};
|
|
314
314
|
}
|
|
315
315
|
}
|
|
@@ -320,40 +320,41 @@ class ConstraintTools {
|
|
|
320
320
|
try {
|
|
321
321
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
322
322
|
if (!dbValidation.valid) {
|
|
323
|
-
return { status:
|
|
323
|
+
return { status: "error", error: dbValidation.error };
|
|
324
324
|
}
|
|
325
325
|
const { table_name, constraint_name, constraint_type } = params;
|
|
326
326
|
const database = dbValidation.database;
|
|
327
327
|
// Validate names
|
|
328
328
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
329
|
-
return { status:
|
|
329
|
+
return { status: "error", error: "Invalid table name" };
|
|
330
330
|
}
|
|
331
331
|
if (!this.security.validateIdentifier(constraint_name).valid) {
|
|
332
|
-
return { status:
|
|
332
|
+
return { status: "error", error: "Invalid constraint name" };
|
|
333
333
|
}
|
|
334
334
|
let alterQuery;
|
|
335
|
-
if (constraint_type ===
|
|
335
|
+
if (constraint_type === "UNIQUE") {
|
|
336
336
|
// UNIQUE constraints are implemented as indexes in MySQL
|
|
337
337
|
alterQuery = `ALTER TABLE \`${database}\`.\`${table_name}\` DROP INDEX \`${constraint_name}\``;
|
|
338
338
|
}
|
|
339
|
-
else if (constraint_type ===
|
|
339
|
+
else if (constraint_type === "CHECK") {
|
|
340
340
|
alterQuery = `ALTER TABLE \`${database}\`.\`${table_name}\` DROP CHECK \`${constraint_name}\``;
|
|
341
341
|
}
|
|
342
342
|
else {
|
|
343
|
-
return {
|
|
343
|
+
return {
|
|
344
|
+
status: "error",
|
|
345
|
+
error: "Invalid constraint type. Use UNIQUE or CHECK.",
|
|
346
|
+
};
|
|
344
347
|
}
|
|
345
348
|
await this.db.query(alterQuery);
|
|
346
349
|
return {
|
|
347
|
-
status:
|
|
350
|
+
status: "success",
|
|
348
351
|
message: `${constraint_type} constraint '${constraint_name}' dropped successfully from table '${table_name}'`,
|
|
349
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
350
352
|
};
|
|
351
353
|
}
|
|
352
354
|
catch (error) {
|
|
353
355
|
return {
|
|
354
|
-
status:
|
|
356
|
+
status: "error",
|
|
355
357
|
error: error.message,
|
|
356
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
357
358
|
};
|
|
358
359
|
}
|
|
359
360
|
}
|
|
@@ -364,40 +365,38 @@ class ConstraintTools {
|
|
|
364
365
|
try {
|
|
365
366
|
const dbValidation = this.validateDatabaseAccess(params?.database);
|
|
366
367
|
if (!dbValidation.valid) {
|
|
367
|
-
return { status:
|
|
368
|
+
return { status: "error", error: dbValidation.error };
|
|
368
369
|
}
|
|
369
|
-
const { table_name, constraint_name, expression, enforced = true } = params;
|
|
370
|
+
const { table_name, constraint_name, expression, enforced = true, } = params;
|
|
370
371
|
const database = dbValidation.database;
|
|
371
372
|
// Validate names
|
|
372
373
|
if (!this.security.validateIdentifier(table_name).valid) {
|
|
373
|
-
return { status:
|
|
374
|
+
return { status: "error", error: "Invalid table name" };
|
|
374
375
|
}
|
|
375
376
|
if (!this.security.validateIdentifier(constraint_name).valid) {
|
|
376
|
-
return { status:
|
|
377
|
+
return { status: "error", error: "Invalid constraint name" };
|
|
377
378
|
}
|
|
378
379
|
let alterQuery = `ALTER TABLE \`${database}\`.\`${table_name}\` ADD CONSTRAINT \`${constraint_name}\` CHECK (${expression})`;
|
|
379
380
|
if (!enforced) {
|
|
380
|
-
alterQuery +=
|
|
381
|
+
alterQuery += " NOT ENFORCED";
|
|
381
382
|
}
|
|
382
383
|
await this.db.query(alterQuery);
|
|
383
384
|
return {
|
|
384
|
-
status:
|
|
385
|
+
status: "success",
|
|
385
386
|
data: {
|
|
386
387
|
message: `Check constraint '${constraint_name}' added successfully`,
|
|
387
388
|
constraint_name,
|
|
388
389
|
table_name,
|
|
389
390
|
expression,
|
|
390
391
|
enforced,
|
|
391
|
-
database
|
|
392
|
+
database,
|
|
392
393
|
},
|
|
393
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
394
394
|
};
|
|
395
395
|
}
|
|
396
396
|
catch (error) {
|
|
397
397
|
return {
|
|
398
|
-
status:
|
|
398
|
+
status: "error",
|
|
399
399
|
error: error.message,
|
|
400
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
401
400
|
};
|
|
402
401
|
}
|
|
403
402
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import SecurityLayer from
|
|
2
|
-
import { FilterCondition, Pagination, Sorting } from
|
|
1
|
+
import SecurityLayer from "../security/securityLayer";
|
|
2
|
+
import { FilterCondition, Pagination, Sorting } from "../validation/schemas";
|
|
3
3
|
export declare class CrudTools {
|
|
4
4
|
private db;
|
|
5
5
|
private security;
|
|
@@ -14,7 +14,6 @@ export declare class CrudTools {
|
|
|
14
14
|
status: string;
|
|
15
15
|
data?: any;
|
|
16
16
|
error?: string;
|
|
17
|
-
queryLog?: string;
|
|
18
17
|
}>;
|
|
19
18
|
/**
|
|
20
19
|
* Read records from the specified table with optional filters, pagination, and sorting
|
|
@@ -29,7 +28,6 @@ export declare class CrudTools {
|
|
|
29
28
|
data?: any[];
|
|
30
29
|
total?: number;
|
|
31
30
|
error?: string;
|
|
32
|
-
queryLog?: string;
|
|
33
31
|
}>;
|
|
34
32
|
/**
|
|
35
33
|
* Update records in the specified table based on conditions
|
|
@@ -44,7 +42,6 @@ export declare class CrudTools {
|
|
|
44
42
|
affectedRows: number;
|
|
45
43
|
};
|
|
46
44
|
error?: string;
|
|
47
|
-
queryLog?: string;
|
|
48
45
|
}>;
|
|
49
46
|
/**
|
|
50
47
|
* Delete records from the specified table based on conditions
|
|
@@ -58,7 +55,6 @@ export declare class CrudTools {
|
|
|
58
55
|
affectedRows: number;
|
|
59
56
|
};
|
|
60
57
|
error?: string;
|
|
61
|
-
queryLog?: string;
|
|
62
58
|
}>;
|
|
63
59
|
/**
|
|
64
60
|
* Bulk insert multiple records into the specified table
|