dbtasker 1.0.0

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/function.js ADDED
@@ -0,0 +1,673 @@
1
+ const mysql = require('mysql2/promise');
2
+
3
+
4
+ function getDateTime(seperator) {
5
+ const today = new Date();
6
+ const formattedDateTime =
7
+ today.getFullYear() +
8
+ seperator +
9
+ (today.getMonth() + 1).toString().padStart(2, "0") +
10
+ seperator +
11
+ today.getDate().toString().padStart(2, "0") +
12
+ " " +
13
+ today.getHours().toString().padStart(2, "0") +
14
+ seperator +
15
+ today.getMinutes().toString().padStart(2, "0") +
16
+ seperator +
17
+ today.getSeconds().toString().padStart(2, "0");
18
+
19
+ const formatedDate =
20
+ today.getFullYear() +
21
+ seperator +
22
+ (today.getMonth() + 1).toString().padStart(2, "0") +
23
+ seperator +
24
+ today.getDate().toString().padStart(2, "0");
25
+ const formatedTime =
26
+ today.getHours().toString().padStart(2, "0") +
27
+ seperator +
28
+ today.getMinutes().toString().padStart(2, "0") +
29
+ seperator +
30
+ today.getSeconds().toString().padStart(2, "0");
31
+ return {
32
+ year: today.getFullYear(),
33
+ month: (today.getMonth() + 1).toString().padStart(2, "0"),
34
+ day: today.getDate().toString().padStart(2, "0"),
35
+ date: formatedDate,
36
+ time: formatedTime,
37
+ hours: today.getHours().toString().padStart(2, "0"),
38
+ minutes: today.getMinutes().toString().padStart(2, "0"),
39
+ seconds: today.getSeconds().toString().padStart(2, "0"),
40
+ datetime: formattedDateTime,
41
+ };
42
+ }
43
+ async function isMySQLDatabase(config) {
44
+ let connection;
45
+ try {
46
+ connection = await mysql.createConnection(config);
47
+ const [rows] = await connection.query('SELECT VERSION() AS version');
48
+
49
+ const version = rows?.[0]?.version;
50
+
51
+ // Check that version is a non-empty string
52
+ return typeof version === 'string' && version.length > 0;
53
+ } catch (err) {
54
+ console.error('Connection error:', err.message);
55
+ return false;
56
+ } finally {
57
+ if (connection) await connection.end();
58
+ }
59
+ }
60
+ async function checkDatabaseExists(config, dbName) {
61
+ try {
62
+ const connection = await mysql.createConnection({
63
+ host: config.host,
64
+ user: config.user,
65
+ password: config.password,
66
+ port: config.port || 3306
67
+ });
68
+
69
+ const [rows] = await connection.query("SHOW DATABASES LIKE ?", [dbName]);
70
+ await connection.end();
71
+
72
+ return rows.length > 0;
73
+ } catch (err) {
74
+ console.error(err.message);
75
+ return null;
76
+ }
77
+ }
78
+ async function createDatabase(config, dbName) {
79
+ let connection;
80
+
81
+ try {
82
+ connection = await mysql.createConnection(config);
83
+ await connection.query(`CREATE DATABASE \`${dbName}\``);
84
+ console.log(`✅ Database '${dbName}' created successfully.`);
85
+ return true;
86
+ } catch (err) {
87
+ if (err.code === 'ER_DB_CREATE_EXISTS') {
88
+ console.log(`⚠️ Database '${dbName}' already exists.`);
89
+ return false;
90
+ } else {
91
+ console.error(`❌ Error creating database:`, err.message);
92
+ return null;
93
+ }
94
+ } finally {
95
+ if (connection) await connection.end();
96
+ }
97
+ }
98
+ async function getAllDatabaseNames(config) {
99
+ let connection;
100
+
101
+ try {
102
+ connection = await mysql.createConnection(config);
103
+ const [rows] = await connection.query('SHOW DATABASES');
104
+
105
+ // Extract database names from result
106
+ const databases = rows.map(row => row.Database);
107
+ return databases;
108
+ } catch (err) {
109
+ console.error('❌ Error fetching database names:', err.message);
110
+ return null;
111
+ } finally {
112
+ if (connection) await connection.end();
113
+ }
114
+ }
115
+ function isValidDatabaseName(name) {
116
+ if (typeof name !== 'string') return false;
117
+
118
+ const maxLength = 64;
119
+
120
+ const reservedKeywords = new Set([
121
+ "select", "insert", "update", "delete", "create", "drop", "alter", "table",
122
+ "from", "where", "join", "and", "or", "not", "null", "group", "by", "order",
123
+ "having", "into", "as", "like", "union", "distinct", "case", "when", "then",
124
+ "else", "end", "in", "exists", "between", "index", "primary", "foreign", "key",
125
+ "check", "constraint", "default", "trigger", "view", "procedure", "function",
126
+ "grant", "revoke", "all", "any", "asc", "desc", "count", "limit", "offset",
127
+ "schema", "cursor", "declare", "begin", "end", "fetch", "loop", "exit",
128
+ "handler", "leave", "open", "close", "temporary", "replace", "if", "while",
129
+ "repeat", "do", "admin", "root", "master", "mysql", "postgres", "test", "sys",
130
+ "system", "public", "information_schema", "performance_schema", "pg_catalog"
131
+ ]);
132
+
133
+ const osReserved = new Set([
134
+ "con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6",
135
+ "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6",
136
+ "lpt7", "lpt8", "lpt9"
137
+ ]);
138
+
139
+ const lowerName = name.toLowerCase();
140
+
141
+ // Basic rules
142
+ if (name.length === 0 || name.length > maxLength) return false;
143
+ if (!/^[a-z][a-z0-9_]*$/.test(name)) return false;
144
+ if (reservedKeywords.has(lowerName)) return false;
145
+ if (osReserved.has(lowerName)) return false;
146
+
147
+ return true;
148
+ }
149
+ function isValidTableName(name) {
150
+ if (typeof name !== 'string') return false;
151
+
152
+ const maxLength = 64;
153
+
154
+ const reservedKeywords = new Set([
155
+ "select", "insert", "update", "delete", "create", "drop", "alter", "table",
156
+ "from", "where", "join", "and", "or", "not", "null", "group", "by", "order",
157
+ "having", "into", "as", "like", "union", "distinct", "case", "when", "then",
158
+ "else", "end", "in", "exists", "between", "index", "primary", "foreign", "key",
159
+ "check", "constraint", "default", "trigger", "view", "procedure", "function",
160
+ "grant", "revoke", "all", "any", "asc", "desc", "count", "limit", "offset",
161
+ "schema", "cursor", "declare", "begin", "end", "fetch", "loop", "exit",
162
+ "handler", "leave", "open", "close", "temporary", "replace", "if", "while",
163
+ "repeat", "do", "admin", "root", "master", "mysql", "postgres", "test", "sys",
164
+ "system", "public", "information_schema", "performance_schema", "pg_catalog"
165
+ ]);
166
+
167
+ const invalidCharacters = /[^a-zA-Z0-9_]/;
168
+ const startsInvalid = /^[^a-zA-Z]/;
169
+ const lowerName = name.toLowerCase();
170
+
171
+ if (name.length === 0 || name.length > maxLength) return false;
172
+ if (invalidCharacters.test(name)) return false;
173
+ if (startsInvalid.test(name)) return false;
174
+ if (reservedKeywords.has(lowerName)) return false;
175
+
176
+ return true;
177
+ }
178
+ function isValidColumnName(name) {
179
+ if (typeof name !== 'string') return false;
180
+
181
+ const maxLength = 64;
182
+
183
+ const reservedKeywords = new Set([
184
+ "select", "insert", "update", "delete", "create", "drop", "alter", "table",
185
+ "column", "from", "where", "join", "and", "or", "not", "null", "group", "by",
186
+ "order", "having", "into", "as", "like", "union", "distinct", "case", "when",
187
+ "then", "else", "end", "in", "exists", "between", "index", "primary", "foreign",
188
+ "key", "check", "constraint", "default", "trigger", "view", "procedure",
189
+ "function", "grant", "revoke", "asc", "desc", "limit", "offset", "schema",
190
+ "if", "while", "do", "loop", "replace", "return", "all", "any", "begin", "end"
191
+ ]);
192
+
193
+ const startsInvalid = /^[^a-zA-Z]/;
194
+ const invalidChars = /[^a-zA-Z0-9_]/;
195
+ const lowerName = name.toLowerCase();
196
+
197
+ if (name.length === 0 || name.length > maxLength) return false;
198
+ if (startsInvalid.test(name)) return false; // Must start with a letter
199
+ if (invalidChars.test(name)) return false; // Only letters, numbers, _
200
+ if (reservedKeywords.has(lowerName)) return false; // Not a SQL keyword
201
+
202
+ return true;
203
+ }
204
+ function parseColumnWithOptionalLoopStrict(text) {
205
+ if (typeof text !== 'string') return false;
206
+
207
+ text = text.trim();
208
+
209
+ // Case 1: product(year)
210
+ let match = text.match(/^([a-zA-Z_][\w]*)\(([^()]+)\)$/);
211
+ if (match) {
212
+ const name = match[1];
213
+ const loop = match[2];
214
+ if (isValidColumnName(name) && isValidColumnName(loop)) {
215
+ return { name, loop };
216
+ }
217
+ return false;
218
+ }
219
+
220
+ // Case 2: (year)product
221
+ match = text.match(/^\(([^()]+)\)([a-zA-Z_][\w]*)$/);
222
+ if (match) {
223
+ const loop = match[1];
224
+ const name = match[2];
225
+ if (isValidColumnName(name) && isValidColumnName(loop)) {
226
+ return { name, loop };
227
+ }
228
+ return false;
229
+ }
230
+
231
+ // Case 3: just a column name without loop
232
+ if (isValidColumnName(text)) {
233
+ return { name: text, loop: null };
234
+ }
235
+
236
+ // Any invalid format or invalid name
237
+ return false;
238
+ }
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+ async function getLastSavedFile(directory) {
250
+ try {
251
+ // Read the directory
252
+ const files = await fs.readdir(directory);
253
+
254
+ // Handle empty directory
255
+ if (files.length === 0) {
256
+ throw new Error(`No files found in the directory: ${directory}`);
257
+ }
258
+
259
+ // Get file stats and sort by modification time
260
+ const fileStats = await Promise.all(
261
+ files.map(async (file) => {
262
+ const filePath = path.join(directory, file);
263
+ const stats = await fs.stat(filePath);
264
+ return { file, stats };
265
+ })
266
+ );
267
+
268
+ const sortedFiles = fileStats.sort((a, b) => b.stats.mtime - a.stats.mtime);
269
+
270
+ // Return the most recently saved file
271
+ const lastSavedFile = sortedFiles[0]?.file; // Use optional chaining
272
+ return lastSavedFile;
273
+ } catch (err) {
274
+ console.error(
275
+ `Error getting last saved file from directory "${directory}": ${err.message}`
276
+ );
277
+ return null; // Return `null` if an error occurs
278
+ }
279
+ }
280
+ async function compareJsonFiles(filePath1, filePath2) {
281
+ try {
282
+ // Ensure both files exist
283
+ await fs.access(filePath1);
284
+ await fs.access(filePath2);
285
+
286
+ // Read the content of both files
287
+ const fileContent1 = await fs.readFile(filePath1, "utf-8");
288
+ const fileContent2 = await fs.readFile(filePath2, "utf-8");
289
+
290
+ // Check if either file is empty
291
+ if (!fileContent1.trim()) {
292
+ console.error("File 1 is empty.");
293
+ return false;
294
+ }
295
+ if (!fileContent2.trim()) {
296
+ console.error("File 2 is empty.");
297
+ return false;
298
+ }
299
+
300
+ // Parse the JSON content of both files
301
+ let jsonData1, jsonData2;
302
+ try {
303
+ jsonData1 = JSON.parse(fileContent1);
304
+ } catch (parseError) {
305
+ console.error("Failed to parse File 1:", parseError.message);
306
+ return false;
307
+ }
308
+
309
+ try {
310
+ jsonData2 = JSON.parse(fileContent2);
311
+ } catch (parseError) {
312
+ console.error("Failed to parse File 2:", parseError.message);
313
+ return false;
314
+ }
315
+
316
+ // Compare the two JSON objects using deepEqual
317
+ const isEqual = JSON.stringify(jsonData1) === JSON.stringify(jsonData2);
318
+ console.log("Are the JSON files equal?", isEqual);
319
+ return isEqual;
320
+ } catch (error) {
321
+ // Log specific errors
322
+ if (error.code === "ENOENT") {
323
+ console.warn(`File not found: ${error.path}`);
324
+ return false;
325
+ } else {
326
+ console.error("Error comparing JSON files:", error.message);
327
+ return null;
328
+ }
329
+ }
330
+ }
331
+ async function readJsonFile(filePath) {
332
+ try {
333
+ // Check if the file has a .json extension
334
+ if (path.extname(filePath).toLowerCase() !== ".json") {
335
+ throw new Error(`The file at ${filePath} is not a JSON file.`);
336
+ }
337
+
338
+ // Read the file as a string
339
+ const fileContent = await fs.readFile(filePath, "utf-8");
340
+
341
+ // Parse the JSON string into an object
342
+ const jsonData = JSON.parse(fileContent);
343
+ return jsonData;
344
+ } catch (error) {
345
+ // Handle errors (e.g., file not found, invalid JSON)
346
+ console.error(`Error reading or parsing JSON file at ${filePath}:`, error);
347
+ return null;
348
+ }
349
+ }
350
+ async function writeJsonFile(filePath, data) {
351
+ try {
352
+ // Ensure the directory exists
353
+ const dir = path.dirname(filePath);
354
+ await fs.mkdir(dir, { recursive: true });
355
+
356
+ // Convert the data object to a JSON string with indentation
357
+ const jsonString = JSON.stringify(data, null, 2);
358
+
359
+ // Write the JSON string to the file
360
+ await fs.writeFile(filePath, jsonString, "utf-8");
361
+ const successMessage = `File written successfully to ${filePath}`;
362
+ console.log(successMessage);
363
+ return successMessage;
364
+ } catch (error) {
365
+ // Handle errors (e.g., permission issues, invalid data)
366
+ console.error(`Error writing JSON file at ${filePath}:`, error);
367
+ return null;
368
+ }
369
+ }
370
+ //Write js file
371
+ const writeJsFile = async (filePath, content) => {
372
+ try {
373
+ await fs.access(filePath).catch(() => fs.mkdir(path.dirname(filePath), { recursive: true }));
374
+ await fs.writeFile(filePath, content, 'utf8');
375
+ console.log(`File written successfully to ${filePath}`);
376
+ return true;
377
+ } catch (error) {
378
+ console.error(`Error writing file at ${filePath}:`, error);
379
+ }
380
+ };
381
+ function removefromarray(arr, text) {
382
+ if (!Array.isArray(arr)) {
383
+ throw new Error("data must be an array.");
384
+ }
385
+ let index = arr.indexOf(text);
386
+ if (index !== -1) {
387
+ arr.splice(index, 1);
388
+ }
389
+ return arr
390
+ }
391
+ function isJsonObject(value) {
392
+ return typeof value === "object" && value !== null && !Array.isArray(value);
393
+ }
394
+ function isJsonString(jsonString) {
395
+ try {
396
+ const parsed = JSON.parse(jsonString);
397
+ return (
398
+ typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)
399
+ );
400
+ } catch (error) {
401
+ return false;
402
+ }
403
+ }
404
+ function isJsonSame(a, b) {
405
+ if (isJsonString(a)) a = JSON.parse(a);
406
+ if (isJsonString(b)) b = JSON.parse(b);
407
+
408
+ if (a === b) return true;
409
+
410
+ if (typeof a !== typeof b || a === null || b === null) return false;
411
+
412
+ if (typeof a !== 'object') return false;
413
+
414
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
415
+
416
+ const keysA = Object.keys(a);
417
+ const keysB = Object.keys(b);
418
+ if (keysA.length !== keysB.length) return false;
419
+
420
+ for (let key of keysA) {
421
+ if (!keysB.includes(key)) return false;
422
+ if (!isJsonSame(a[key], b[key])) return false;
423
+ }
424
+
425
+ return true;
426
+ }
427
+ function bypassQuotes(data) {
428
+ let stringData = "";
429
+
430
+ if (typeof data !== "string") {
431
+ stringData = safeStringify(data);
432
+ } else {
433
+ stringData = data;
434
+ }
435
+
436
+ // First unescape any previously escaped quotes and backslashes
437
+ stringData = stringData.replace(/\\(["'\\])/g, "$1");
438
+
439
+ // Now escape all quotes and backslashes
440
+ return stringData.replace(/(["'\\])/g, "\\$1");
441
+ }
442
+ function isNumber(str) {
443
+ if (str === null || str === undefined) {
444
+ return false;
445
+ }
446
+ if (typeof str === "number") {
447
+ return true;
448
+ }
449
+ if (Array.isArray(str) || typeof str === "object") {
450
+ return false;
451
+ }
452
+ return !isNaN(str) && str.trim() !== "";
453
+ }
454
+ async function getTableNames(config, databaseName) {
455
+ const dbName = databaseName || config.database;
456
+
457
+ if (!dbName) throw new Error("No database name provided.");
458
+
459
+ const query = `
460
+ SELECT table_name
461
+ FROM information_schema.tables
462
+ WHERE table_schema = ?
463
+ `;
464
+
465
+ const pool = await mysql.createPool(config);
466
+ try {
467
+ const [results] = await pool.query(query, [dbName]);
468
+ return results.map(row => row.TABLE_NAME || row.table_name);
469
+ } catch (err) {
470
+ console.error("Query failed:", err.message);
471
+ return null;
472
+ } finally {
473
+ await pool.end();
474
+ }
475
+ }
476
+ async function getColumnNames(config, databaseName, tableName) {
477
+ let connection;
478
+
479
+ try {
480
+ // Create a new connection using the provided config
481
+ connection = await mysql.createConnection({ ...config, database: databaseName });
482
+
483
+ const query = `
484
+ SELECT COLUMN_NAME
485
+ FROM INFORMATION_SCHEMA.COLUMNS
486
+ WHERE TABLE_SCHEMA = ?
487
+ AND TABLE_NAME = ?
488
+ `;
489
+
490
+ const [rows] = await connection.execute(query, [databaseName, tableName]);
491
+
492
+ return rows.map(row => row.COLUMN_NAME);
493
+ } catch (err) {
494
+ console.error("Error fetching column names:", err.message);
495
+ return null;
496
+ } finally {
497
+ if (connection) await connection.end(); // Ensure connection is closed
498
+ }
499
+ }
500
+ async function getColumnDetails(config, databaseName, tableName, columnName = null) {
501
+ let connection;
502
+
503
+ const query = `
504
+ SELECT
505
+ COLUMN_NAME AS column_name,
506
+ DATA_TYPE AS data_type,
507
+ COLUMN_TYPE AS column_type,
508
+ CHARACTER_MAXIMUM_LENGTH AS character_maximum_length,
509
+ IS_NULLABLE AS is_nullable,
510
+ COLUMN_DEFAULT AS default_value,
511
+ COLUMN_COMMENT AS column_comment,
512
+ COLLATION_NAME AS collation_name
513
+ FROM INFORMATION_SCHEMA.COLUMNS
514
+ WHERE
515
+ TABLE_SCHEMA = ?
516
+ AND TABLE_NAME = ?
517
+ ${columnName ? "AND COLUMN_NAME = ?" : ""}
518
+ `;
519
+
520
+ const params = columnName
521
+ ? [databaseName, tableName, columnName]
522
+ : [databaseName, tableName];
523
+
524
+ try {
525
+ connection = await mysql.createConnection({ ...config, database: databaseName });
526
+ const [rows] = await connection.execute(query, params);
527
+
528
+ // Process ENUM and SET types
529
+ rows.forEach((row) => {
530
+ if (row.data_type === "enum" || row.data_type === "set") {
531
+ row.enum_set_values = row.column_type
532
+ .replace(/(enum|set)\((.*)\)/i, "$2")
533
+ .split(",")
534
+ .map((val) => val.replace(/'/g, ""));
535
+ }
536
+ });
537
+
538
+ return rows;
539
+ } catch (error) {
540
+ console.error("Error fetching column details:", error.message);
541
+ return null;
542
+ } finally {
543
+ if (connection) await connection.end();
544
+ }
545
+ }
546
+ async function getForeignKeyDetails(config, databaseName, tableName) {
547
+ let connection;
548
+
549
+ const query = `
550
+ SELECT
551
+ k.TABLE_NAME,
552
+ k.COLUMN_NAME,
553
+ k.CONSTRAINT_NAME,
554
+ k.REFERENCED_TABLE_NAME,
555
+ k.REFERENCED_COLUMN_NAME,
556
+ r.DELETE_RULE
557
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE k
558
+ JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS r
559
+ ON k.CONSTRAINT_NAME = r.CONSTRAINT_NAME
560
+ AND k.CONSTRAINT_SCHEMA = r.CONSTRAINT_SCHEMA
561
+ WHERE k.TABLE_SCHEMA = ?
562
+ AND k.TABLE_NAME = ?
563
+ AND k.REFERENCED_TABLE_NAME IS NOT NULL;
564
+ `;
565
+
566
+ try {
567
+ connection = await mysql.createConnection({ ...config, database: databaseName });
568
+ const [rows] = await connection.execute(query, [databaseName, tableName]);
569
+ return rows;
570
+ } catch (err) {
571
+ console.error("Error fetching foreign key details:", err.message);
572
+ return null;
573
+ } finally {
574
+ if (connection) await connection.end();
575
+ }
576
+ }
577
+ async function dropTables(databaseName, tableNames) {
578
+ if (typeof databaseName !== "string" || !databaseName.trim()) {
579
+ throw new Error("databaseName must be a non-empty string.");
580
+ }
581
+ if (!Array.isArray(tableNames)) {
582
+ throw new Error("tableNames must be an array of strings.");
583
+ }
584
+ if (tableNames.length === 0) return;
585
+
586
+ try {
587
+ console.log(`Attempting to drop tables in database ${databaseName}: ${tableNames.join(", ")}`);
588
+
589
+ // Escape table names and prefix with database name, safely quoted
590
+ const escapedTables = tableNames
591
+ .map(t => `\`${databaseName.replace(/`/g, "``")}\`.\`${t.replace(/`/g, "``")}\``)
592
+ .join(", ");
593
+
594
+ const query = `DROP TABLE IF EXISTS ${escapedTables}`;
595
+ await pool.query(query);
596
+
597
+ console.log(`Tables dropped successfully in database ${databaseName}: ${tableNames.join(", ")}`);
598
+ } catch (error) {
599
+ console.error(`Error dropping tables in database ${databaseName}:`, error.message);
600
+ }
601
+ }
602
+ async function createOrModifyTable(queryText, databaseName) {
603
+ try {
604
+ if (databaseName && typeof databaseName === "string" && databaseName.trim()) {
605
+ // Add databaseName prefix to the table name(s) inside queryText
606
+
607
+ // This is a naive regex that finds first table name after CREATE TABLE or ALTER TABLE
608
+ // and prefixes it with databaseName.
609
+ queryText = queryText.replace(
610
+ /(CREATE TABLE IF NOT EXISTS|CREATE TABLE|ALTER TABLE)\s+(`?)(\w+)(`?)/i,
611
+ (match, p1, p2, p3, p4) => {
612
+ const dbNameEscaped = `\`${databaseName.replace(/`/g, "``")}\``;
613
+ const tableNameEscaped = `${p2}${p3}${p4}`;
614
+ return `${p1} ${dbNameEscaped}.${tableNameEscaped}`;
615
+ }
616
+ );
617
+ }
618
+
619
+ await pool.query(queryText);
620
+
621
+ function getTableName(input) {
622
+ if (typeof input !== "string") {
623
+ throw new Error("Query text must be a string");
624
+ }
625
+ const words = input.trim().split(/\s+/);
626
+ if (words.length < 5) {
627
+ return "";
628
+ }
629
+ if (input.startsWith("CREATE TABLE IF NOT EXISTS") && words.length > 5) {
630
+ return [words[5]];
631
+ } else {
632
+ return [words[2], words[5]];
633
+ }
634
+ }
635
+
636
+ let table_name = getTableName(queryText);
637
+ if (table_name.length > 1) {
638
+ return {
639
+ success: true,
640
+ message: `${table_name[1]} column of ${table_name[0]} table created or modified successfully.`,
641
+ querytext: queryText,
642
+ };
643
+ } else {
644
+ return {
645
+ success: true,
646
+ message: `${table_name[0]} table created or modified successfully.`,
647
+ querytext: queryText,
648
+ };
649
+ }
650
+ } catch (err) {
651
+ return { success: false, message: err.message };
652
+ }
653
+ }
654
+
655
+
656
+ module.exports = {
657
+ isMySQLDatabase,
658
+ checkDatabaseExists,
659
+ createDatabase,
660
+ getAllDatabaseNames,
661
+ isValidDatabaseName,
662
+ isValidTableName,
663
+ isValidColumnName,
664
+ parseColumnWithOptionalLoopStrict,
665
+ getDateTime,
666
+ isJsonString,
667
+ isJsonObject,
668
+ isJsonSame,
669
+ getTableNames,
670
+ getColumnNames,
671
+ getColumnDetails,
672
+ getForeignKeyDetails,
673
+ }