@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
|
@@ -25,7 +25,6 @@ export declare class DataExportTools {
|
|
|
25
25
|
status: string;
|
|
26
26
|
data?: any;
|
|
27
27
|
error?: string;
|
|
28
|
-
queryLog?: string;
|
|
29
28
|
}>;
|
|
30
29
|
/**
|
|
31
30
|
* Export query results to CSV format
|
|
@@ -38,7 +37,6 @@ export declare class DataExportTools {
|
|
|
38
37
|
status: string;
|
|
39
38
|
data?: any;
|
|
40
39
|
error?: string;
|
|
41
|
-
queryLog?: string;
|
|
42
40
|
}>;
|
|
43
41
|
/**
|
|
44
42
|
* Export table data to JSON format
|
|
@@ -54,7 +52,6 @@ export declare class DataExportTools {
|
|
|
54
52
|
status: string;
|
|
55
53
|
data?: any;
|
|
56
54
|
error?: string;
|
|
57
|
-
queryLog?: string;
|
|
58
55
|
}>;
|
|
59
56
|
/**
|
|
60
57
|
* Export query results to JSON format
|
|
@@ -67,7 +64,6 @@ export declare class DataExportTools {
|
|
|
67
64
|
status: string;
|
|
68
65
|
data?: any;
|
|
69
66
|
error?: string;
|
|
70
|
-
queryLog?: string;
|
|
71
67
|
}>;
|
|
72
68
|
/**
|
|
73
69
|
* Export table data to SQL INSERT statements
|
|
@@ -82,7 +78,6 @@ export declare class DataExportTools {
|
|
|
82
78
|
status: string;
|
|
83
79
|
data?: any;
|
|
84
80
|
error?: string;
|
|
85
|
-
queryLog?: string;
|
|
86
81
|
}>;
|
|
87
82
|
/**
|
|
88
83
|
* Import data from CSV string
|
|
@@ -99,7 +94,6 @@ export declare class DataExportTools {
|
|
|
99
94
|
status: string;
|
|
100
95
|
data?: any;
|
|
101
96
|
error?: string;
|
|
102
|
-
queryLog?: string;
|
|
103
97
|
}>;
|
|
104
98
|
/**
|
|
105
99
|
* Parse CSV string into array of arrays
|
|
@@ -119,6 +113,5 @@ export declare class DataExportTools {
|
|
|
119
113
|
status: string;
|
|
120
114
|
data?: any;
|
|
121
115
|
error?: string;
|
|
122
|
-
queryLog?: string;
|
|
123
116
|
}>;
|
|
124
117
|
}
|
|
@@ -252,7 +252,6 @@ class DataExportTools {
|
|
|
252
252
|
csv: include_headers ? "" : "",
|
|
253
253
|
row_count: 0,
|
|
254
254
|
},
|
|
255
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
256
255
|
};
|
|
257
256
|
}
|
|
258
257
|
// Generate CSV
|
|
@@ -288,14 +287,12 @@ class DataExportTools {
|
|
|
288
287
|
csv: csv,
|
|
289
288
|
row_count: results.length,
|
|
290
289
|
},
|
|
291
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
292
290
|
};
|
|
293
291
|
}
|
|
294
292
|
catch (error) {
|
|
295
293
|
return {
|
|
296
294
|
status: "error",
|
|
297
295
|
error: error.message,
|
|
298
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
299
296
|
};
|
|
300
297
|
}
|
|
301
298
|
}
|
|
@@ -417,14 +414,12 @@ class DataExportTools {
|
|
|
417
414
|
row_count: results.length,
|
|
418
415
|
table_name: table_name,
|
|
419
416
|
},
|
|
420
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
421
417
|
};
|
|
422
418
|
}
|
|
423
419
|
catch (error) {
|
|
424
420
|
return {
|
|
425
421
|
status: "error",
|
|
426
422
|
error: error.message,
|
|
427
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
428
423
|
};
|
|
429
424
|
}
|
|
430
425
|
}
|
|
@@ -458,14 +453,12 @@ class DataExportTools {
|
|
|
458
453
|
json: json,
|
|
459
454
|
row_count: results.length,
|
|
460
455
|
},
|
|
461
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
462
456
|
};
|
|
463
457
|
}
|
|
464
458
|
catch (error) {
|
|
465
459
|
return {
|
|
466
460
|
status: "error",
|
|
467
461
|
error: error.message,
|
|
468
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
469
462
|
};
|
|
470
463
|
}
|
|
471
464
|
}
|
|
@@ -594,14 +587,12 @@ class DataExportTools {
|
|
|
594
587
|
row_count: results.length,
|
|
595
588
|
table_name: table_name,
|
|
596
589
|
},
|
|
597
|
-
queryLog: this.db.getFormattedQueryLogs(queryCount),
|
|
598
590
|
};
|
|
599
591
|
}
|
|
600
592
|
catch (error) {
|
|
601
593
|
return {
|
|
602
594
|
status: "error",
|
|
603
595
|
error: error.message,
|
|
604
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
605
596
|
};
|
|
606
597
|
}
|
|
607
598
|
}
|
|
@@ -710,7 +701,6 @@ class DataExportTools {
|
|
|
710
701
|
status: "error",
|
|
711
702
|
error: `Import failed at row ${i + 1}: ${error.message}`,
|
|
712
703
|
data: { rows_imported: successCount },
|
|
713
|
-
queryLog: this.db.getFormattedQueryLogs(queryCount),
|
|
714
704
|
};
|
|
715
705
|
}
|
|
716
706
|
}
|
|
@@ -725,14 +715,12 @@ class DataExportTools {
|
|
|
725
715
|
rows_failed: errorCount,
|
|
726
716
|
errors: errors.length > 0 ? errors.slice(0, 10) : undefined,
|
|
727
717
|
},
|
|
728
|
-
queryLog: this.db.getFormattedQueryLogs(queryCount),
|
|
729
718
|
};
|
|
730
719
|
}
|
|
731
720
|
catch (error) {
|
|
732
721
|
return {
|
|
733
722
|
status: "error",
|
|
734
723
|
error: error.message,
|
|
735
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
736
724
|
};
|
|
737
725
|
}
|
|
738
726
|
}
|
|
@@ -873,7 +861,6 @@ class DataExportTools {
|
|
|
873
861
|
status: "error",
|
|
874
862
|
error: `Import failed at row ${i + 1}: ${error.message}`,
|
|
875
863
|
data: { rows_imported: successCount },
|
|
876
|
-
queryLog: this.db.getFormattedQueryLogs(queryCount),
|
|
877
864
|
};
|
|
878
865
|
}
|
|
879
866
|
}
|
|
@@ -888,14 +875,12 @@ class DataExportTools {
|
|
|
888
875
|
rows_failed: errorCount,
|
|
889
876
|
errors: errors.length > 0 ? errors.slice(0, 10) : undefined,
|
|
890
877
|
},
|
|
891
|
-
queryLog: this.db.getFormattedQueryLogs(queryCount),
|
|
892
878
|
};
|
|
893
879
|
}
|
|
894
880
|
catch (error) {
|
|
895
881
|
return {
|
|
896
882
|
status: "error",
|
|
897
883
|
error: error.message,
|
|
898
|
-
queryLog: this.db.getFormattedQueryLogs(1),
|
|
899
884
|
};
|
|
900
885
|
}
|
|
901
886
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TableInfo, ColumnInfo } from
|
|
1
|
+
import { TableInfo, ColumnInfo } from "../validation/schemas";
|
|
2
2
|
export declare class DatabaseTools {
|
|
3
3
|
private db;
|
|
4
4
|
constructor();
|
|
@@ -10,7 +10,6 @@ export declare class DatabaseTools {
|
|
|
10
10
|
status: string;
|
|
11
11
|
data?: string[];
|
|
12
12
|
error?: string;
|
|
13
|
-
queryLog?: string;
|
|
14
13
|
}>;
|
|
15
14
|
/**
|
|
16
15
|
* List all tables in the selected database
|
|
@@ -21,7 +20,6 @@ export declare class DatabaseTools {
|
|
|
21
20
|
status: string;
|
|
22
21
|
data?: TableInfo[];
|
|
23
22
|
error?: string;
|
|
24
|
-
queryLog?: string;
|
|
25
23
|
}>;
|
|
26
24
|
/**
|
|
27
25
|
* Read table schema (columns, types, keys, etc.)
|
|
@@ -32,6 +30,5 @@ export declare class DatabaseTools {
|
|
|
32
30
|
status: string;
|
|
33
31
|
data?: ColumnInfo[];
|
|
34
32
|
error?: string;
|
|
35
|
-
queryLog?: string;
|
|
36
33
|
}>;
|
|
37
34
|
}
|
|
@@ -21,31 +21,28 @@ class DatabaseTools {
|
|
|
21
21
|
// This is a security measure to prevent access to other databases
|
|
22
22
|
if (!config_1.dbConfig.database) {
|
|
23
23
|
return {
|
|
24
|
-
status:
|
|
25
|
-
error:
|
|
24
|
+
status: "error",
|
|
25
|
+
error: "No database specified in connection string. Please specify a database name in your MySQL connection URL.",
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
// Verify the database exists and is accessible
|
|
29
|
-
const results = await this.db.query(
|
|
29
|
+
const results = await this.db.query("SELECT DATABASE() as current_database");
|
|
30
30
|
const currentDatabase = results[0]?.current_database;
|
|
31
31
|
if (!currentDatabase) {
|
|
32
32
|
return {
|
|
33
|
-
status:
|
|
34
|
-
error:
|
|
35
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
33
|
+
status: "error",
|
|
34
|
+
error: "No database selected. Please ensure your connection string includes a valid database name.",
|
|
36
35
|
};
|
|
37
36
|
}
|
|
38
37
|
return {
|
|
39
|
-
status:
|
|
38
|
+
status: "success",
|
|
40
39
|
data: [currentDatabase],
|
|
41
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
42
40
|
};
|
|
43
41
|
}
|
|
44
42
|
catch (error) {
|
|
45
43
|
return {
|
|
46
|
-
status:
|
|
44
|
+
status: "error",
|
|
47
45
|
error: error.message,
|
|
48
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
49
46
|
};
|
|
50
47
|
}
|
|
51
48
|
}
|
|
@@ -56,8 +53,8 @@ class DatabaseTools {
|
|
|
56
53
|
// Validate input
|
|
57
54
|
if (!(0, schemas_1.validateListTables)(params)) {
|
|
58
55
|
return {
|
|
59
|
-
status:
|
|
60
|
-
error:
|
|
56
|
+
status: "error",
|
|
57
|
+
error: "Invalid parameters: " + JSON.stringify(schemas_1.validateListTables.errors),
|
|
61
58
|
};
|
|
62
59
|
}
|
|
63
60
|
try {
|
|
@@ -65,39 +62,37 @@ class DatabaseTools {
|
|
|
65
62
|
if (params.database) {
|
|
66
63
|
if (!config_1.dbConfig.database) {
|
|
67
64
|
return {
|
|
68
|
-
status:
|
|
69
|
-
error:
|
|
65
|
+
status: "error",
|
|
66
|
+
error: "No database specified in connection string. Cannot access other databases.",
|
|
70
67
|
};
|
|
71
68
|
}
|
|
72
69
|
if (params.database !== config_1.dbConfig.database) {
|
|
73
70
|
return {
|
|
74
|
-
status:
|
|
75
|
-
error: `Access denied. You can only access the connected database '${config_1.dbConfig.database}'. Requested database '${params.database}' is not allowed
|
|
71
|
+
status: "error",
|
|
72
|
+
error: `Access denied. You can only access the connected database '${config_1.dbConfig.database}'. Requested database '${params.database}' is not allowed.`,
|
|
76
73
|
};
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
|
-
let query =
|
|
76
|
+
let query = "SHOW TABLES";
|
|
80
77
|
// If database is specified and validated, use it
|
|
81
78
|
if (params.database) {
|
|
82
79
|
query = `SHOW TABLES FROM \`${params.database}\``;
|
|
83
80
|
}
|
|
84
81
|
const results = await this.db.query(query);
|
|
85
|
-
const tables = results.map(row => {
|
|
82
|
+
const tables = results.map((row) => {
|
|
86
83
|
// Extract the table name from the first column (which might have different names)
|
|
87
84
|
const firstColumnName = Object.keys(row)[0];
|
|
88
85
|
return { table_name: row[firstColumnName] };
|
|
89
86
|
});
|
|
90
87
|
return {
|
|
91
|
-
status:
|
|
88
|
+
status: "success",
|
|
92
89
|
data: tables,
|
|
93
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
94
90
|
};
|
|
95
91
|
}
|
|
96
92
|
catch (error) {
|
|
97
93
|
return {
|
|
98
|
-
status:
|
|
94
|
+
status: "error",
|
|
99
95
|
error: error.message,
|
|
100
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
101
96
|
};
|
|
102
97
|
}
|
|
103
98
|
}
|
|
@@ -108,38 +103,39 @@ class DatabaseTools {
|
|
|
108
103
|
// Validate input
|
|
109
104
|
if (!(0, schemas_1.validateReadTableSchema)(params)) {
|
|
110
105
|
return {
|
|
111
|
-
status:
|
|
112
|
-
error:
|
|
106
|
+
status: "error",
|
|
107
|
+
error: "Invalid parameters: " +
|
|
108
|
+
JSON.stringify(schemas_1.validateReadTableSchema.errors),
|
|
113
109
|
};
|
|
114
110
|
}
|
|
115
111
|
try {
|
|
116
112
|
const query = `
|
|
117
|
-
SELECT
|
|
113
|
+
SELECT
|
|
118
114
|
COLUMN_NAME as column_name,
|
|
119
115
|
DATA_TYPE as data_type,
|
|
120
116
|
IS_NULLABLE as is_nullable,
|
|
121
117
|
COLUMN_KEY as column_key,
|
|
122
118
|
COLUMN_DEFAULT as column_default,
|
|
123
119
|
EXTRA as extra
|
|
124
|
-
FROM
|
|
120
|
+
FROM
|
|
125
121
|
INFORMATION_SCHEMA.COLUMNS
|
|
126
|
-
WHERE
|
|
122
|
+
WHERE
|
|
127
123
|
TABLE_NAME = ?
|
|
128
|
-
ORDER BY
|
|
124
|
+
ORDER BY
|
|
129
125
|
ORDINAL_POSITION
|
|
130
126
|
`;
|
|
131
|
-
const results = await this.db.query(query, [
|
|
127
|
+
const results = await this.db.query(query, [
|
|
128
|
+
params.table_name,
|
|
129
|
+
]);
|
|
132
130
|
return {
|
|
133
|
-
status:
|
|
131
|
+
status: "success",
|
|
134
132
|
data: results,
|
|
135
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
136
133
|
};
|
|
137
134
|
}
|
|
138
135
|
catch (error) {
|
|
139
136
|
return {
|
|
140
|
-
status:
|
|
137
|
+
status: "error",
|
|
141
138
|
error: error.message,
|
|
142
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
143
139
|
};
|
|
144
140
|
}
|
|
145
141
|
}
|
package/dist/tools/ddlTools.d.ts
CHANGED
|
@@ -23,7 +23,6 @@ export declare class DdlTools {
|
|
|
23
23
|
status: string;
|
|
24
24
|
data?: any;
|
|
25
25
|
error?: string;
|
|
26
|
-
queryLog?: string;
|
|
27
26
|
}>;
|
|
28
27
|
/**
|
|
29
28
|
* Alter an existing table
|
|
@@ -31,7 +30,7 @@ export declare class DdlTools {
|
|
|
31
30
|
alterTable(params: {
|
|
32
31
|
table_name: string;
|
|
33
32
|
operations: Array<{
|
|
34
|
-
type:
|
|
33
|
+
type: "add_column" | "drop_column" | "modify_column" | "rename_column" | "add_index" | "drop_index";
|
|
35
34
|
column_name?: string;
|
|
36
35
|
new_column_name?: string;
|
|
37
36
|
column_type?: string;
|
|
@@ -45,7 +44,6 @@ export declare class DdlTools {
|
|
|
45
44
|
status: string;
|
|
46
45
|
data?: any;
|
|
47
46
|
error?: string;
|
|
48
|
-
queryLog?: string;
|
|
49
47
|
}>;
|
|
50
48
|
/**
|
|
51
49
|
* Drop a table
|
|
@@ -57,7 +55,6 @@ export declare class DdlTools {
|
|
|
57
55
|
status: string;
|
|
58
56
|
data?: any;
|
|
59
57
|
error?: string;
|
|
60
|
-
queryLog?: string;
|
|
61
58
|
}>;
|
|
62
59
|
/**
|
|
63
60
|
* Execute raw DDL SQL
|
|
@@ -68,6 +65,5 @@ export declare class DdlTools {
|
|
|
68
65
|
status: string;
|
|
69
66
|
data?: any;
|
|
70
67
|
error?: string;
|
|
71
|
-
queryLog?: string;
|
|
72
68
|
}>;
|
|
73
69
|
}
|
package/dist/tools/ddlTools.js
CHANGED
|
@@ -16,22 +16,24 @@ class DdlTools {
|
|
|
16
16
|
try {
|
|
17
17
|
const { table_name, columns, indexes } = params;
|
|
18
18
|
// Build column definitions
|
|
19
|
-
const columnDefs = columns
|
|
19
|
+
const columnDefs = columns
|
|
20
|
+
.map((col) => {
|
|
20
21
|
let def = `\`${col.name}\` ${col.type}`;
|
|
21
22
|
if (col.nullable === false) {
|
|
22
|
-
def +=
|
|
23
|
+
def += " NOT NULL";
|
|
23
24
|
}
|
|
24
25
|
if (col.auto_increment) {
|
|
25
|
-
def +=
|
|
26
|
+
def += " AUTO_INCREMENT";
|
|
26
27
|
}
|
|
27
28
|
if (col.default !== undefined) {
|
|
28
29
|
def += ` DEFAULT ${col.default}`;
|
|
29
30
|
}
|
|
30
31
|
if (col.primary_key) {
|
|
31
|
-
def +=
|
|
32
|
+
def += " PRIMARY KEY";
|
|
32
33
|
}
|
|
33
34
|
return def;
|
|
34
|
-
})
|
|
35
|
+
})
|
|
36
|
+
.join(", ");
|
|
35
37
|
// Build the CREATE TABLE query
|
|
36
38
|
let query = `CREATE TABLE \`${table_name}\` (${columnDefs})`;
|
|
37
39
|
// Execute the query
|
|
@@ -40,27 +42,25 @@ class DdlTools {
|
|
|
40
42
|
let queryCount = 1;
|
|
41
43
|
if (indexes && indexes.length > 0) {
|
|
42
44
|
for (const index of indexes) {
|
|
43
|
-
const indexType = index.unique ?
|
|
44
|
-
const indexColumns = index.columns.map(c => `\`${c}\``).join(
|
|
45
|
+
const indexType = index.unique ? "UNIQUE INDEX" : "INDEX";
|
|
46
|
+
const indexColumns = index.columns.map((c) => `\`${c}\``).join(", ");
|
|
45
47
|
const indexQuery = `CREATE ${indexType} \`${index.name}\` ON \`${table_name}\` (${indexColumns})`;
|
|
46
48
|
await this.db.query(indexQuery);
|
|
47
49
|
queryCount++;
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
return {
|
|
51
|
-
status:
|
|
53
|
+
status: "success",
|
|
52
54
|
data: {
|
|
53
55
|
message: `Table '${table_name}' created successfully`,
|
|
54
|
-
table_name
|
|
56
|
+
table_name,
|
|
55
57
|
},
|
|
56
|
-
queryLog: this.db.getFormattedQueryLogs(queryCount)
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
catch (error) {
|
|
60
61
|
return {
|
|
61
|
-
status:
|
|
62
|
+
status: "error",
|
|
62
63
|
error: error.message,
|
|
63
|
-
queryLog: this.db.getFormattedQueryLogs(10)
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -73,72 +73,91 @@ class DdlTools {
|
|
|
73
73
|
for (const op of operations) {
|
|
74
74
|
let query = `ALTER TABLE \`${table_name}\``;
|
|
75
75
|
switch (op.type) {
|
|
76
|
-
case
|
|
76
|
+
case "add_column":
|
|
77
77
|
if (!op.column_name || !op.column_type) {
|
|
78
|
-
return {
|
|
78
|
+
return {
|
|
79
|
+
status: "error",
|
|
80
|
+
error: "column_name and column_type required for add_column",
|
|
81
|
+
};
|
|
79
82
|
}
|
|
80
83
|
query += ` ADD COLUMN \`${op.column_name}\` ${op.column_type}`;
|
|
81
84
|
if (op.nullable === false)
|
|
82
|
-
query +=
|
|
85
|
+
query += " NOT NULL";
|
|
83
86
|
if (op.default !== undefined)
|
|
84
87
|
query += ` DEFAULT ${op.default}`;
|
|
85
88
|
break;
|
|
86
|
-
case
|
|
89
|
+
case "drop_column":
|
|
87
90
|
if (!op.column_name) {
|
|
88
|
-
return {
|
|
91
|
+
return {
|
|
92
|
+
status: "error",
|
|
93
|
+
error: "column_name required for drop_column",
|
|
94
|
+
};
|
|
89
95
|
}
|
|
90
96
|
query += ` DROP COLUMN \`${op.column_name}\``;
|
|
91
97
|
break;
|
|
92
|
-
case
|
|
98
|
+
case "modify_column":
|
|
93
99
|
if (!op.column_name || !op.column_type) {
|
|
94
|
-
return {
|
|
100
|
+
return {
|
|
101
|
+
status: "error",
|
|
102
|
+
error: "column_name and column_type required for modify_column",
|
|
103
|
+
};
|
|
95
104
|
}
|
|
96
105
|
query += ` MODIFY COLUMN \`${op.column_name}\` ${op.column_type}`;
|
|
97
106
|
if (op.nullable === false)
|
|
98
|
-
query +=
|
|
107
|
+
query += " NOT NULL";
|
|
99
108
|
if (op.default !== undefined)
|
|
100
109
|
query += ` DEFAULT ${op.default}`;
|
|
101
110
|
break;
|
|
102
|
-
case
|
|
111
|
+
case "rename_column":
|
|
103
112
|
if (!op.column_name || !op.new_column_name || !op.column_type) {
|
|
104
|
-
return {
|
|
113
|
+
return {
|
|
114
|
+
status: "error",
|
|
115
|
+
error: "column_name, new_column_name, and column_type required for rename_column",
|
|
116
|
+
};
|
|
105
117
|
}
|
|
106
118
|
query += ` CHANGE COLUMN \`${op.column_name}\` \`${op.new_column_name}\` ${op.column_type}`;
|
|
107
119
|
break;
|
|
108
|
-
case
|
|
120
|
+
case "add_index":
|
|
109
121
|
if (!op.index_name || !op.index_columns) {
|
|
110
|
-
return {
|
|
122
|
+
return {
|
|
123
|
+
status: "error",
|
|
124
|
+
error: "index_name and index_columns required for add_index",
|
|
125
|
+
};
|
|
111
126
|
}
|
|
112
|
-
const indexType = op.unique ?
|
|
113
|
-
const columns = op.index_columns.map(c => `\`${c}\``).join(
|
|
127
|
+
const indexType = op.unique ? "UNIQUE INDEX" : "INDEX";
|
|
128
|
+
const columns = op.index_columns.map((c) => `\`${c}\``).join(", ");
|
|
114
129
|
query += ` ADD ${indexType} \`${op.index_name}\` (${columns})`;
|
|
115
130
|
break;
|
|
116
|
-
case
|
|
131
|
+
case "drop_index":
|
|
117
132
|
if (!op.index_name) {
|
|
118
|
-
return {
|
|
133
|
+
return {
|
|
134
|
+
status: "error",
|
|
135
|
+
error: "index_name required for drop_index",
|
|
136
|
+
};
|
|
119
137
|
}
|
|
120
138
|
query += ` DROP INDEX \`${op.index_name}\``;
|
|
121
139
|
break;
|
|
122
140
|
default:
|
|
123
|
-
return {
|
|
141
|
+
return {
|
|
142
|
+
status: "error",
|
|
143
|
+
error: `Unknown operation type: ${op.type}`,
|
|
144
|
+
};
|
|
124
145
|
}
|
|
125
146
|
await this.db.query(query);
|
|
126
147
|
}
|
|
127
148
|
return {
|
|
128
|
-
status:
|
|
149
|
+
status: "success",
|
|
129
150
|
data: {
|
|
130
151
|
message: `Table '${table_name}' altered successfully`,
|
|
131
152
|
table_name,
|
|
132
|
-
operations_count: operations.length
|
|
153
|
+
operations_count: operations.length,
|
|
133
154
|
},
|
|
134
|
-
queryLog: this.db.getFormattedQueryLogs(operations.length)
|
|
135
155
|
};
|
|
136
156
|
}
|
|
137
157
|
catch (error) {
|
|
138
158
|
return {
|
|
139
|
-
status:
|
|
159
|
+
status: "error",
|
|
140
160
|
error: error.message,
|
|
141
|
-
queryLog: this.db.getFormattedQueryLogs(10)
|
|
142
161
|
};
|
|
143
162
|
}
|
|
144
163
|
}
|
|
@@ -148,23 +167,21 @@ class DdlTools {
|
|
|
148
167
|
async dropTable(params) {
|
|
149
168
|
try {
|
|
150
169
|
const { table_name, if_exists } = params;
|
|
151
|
-
const ifExistsClause = if_exists ?
|
|
170
|
+
const ifExistsClause = if_exists ? "IF EXISTS " : "";
|
|
152
171
|
const query = `DROP TABLE ${ifExistsClause}\`${table_name}\``;
|
|
153
172
|
await this.db.query(query);
|
|
154
173
|
return {
|
|
155
|
-
status:
|
|
174
|
+
status: "success",
|
|
156
175
|
data: {
|
|
157
176
|
message: `Table '${table_name}' dropped successfully`,
|
|
158
|
-
table_name
|
|
177
|
+
table_name,
|
|
159
178
|
},
|
|
160
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
161
179
|
};
|
|
162
180
|
}
|
|
163
181
|
catch (error) {
|
|
164
182
|
return {
|
|
165
|
-
status:
|
|
183
|
+
status: "error",
|
|
166
184
|
error: error.message,
|
|
167
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
168
185
|
};
|
|
169
186
|
}
|
|
170
187
|
}
|
|
@@ -176,32 +193,30 @@ class DdlTools {
|
|
|
176
193
|
const { query } = params;
|
|
177
194
|
// Basic validation - ensure it's a DDL query
|
|
178
195
|
const upperQuery = query.trim().toUpperCase();
|
|
179
|
-
const isDdl = upperQuery.startsWith(
|
|
180
|
-
upperQuery.startsWith(
|
|
181
|
-
upperQuery.startsWith(
|
|
182
|
-
upperQuery.startsWith(
|
|
183
|
-
upperQuery.startsWith(
|
|
196
|
+
const isDdl = upperQuery.startsWith("CREATE") ||
|
|
197
|
+
upperQuery.startsWith("ALTER") ||
|
|
198
|
+
upperQuery.startsWith("DROP") ||
|
|
199
|
+
upperQuery.startsWith("TRUNCATE") ||
|
|
200
|
+
upperQuery.startsWith("RENAME");
|
|
184
201
|
if (!isDdl) {
|
|
185
202
|
return {
|
|
186
|
-
status:
|
|
187
|
-
error:
|
|
203
|
+
status: "error",
|
|
204
|
+
error: "Only DDL operations (CREATE, ALTER, DROP, TRUNCATE, RENAME) are allowed with executeDdl",
|
|
188
205
|
};
|
|
189
206
|
}
|
|
190
207
|
const result = await this.db.query(query);
|
|
191
208
|
return {
|
|
192
|
-
status:
|
|
209
|
+
status: "success",
|
|
193
210
|
data: {
|
|
194
|
-
message:
|
|
195
|
-
affected_rows: result.affectedRows || 0
|
|
211
|
+
message: "DDL query executed successfully",
|
|
212
|
+
affected_rows: result.affectedRows || 0,
|
|
196
213
|
},
|
|
197
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
198
214
|
};
|
|
199
215
|
}
|
|
200
216
|
catch (error) {
|
|
201
217
|
return {
|
|
202
|
-
status:
|
|
218
|
+
status: "error",
|
|
203
219
|
error: error.message,
|
|
204
|
-
queryLog: this.db.getFormattedQueryLogs(1)
|
|
205
220
|
};
|
|
206
221
|
}
|
|
207
222
|
}
|