@berthojoris/mcp-mysql-server 1.5.0 → 1.6.1

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.
@@ -0,0 +1,305 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ProcessTools = void 0;
7
+ const connection_1 = __importDefault(require("../db/connection"));
8
+ class ProcessTools {
9
+ constructor(security) {
10
+ this.db = connection_1.default.getInstance();
11
+ this.security = security;
12
+ }
13
+ /**
14
+ * Show all running processes/connections
15
+ */
16
+ async showProcessList(params) {
17
+ try {
18
+ const query = params?.full ? 'SHOW FULL PROCESSLIST' : 'SHOW PROCESSLIST';
19
+ const results = await this.db.query(query);
20
+ // Format results for better readability
21
+ const formattedResults = results.map(row => ({
22
+ id: row.Id,
23
+ user: row.User,
24
+ host: row.Host,
25
+ database: row.db,
26
+ command: row.Command,
27
+ time: row.Time,
28
+ state: row.State,
29
+ info: row.Info,
30
+ progress: row.Progress
31
+ }));
32
+ return {
33
+ status: 'success',
34
+ data: formattedResults,
35
+ queryLog: this.db.getFormattedQueryLogs(1)
36
+ };
37
+ }
38
+ catch (error) {
39
+ return {
40
+ status: 'error',
41
+ error: error.message,
42
+ queryLog: this.db.getFormattedQueryLogs(1)
43
+ };
44
+ }
45
+ }
46
+ /**
47
+ * Kill a specific process/connection
48
+ */
49
+ async killProcess(params) {
50
+ try {
51
+ const { process_id, type = 'CONNECTION' } = params;
52
+ // Validate process_id is a positive integer
53
+ if (!Number.isInteger(process_id) || process_id <= 0) {
54
+ return { status: 'error', error: 'Process ID must be a positive integer' };
55
+ }
56
+ const query = type === 'QUERY'
57
+ ? `KILL QUERY ${process_id}`
58
+ : `KILL ${process_id}`;
59
+ await this.db.query(query);
60
+ return {
61
+ status: 'success',
62
+ message: type === 'QUERY'
63
+ ? `Query for process ${process_id} killed successfully`
64
+ : `Process ${process_id} killed successfully`,
65
+ queryLog: this.db.getFormattedQueryLogs(1)
66
+ };
67
+ }
68
+ catch (error) {
69
+ return {
70
+ status: 'error',
71
+ error: error.message,
72
+ queryLog: this.db.getFormattedQueryLogs(1)
73
+ };
74
+ }
75
+ }
76
+ /**
77
+ * Show server status variables
78
+ */
79
+ async showStatus(params) {
80
+ try {
81
+ let query = params?.global ? 'SHOW GLOBAL STATUS' : 'SHOW STATUS';
82
+ if (params?.like) {
83
+ // Validate the LIKE pattern (basic check)
84
+ if (params.like.includes(';') || params.like.includes('--')) {
85
+ return { status: 'error', error: 'Invalid pattern' };
86
+ }
87
+ query += ` LIKE '${params.like}'`;
88
+ }
89
+ const results = await this.db.query(query);
90
+ // Convert to object for easier access
91
+ const statusObj = {};
92
+ for (const row of results) {
93
+ statusObj[row.Variable_name] = row.Value;
94
+ }
95
+ return {
96
+ status: 'success',
97
+ data: params?.like ? statusObj : {
98
+ variables: statusObj,
99
+ count: results.length
100
+ },
101
+ queryLog: this.db.getFormattedQueryLogs(1)
102
+ };
103
+ }
104
+ catch (error) {
105
+ return {
106
+ status: 'error',
107
+ error: error.message,
108
+ queryLog: this.db.getFormattedQueryLogs(1)
109
+ };
110
+ }
111
+ }
112
+ /**
113
+ * Show server variables
114
+ */
115
+ async showVariables(params) {
116
+ try {
117
+ let query = params?.global ? 'SHOW GLOBAL VARIABLES' : 'SHOW VARIABLES';
118
+ if (params?.like) {
119
+ // Validate the LIKE pattern (basic check)
120
+ if (params.like.includes(';') || params.like.includes('--')) {
121
+ return { status: 'error', error: 'Invalid pattern' };
122
+ }
123
+ query += ` LIKE '${params.like}'`;
124
+ }
125
+ const results = await this.db.query(query);
126
+ // Convert to object for easier access
127
+ const varsObj = {};
128
+ for (const row of results) {
129
+ varsObj[row.Variable_name] = row.Value;
130
+ }
131
+ return {
132
+ status: 'success',
133
+ data: params?.like ? varsObj : {
134
+ variables: varsObj,
135
+ count: results.length
136
+ },
137
+ queryLog: this.db.getFormattedQueryLogs(1)
138
+ };
139
+ }
140
+ catch (error) {
141
+ return {
142
+ status: 'error',
143
+ error: error.message,
144
+ queryLog: this.db.getFormattedQueryLogs(1)
145
+ };
146
+ }
147
+ }
148
+ /**
149
+ * Explain a query (show execution plan)
150
+ */
151
+ async explainQuery(params) {
152
+ try {
153
+ const { query, format = 'TRADITIONAL', analyze = false } = params;
154
+ // Only allow SELECT, UPDATE, DELETE, INSERT queries to be explained
155
+ const normalizedQuery = query.trim().toUpperCase();
156
+ if (!normalizedQuery.startsWith('SELECT') &&
157
+ !normalizedQuery.startsWith('UPDATE') &&
158
+ !normalizedQuery.startsWith('DELETE') &&
159
+ !normalizedQuery.startsWith('INSERT')) {
160
+ return { status: 'error', error: 'EXPLAIN only supports SELECT, UPDATE, DELETE, and INSERT statements' };
161
+ }
162
+ let explainQuery = analyze ? 'EXPLAIN ANALYZE ' : 'EXPLAIN ';
163
+ if (format !== 'TRADITIONAL') {
164
+ explainQuery += `FORMAT=${format} `;
165
+ }
166
+ explainQuery += query;
167
+ const results = await this.db.query(explainQuery);
168
+ return {
169
+ status: 'success',
170
+ data: format === 'JSON' ? JSON.parse(results[0]['EXPLAIN']) : results,
171
+ queryLog: this.db.getFormattedQueryLogs(1)
172
+ };
173
+ }
174
+ catch (error) {
175
+ return {
176
+ status: 'error',
177
+ error: error.message,
178
+ queryLog: this.db.getFormattedQueryLogs(1)
179
+ };
180
+ }
181
+ }
182
+ /**
183
+ * Show engine status (InnoDB, etc.)
184
+ */
185
+ async showEngineStatus(params) {
186
+ try {
187
+ const engine = params?.engine || 'INNODB';
188
+ // Validate engine name
189
+ const validEngines = ['INNODB', 'PERFORMANCE_SCHEMA', 'NDB', 'NDBCLUSTER'];
190
+ if (!validEngines.includes(engine.toUpperCase())) {
191
+ return { status: 'error', error: `Invalid engine. Supported: ${validEngines.join(', ')}` };
192
+ }
193
+ const query = `SHOW ENGINE ${engine.toUpperCase()} STATUS`;
194
+ const results = await this.db.query(query);
195
+ return {
196
+ status: 'success',
197
+ data: results,
198
+ queryLog: this.db.getFormattedQueryLogs(1)
199
+ };
200
+ }
201
+ catch (error) {
202
+ return {
203
+ status: 'error',
204
+ error: error.message,
205
+ queryLog: this.db.getFormattedQueryLogs(1)
206
+ };
207
+ }
208
+ }
209
+ /**
210
+ * Get server information
211
+ */
212
+ async getServerInfo() {
213
+ try {
214
+ // Get various server info
215
+ const queries = [
216
+ { key: 'version', query: 'SELECT VERSION() as value' },
217
+ { key: 'connection_id', query: 'SELECT CONNECTION_ID() as value' },
218
+ { key: 'current_user', query: 'SELECT CURRENT_USER() as value' },
219
+ { key: 'database', query: 'SELECT DATABASE() as value' }
220
+ ];
221
+ const info = {};
222
+ for (const q of queries) {
223
+ const result = await this.db.query(q.query);
224
+ info[q.key] = result[0]?.value;
225
+ }
226
+ // Get uptime and other status
227
+ const statusQuery = `SHOW GLOBAL STATUS WHERE Variable_name IN ('Uptime', 'Threads_connected', 'Threads_running', 'Questions', 'Slow_queries', 'Opens', 'Flush_commands', 'Open_tables', 'Queries')`;
228
+ const statusResult = await this.db.query(statusQuery);
229
+ for (const row of statusResult) {
230
+ info[row.Variable_name.toLowerCase()] = row.Value;
231
+ }
232
+ // Format uptime
233
+ if (info.uptime) {
234
+ const uptimeSec = parseInt(info.uptime);
235
+ const days = Math.floor(uptimeSec / 86400);
236
+ const hours = Math.floor((uptimeSec % 86400) / 3600);
237
+ const minutes = Math.floor((uptimeSec % 3600) / 60);
238
+ info.uptime_formatted = `${days}d ${hours}h ${minutes}m`;
239
+ }
240
+ return {
241
+ status: 'success',
242
+ data: info,
243
+ queryLog: this.db.getFormattedQueryLogs(queries.length + 1)
244
+ };
245
+ }
246
+ catch (error) {
247
+ return {
248
+ status: 'error',
249
+ error: error.message,
250
+ queryLog: this.db.getFormattedQueryLogs(1)
251
+ };
252
+ }
253
+ }
254
+ /**
255
+ * Show binary logs
256
+ */
257
+ async showBinaryLogs() {
258
+ try {
259
+ const query = 'SHOW BINARY LOGS';
260
+ const results = await this.db.query(query);
261
+ return {
262
+ status: 'success',
263
+ data: results,
264
+ queryLog: this.db.getFormattedQueryLogs(1)
265
+ };
266
+ }
267
+ catch (error) {
268
+ return {
269
+ status: 'error',
270
+ error: error.message,
271
+ queryLog: this.db.getFormattedQueryLogs(1)
272
+ };
273
+ }
274
+ }
275
+ /**
276
+ * Show master/replica status
277
+ */
278
+ async showReplicationStatus(params) {
279
+ try {
280
+ const type = params?.type || 'REPLICA';
281
+ let query;
282
+ if (type === 'MASTER') {
283
+ query = 'SHOW MASTER STATUS';
284
+ }
285
+ else {
286
+ // MySQL 8.0.22+ uses REPLICA, older versions use SLAVE
287
+ query = type === 'SLAVE' ? 'SHOW SLAVE STATUS' : 'SHOW REPLICA STATUS';
288
+ }
289
+ const results = await this.db.query(query);
290
+ return {
291
+ status: 'success',
292
+ data: results.length > 0 ? results[0] : null,
293
+ queryLog: this.db.getFormattedQueryLogs(1)
294
+ };
295
+ }
296
+ catch (error) {
297
+ return {
298
+ status: 'error',
299
+ error: error.message,
300
+ queryLog: this.db.getFormattedQueryLogs(1)
301
+ };
302
+ }
303
+ }
304
+ }
305
+ exports.ProcessTools = ProcessTools;
@@ -0,0 +1,76 @@
1
+ import { SecurityLayer } from '../security/securityLayer';
2
+ export declare class TriggerTools {
3
+ private db;
4
+ private security;
5
+ constructor(security: SecurityLayer);
6
+ /**
7
+ * Validate database access - ensures only the connected database can be accessed
8
+ */
9
+ private validateDatabaseAccess;
10
+ /**
11
+ * List all triggers in the current database
12
+ */
13
+ listTriggers(params: {
14
+ database?: string;
15
+ table_name?: string;
16
+ }): Promise<{
17
+ status: string;
18
+ data?: any[];
19
+ error?: string;
20
+ queryLog?: string;
21
+ }>;
22
+ /**
23
+ * Get detailed information about a specific trigger
24
+ */
25
+ getTriggerInfo(params: {
26
+ trigger_name: string;
27
+ database?: string;
28
+ }): Promise<{
29
+ status: string;
30
+ data?: any;
31
+ error?: string;
32
+ queryLog?: string;
33
+ }>;
34
+ /**
35
+ * Create a new trigger
36
+ */
37
+ createTrigger(params: {
38
+ trigger_name: string;
39
+ table_name: string;
40
+ timing: 'BEFORE' | 'AFTER';
41
+ event: 'INSERT' | 'UPDATE' | 'DELETE';
42
+ body: string;
43
+ definer?: string;
44
+ database?: string;
45
+ }): Promise<{
46
+ status: string;
47
+ data?: any;
48
+ error?: string;
49
+ queryLog?: string;
50
+ }>;
51
+ /**
52
+ * Drop a trigger
53
+ */
54
+ dropTrigger(params: {
55
+ trigger_name: string;
56
+ if_exists?: boolean;
57
+ database?: string;
58
+ }): Promise<{
59
+ status: string;
60
+ message?: string;
61
+ error?: string;
62
+ queryLog?: string;
63
+ }>;
64
+ /**
65
+ * Show the CREATE statement for a trigger
66
+ */
67
+ showCreateTrigger(params: {
68
+ trigger_name: string;
69
+ database?: string;
70
+ }): Promise<{
71
+ status: string;
72
+ data?: any;
73
+ error?: string;
74
+ queryLog?: string;
75
+ }>;
76
+ }
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TriggerTools = void 0;
7
+ const connection_1 = __importDefault(require("../db/connection"));
8
+ const config_1 = require("../config/config");
9
+ class TriggerTools {
10
+ constructor(security) {
11
+ this.db = connection_1.default.getInstance();
12
+ this.security = security;
13
+ }
14
+ /**
15
+ * Validate database access - ensures only the connected database can be accessed
16
+ */
17
+ validateDatabaseAccess(requestedDatabase) {
18
+ const connectedDatabase = config_1.dbConfig.database;
19
+ if (!connectedDatabase) {
20
+ return {
21
+ valid: false,
22
+ database: '',
23
+ error: 'No database specified in connection string. Cannot access any database.'
24
+ };
25
+ }
26
+ if (!requestedDatabase) {
27
+ return {
28
+ valid: true,
29
+ database: connectedDatabase
30
+ };
31
+ }
32
+ if (requestedDatabase !== connectedDatabase) {
33
+ return {
34
+ valid: false,
35
+ database: '',
36
+ error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed.`
37
+ };
38
+ }
39
+ return {
40
+ valid: true,
41
+ database: connectedDatabase
42
+ };
43
+ }
44
+ /**
45
+ * List all triggers in the current database
46
+ */
47
+ async listTriggers(params) {
48
+ try {
49
+ const dbValidation = this.validateDatabaseAccess(params?.database);
50
+ if (!dbValidation.valid) {
51
+ return { status: 'error', error: dbValidation.error };
52
+ }
53
+ const database = dbValidation.database;
54
+ let query = `
55
+ SELECT
56
+ TRIGGER_NAME as trigger_name,
57
+ EVENT_MANIPULATION as event,
58
+ EVENT_OBJECT_TABLE as table_name,
59
+ ACTION_TIMING as timing,
60
+ ACTION_STATEMENT as statement,
61
+ ACTION_ORIENTATION as orientation,
62
+ DEFINER as definer,
63
+ CREATED as created
64
+ FROM INFORMATION_SCHEMA.TRIGGERS
65
+ WHERE TRIGGER_SCHEMA = ?
66
+ `;
67
+ const queryParams = [database];
68
+ if (params?.table_name) {
69
+ const identifierValidation = this.security.validateIdentifier(params.table_name);
70
+ if (!identifierValidation.valid) {
71
+ return { status: 'error', error: identifierValidation.error || 'Invalid table name' };
72
+ }
73
+ query += ` AND EVENT_OBJECT_TABLE = ?`;
74
+ queryParams.push(params.table_name);
75
+ }
76
+ query += ` ORDER BY EVENT_OBJECT_TABLE, ACTION_TIMING, EVENT_MANIPULATION`;
77
+ const results = await this.db.query(query, queryParams);
78
+ return {
79
+ status: 'success',
80
+ data: results,
81
+ queryLog: this.db.getFormattedQueryLogs(1)
82
+ };
83
+ }
84
+ catch (error) {
85
+ return {
86
+ status: 'error',
87
+ error: error.message,
88
+ queryLog: this.db.getFormattedQueryLogs(1)
89
+ };
90
+ }
91
+ }
92
+ /**
93
+ * Get detailed information about a specific trigger
94
+ */
95
+ async getTriggerInfo(params) {
96
+ try {
97
+ const dbValidation = this.validateDatabaseAccess(params?.database);
98
+ if (!dbValidation.valid) {
99
+ return { status: 'error', error: dbValidation.error };
100
+ }
101
+ const { trigger_name } = params;
102
+ const database = dbValidation.database;
103
+ // Validate trigger name
104
+ const identifierValidation = this.security.validateIdentifier(trigger_name);
105
+ if (!identifierValidation.valid) {
106
+ return { status: 'error', error: identifierValidation.error || 'Invalid trigger name' };
107
+ }
108
+ const query = `
109
+ SELECT
110
+ TRIGGER_NAME as trigger_name,
111
+ EVENT_MANIPULATION as event,
112
+ EVENT_OBJECT_SCHEMA as schema_name,
113
+ EVENT_OBJECT_TABLE as table_name,
114
+ ACTION_ORDER as action_order,
115
+ ACTION_CONDITION as condition_value,
116
+ ACTION_STATEMENT as statement,
117
+ ACTION_ORIENTATION as orientation,
118
+ ACTION_TIMING as timing,
119
+ ACTION_REFERENCE_OLD_TABLE as old_table,
120
+ ACTION_REFERENCE_NEW_TABLE as new_table,
121
+ ACTION_REFERENCE_OLD_ROW as old_row,
122
+ ACTION_REFERENCE_NEW_ROW as new_row,
123
+ CREATED as created,
124
+ SQL_MODE as sql_mode,
125
+ DEFINER as definer,
126
+ CHARACTER_SET_CLIENT as charset,
127
+ COLLATION_CONNECTION as collation,
128
+ DATABASE_COLLATION as db_collation
129
+ FROM INFORMATION_SCHEMA.TRIGGERS
130
+ WHERE TRIGGER_SCHEMA = ? AND TRIGGER_NAME = ?
131
+ `;
132
+ const results = await this.db.query(query, [database, trigger_name]);
133
+ if (results.length === 0) {
134
+ return {
135
+ status: 'error',
136
+ error: `Trigger '${trigger_name}' not found in database '${database}'`,
137
+ queryLog: this.db.getFormattedQueryLogs(1)
138
+ };
139
+ }
140
+ return {
141
+ status: 'success',
142
+ data: results[0],
143
+ queryLog: this.db.getFormattedQueryLogs(1)
144
+ };
145
+ }
146
+ catch (error) {
147
+ return {
148
+ status: 'error',
149
+ error: error.message,
150
+ queryLog: this.db.getFormattedQueryLogs(1)
151
+ };
152
+ }
153
+ }
154
+ /**
155
+ * Create a new trigger
156
+ */
157
+ async createTrigger(params) {
158
+ try {
159
+ const dbValidation = this.validateDatabaseAccess(params?.database);
160
+ if (!dbValidation.valid) {
161
+ return { status: 'error', error: dbValidation.error };
162
+ }
163
+ const { trigger_name, table_name, timing, event, body, definer } = params;
164
+ const database = dbValidation.database;
165
+ // Validate trigger name
166
+ const triggerValidation = this.security.validateIdentifier(trigger_name);
167
+ if (!triggerValidation.valid) {
168
+ return { status: 'error', error: triggerValidation.error || 'Invalid trigger name' };
169
+ }
170
+ // Validate table name
171
+ const tableValidation = this.security.validateIdentifier(table_name);
172
+ if (!tableValidation.valid) {
173
+ return { status: 'error', error: tableValidation.error || 'Invalid table name' };
174
+ }
175
+ // Validate timing
176
+ if (!['BEFORE', 'AFTER'].includes(timing)) {
177
+ return { status: 'error', error: 'Timing must be BEFORE or AFTER' };
178
+ }
179
+ // Validate event
180
+ if (!['INSERT', 'UPDATE', 'DELETE'].includes(event)) {
181
+ return { status: 'error', error: 'Event must be INSERT, UPDATE, or DELETE' };
182
+ }
183
+ // Build CREATE TRIGGER statement
184
+ let createQuery = 'CREATE';
185
+ if (definer) {
186
+ createQuery += ` DEFINER = ${definer}`;
187
+ }
188
+ createQuery += ` TRIGGER \`${database}\`.\`${trigger_name}\``;
189
+ createQuery += ` ${timing} ${event}`;
190
+ createQuery += ` ON \`${database}\`.\`${table_name}\``;
191
+ createQuery += ` FOR EACH ROW`;
192
+ // Check if body already contains BEGIN/END
193
+ const trimmedBody = body.trim();
194
+ if (trimmedBody.toUpperCase().startsWith('BEGIN') && trimmedBody.toUpperCase().endsWith('END')) {
195
+ createQuery += `\n${body}`;
196
+ }
197
+ else {
198
+ createQuery += `\nBEGIN\n${body}\nEND`;
199
+ }
200
+ await this.db.query(createQuery);
201
+ return {
202
+ status: 'success',
203
+ data: {
204
+ message: `Trigger '${trigger_name}' created successfully`,
205
+ trigger_name,
206
+ table_name,
207
+ timing,
208
+ event,
209
+ database
210
+ },
211
+ queryLog: this.db.getFormattedQueryLogs(1)
212
+ };
213
+ }
214
+ catch (error) {
215
+ return {
216
+ status: 'error',
217
+ error: error.message,
218
+ queryLog: this.db.getFormattedQueryLogs(1)
219
+ };
220
+ }
221
+ }
222
+ /**
223
+ * Drop a trigger
224
+ */
225
+ async dropTrigger(params) {
226
+ try {
227
+ const dbValidation = this.validateDatabaseAccess(params?.database);
228
+ if (!dbValidation.valid) {
229
+ return { status: 'error', error: dbValidation.error };
230
+ }
231
+ const { trigger_name, if_exists = false } = params;
232
+ const database = dbValidation.database;
233
+ // Validate trigger name
234
+ const identifierValidation = this.security.validateIdentifier(trigger_name);
235
+ if (!identifierValidation.valid) {
236
+ return { status: 'error', error: identifierValidation.error || 'Invalid trigger name' };
237
+ }
238
+ const dropQuery = `DROP TRIGGER ${if_exists ? 'IF EXISTS' : ''} \`${database}\`.\`${trigger_name}\``;
239
+ await this.db.query(dropQuery);
240
+ return {
241
+ status: 'success',
242
+ message: `Trigger '${trigger_name}' dropped successfully`,
243
+ queryLog: this.db.getFormattedQueryLogs(1)
244
+ };
245
+ }
246
+ catch (error) {
247
+ return {
248
+ status: 'error',
249
+ error: error.message,
250
+ queryLog: this.db.getFormattedQueryLogs(1)
251
+ };
252
+ }
253
+ }
254
+ /**
255
+ * Show the CREATE statement for a trigger
256
+ */
257
+ async showCreateTrigger(params) {
258
+ try {
259
+ const dbValidation = this.validateDatabaseAccess(params?.database);
260
+ if (!dbValidation.valid) {
261
+ return { status: 'error', error: dbValidation.error };
262
+ }
263
+ const { trigger_name } = params;
264
+ const database = dbValidation.database;
265
+ // Validate trigger name
266
+ const identifierValidation = this.security.validateIdentifier(trigger_name);
267
+ if (!identifierValidation.valid) {
268
+ return { status: 'error', error: identifierValidation.error || 'Invalid trigger name' };
269
+ }
270
+ const query = `SHOW CREATE TRIGGER \`${database}\`.\`${trigger_name}\``;
271
+ const results = await this.db.query(query);
272
+ if (results.length === 0) {
273
+ return {
274
+ status: 'error',
275
+ error: `Trigger '${trigger_name}' not found`,
276
+ queryLog: this.db.getFormattedQueryLogs(1)
277
+ };
278
+ }
279
+ return {
280
+ status: 'success',
281
+ data: results[0],
282
+ queryLog: this.db.getFormattedQueryLogs(1)
283
+ };
284
+ }
285
+ catch (error) {
286
+ return {
287
+ status: 'error',
288
+ error: error.message,
289
+ queryLog: this.db.getFormattedQueryLogs(1)
290
+ };
291
+ }
292
+ }
293
+ }
294
+ exports.TriggerTools = TriggerTools;