dbtasker 3.0.8 → 3.0.9
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/addcolumn.js +8 -1
- package/altercolumn.js +72 -47
- package/dropcolumn.js +8 -3
- package/function.js +65 -4
- package/index.js +6 -10
- package/package.json +3 -2
- package/tableop.js +7 -7
package/addcolumn.js
CHANGED
|
@@ -170,6 +170,7 @@ async function addColumnQuery(columndata, columnName, tableName, databaseName, c
|
|
|
170
170
|
async function addColumnIfNeeded(config, jsondata, separator) {
|
|
171
171
|
try {
|
|
172
172
|
console.log(cstyler.bold.yellow("Let's initiate addColumn to table if needed..."));
|
|
173
|
+
let count = 0;
|
|
173
174
|
for (const jsondb of Object.keys(jsondata)) {
|
|
174
175
|
let remainfk = {};
|
|
175
176
|
const loopdb = fncs.perseDatabaseNameWithLoop(jsondb, separator);
|
|
@@ -212,6 +213,8 @@ async function addColumnIfNeeded(config, jsondata, separator) {
|
|
|
212
213
|
console.error(cstyler.red(`Failed to add column ${jsoncolumn} to table ${tableName} in database ${databaseName}. Skipping...`));
|
|
213
214
|
return null;
|
|
214
215
|
}
|
|
216
|
+
console.log(cstyler.blue("Database: "), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue(" Table: "), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column: "), cstyler.hex("#00d9ffff")(jsoncolumn), cstyler.green("- added successfully."))
|
|
217
|
+
count += 1;
|
|
215
218
|
// check for foreign key
|
|
216
219
|
if (columndata.hasOwnProperty("foreign_key")) {
|
|
217
220
|
const fk = columndata.foreign_key;
|
|
@@ -249,7 +252,11 @@ async function addColumnIfNeeded(config, jsondata, separator) {
|
|
|
249
252
|
}
|
|
250
253
|
}
|
|
251
254
|
}
|
|
252
|
-
|
|
255
|
+
if(count > 0){
|
|
256
|
+
console.log(cstyler.green.bold("Successfully added " + count + " columns."));
|
|
257
|
+
} else {
|
|
258
|
+
console.log("No column found to be added. All the column are added already.");
|
|
259
|
+
}
|
|
253
260
|
return true;
|
|
254
261
|
} catch (err) {
|
|
255
262
|
console.error(err.message);
|
package/altercolumn.js
CHANGED
|
@@ -1,40 +1,22 @@
|
|
|
1
1
|
const fncs = require("./function");
|
|
2
2
|
const cstyler = require("cstyler");
|
|
3
|
+
const crypto = require('crypto');
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
if ((refColData.unsigned || false) !== (columnData.unsigned || false)) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
if (["CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "ENUM", "SET"].includes(refColData.columntype.toUpperCase())) {
|
|
26
|
-
if ((refColData._charset_ || "") !== (columnData._charset_ || "")) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
if ((refColData._collate_ || "") !== (columnData._collate_ || "")) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return true;
|
|
34
|
-
} catch (err) {
|
|
35
|
-
console.log(err);
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
function generateSafeIndexName(prefix, table, column) {
|
|
10
|
+
const fullName = `${prefix}_${table}_${column}`;
|
|
11
|
+
|
|
12
|
+
// If it fits, just return it
|
|
13
|
+
if (fullName.length <= 64) return fullName;
|
|
14
|
+
|
|
15
|
+
// If too long, hash the full string and append it to a slice
|
|
16
|
+
const hash = crypto.createHash('sha256').update(fullName).digest('hex').slice(0, 8);
|
|
17
|
+
|
|
18
|
+
// 55 chars + 1 underscore + 8 chars hash = 64 chars total
|
|
19
|
+
return `${fullName.slice(0, 55)}_${hash}`;
|
|
38
20
|
}
|
|
39
21
|
async function isColumnDataSame(config, databaseName, tableName, columnName, columnData, columndetails, fkdetails,) {
|
|
40
22
|
// 1. Column type
|
|
@@ -146,7 +128,7 @@ async function isColumnDataSame(config, databaseName, tableName, columnName, col
|
|
|
146
128
|
} else if (idxA !== idxB && !realfk) {
|
|
147
129
|
console.log(cstyler.blue("Table:"), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column:"), cstyler.hex("#00d9ffff")(columnName));
|
|
148
130
|
console.log(cstyler.red("Index are not same"), cstyler.hex("#00b7ff")("Given data:"), cstyler.hex("#ffffff")(columnData.index), cstyler.hex("#00b7ff")("Server data:"), cstyler.hex("#ffffff")(columndetails.index),);
|
|
149
|
-
console.log("
|
|
131
|
+
console.log("Foreign key exist:", fkdetails)
|
|
150
132
|
return false;
|
|
151
133
|
}
|
|
152
134
|
|
|
@@ -186,7 +168,7 @@ async function isColumnDataSame(config, databaseName, tableName, columnName, col
|
|
|
186
168
|
}
|
|
187
169
|
// Identifier validator (letters, digits, underscore, dollar, max 64 chars)
|
|
188
170
|
const validIdent = name => typeof name === 'string' && /^[A-Za-z0-9$_]{1,64}$/.test(name);
|
|
189
|
-
async function alterColumnQuery(dbConfig, columndata, columnName, tableName, database, options = {}) {
|
|
171
|
+
async function alterColumnQuery(dbConfig, columndata, columnName, tableName, database, options = {}, forceupdatecolumn) {
|
|
190
172
|
try {
|
|
191
173
|
// Basic validation
|
|
192
174
|
if (!validIdent(columnName)) throw new Error('Invalid columnName');
|
|
@@ -320,14 +302,36 @@ async function alterColumnQuery(dbConfig, columndata, columnName, tableName, dat
|
|
|
320
302
|
};
|
|
321
303
|
|
|
322
304
|
if (wantsUnique) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
305
|
+
// Lets check for duplicates first
|
|
306
|
+
const hasdupes = await fncs.checkDuplicates(dbConfig, database, tableName, columnName);
|
|
307
|
+
if (hasdupes === null) {
|
|
308
|
+
console.error("Having problem getting duplicate value of column from database");
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
if (hasdupes === true) {
|
|
312
|
+
if (forceupdatecolumn) {
|
|
313
|
+
console.log(cstyler.bold.yellow("Cleaning duplicate rows before adding UNIQUE index..."));
|
|
314
|
+
const cleancol = await fncs.cleanDuplicateRows(dbConfig, database, tableName, columnName);
|
|
315
|
+
if (cleancol === null) {
|
|
316
|
+
console.error("Having server connection problem cleaning duplicate rows from database");
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
console.error(`${cstyler.blue("Database:")} ${cstyler.hex("#00d9ffff")(database)} ${cstyler.blue("Table:")} ${cstyler.hex("#00d9ffff")(tableName)} ${cstyler.blue("Column:")} ${cstyler.hex("#00d9ffff")(columnName)} - Cannot add UNIQUE index because duplicate values exist. You need to turn on the ${cstyler.yellow("force_update_column")} option to true clean duplicates first.`);
|
|
321
|
+
return false;
|
|
327
322
|
}
|
|
323
|
+
}
|
|
324
|
+
if (columnHasConstraint && info.constraints[0].constraintType === 'UNIQUE') {
|
|
325
|
+
console.info(`Skipping: A Unique key already exists on ${columnName}.`);
|
|
328
326
|
} else {
|
|
327
|
+
// Remove existing constraint/index first
|
|
328
|
+
const remfkconstraint = await fncs.removeForeignKeyConstraintFromColumn(dbConfig, database, tableName, columnName);
|
|
329
|
+
if (remfkconstraint === null) {
|
|
330
|
+
console.error("Having problem removing constraint name from the column.");
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
329
333
|
// Add UNIQUE on the column (single-column unique)
|
|
330
|
-
const idxName = (
|
|
334
|
+
const idxName = (`${generateSafeIndexName("un", tableName, columnName)}`).slice(0, 64);
|
|
331
335
|
actions.push(`ADD UNIQUE KEY ${quoteId(idxName)} (${quoteId(columnName)})`);
|
|
332
336
|
}
|
|
333
337
|
} else {
|
|
@@ -355,6 +359,14 @@ async function alterColumnQuery(dbConfig, columndata, columnName, tableName, dat
|
|
|
355
359
|
else actions.push(`ADD ${type}${namePart} (${colsSql})`);
|
|
356
360
|
}
|
|
357
361
|
}
|
|
362
|
+
} else {
|
|
363
|
+
if (columnHasConstraint) {
|
|
364
|
+
const rem = await fncs.removeForeignKeyConstraintFromColumn(dbConfig, database, tableName, columnName);
|
|
365
|
+
if (rem === null) {
|
|
366
|
+
console.error("Having problem removing constraint name from the column.");
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
358
370
|
}
|
|
359
371
|
|
|
360
372
|
// Return single ALTER TABLE statement (no multi-statement)
|
|
@@ -392,6 +404,7 @@ async function addForeignKeyWithIndexQuery(config, databaseName, tableName, colu
|
|
|
392
404
|
async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separator) {
|
|
393
405
|
try {
|
|
394
406
|
console.log(cstyler.bold.yellow("Let's initiate Alter Column to table if needed..."));
|
|
407
|
+
let count = 0;
|
|
395
408
|
for (const jsondb of Object.keys(jsondata)) {
|
|
396
409
|
const loopdb = fncs.perseTableNameWithLoop(jsondb, separator);
|
|
397
410
|
if (loopdb === false) {
|
|
@@ -471,11 +484,12 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
471
484
|
}
|
|
472
485
|
}
|
|
473
486
|
// now alter the column
|
|
474
|
-
const alterquery = await alterColumnQuery(config, columndata, jsoncolumn, tableName, databaseName);
|
|
487
|
+
const alterquery = await alterColumnQuery(config, columndata, jsoncolumn, tableName, databaseName, {}, forceupdatecolumn);
|
|
475
488
|
if (alterquery === null) {
|
|
476
489
|
console.error("There was an issue when creating alter column for", cstyler.blue("Database:"), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue("Table:"), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column:"), cstyler.hex("#00d9ffff")(jsoncolumn));
|
|
477
490
|
return null;
|
|
478
491
|
}
|
|
492
|
+
count += 1;
|
|
479
493
|
// now re add foreign key to the column if exist
|
|
480
494
|
if (columndata.hasOwnProperty("foreign_key")) {
|
|
481
495
|
const fkdata = columndata.foreign_key;
|
|
@@ -516,11 +530,12 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
516
530
|
return null;
|
|
517
531
|
}
|
|
518
532
|
}
|
|
519
|
-
const alterquery = await alterColumnQuery(config, columndata, jsoncolumn, tableName, databaseName);
|
|
533
|
+
const alterquery = await alterColumnQuery(config, columndata, jsoncolumn, tableName, databaseName, {}, forceupdatecolumn);
|
|
520
534
|
if (alterquery === null) {
|
|
521
535
|
console.error(cstyler.blue("Database:"), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue("Table:"), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column:"), cstyler.hex("#00d9ffff")(jsoncolumn), cstyler.red("There was an issue when modifying column",));
|
|
522
536
|
return null;
|
|
523
537
|
}
|
|
538
|
+
count += 1;
|
|
524
539
|
if (columndata.hasOwnProperty("foreign_key")) {
|
|
525
540
|
const fkdata = columndata.foreign_key;
|
|
526
541
|
const fkquery = await addForeignKeyWithIndexQuery(config, databaseName, tableName, jsoncolumn, fkdata.table, fkdata.column, {
|
|
@@ -535,9 +550,10 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
535
550
|
}
|
|
536
551
|
}
|
|
537
552
|
} else {
|
|
538
|
-
console.log(cstyler.blue("Database:
|
|
553
|
+
console.log(cstyler.blue("Database:"), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue("Table:"), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column Name:"), cstyler.hex("#00d9ffff")(jsoncolumn), cstyler.yellow("- Given column data and server data are same."));
|
|
539
554
|
// lets check if foreign key need update
|
|
540
555
|
if (fkdetails === false && !columndata.hasOwnProperty("foreign_key")) {
|
|
556
|
+
console.log(cstyler.underline("Column do not have foreign key."));
|
|
541
557
|
continue;
|
|
542
558
|
} else if (fkdetails === false && columndata.hasOwnProperty("foreign_key")) {
|
|
543
559
|
console.log(cstyler.yellow("Foreign key need to be added for "), cstyler.blue("Database: "), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue(" Table: "), cstyler.hex("#00d9ffff")(tableName), cstyler.blue(" Column Name: "), cstyler.hex("#00d9ffff")(jsoncolumn));
|
|
@@ -551,17 +567,18 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
551
567
|
console.error("There was an issue when creating foreign key for", cstyler.blue("Database:"), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue("Table:"), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column:"), cstyler.hex("#00d9ffff")(jsoncolumn));
|
|
552
568
|
return null;
|
|
553
569
|
}
|
|
570
|
+
count += 1;
|
|
554
571
|
} else if (fncs.isJsonObject(fkdetails) && columndata.hasOwnProperty("foreign_key")) {
|
|
555
572
|
// need to check if foreign key details are same
|
|
556
573
|
const fkdt = columndata.foreign_key;
|
|
557
574
|
if (fkdetails.table === fkdt.table &&
|
|
558
575
|
fkdetails.column === fkdt.column &&
|
|
559
576
|
fkdetails.deleteOption === fkdt.deleteOption &&
|
|
560
|
-
(fkdt.updateOption === undefined ||fkdetails.updateOption === fkdt.updateOption)) {
|
|
577
|
+
(fkdt.updateOption === undefined || fkdetails.updateOption === fkdt.updateOption)) {
|
|
578
|
+
console.log(cstyler.underline("Foreign key details are matched. No changes needed."))
|
|
561
579
|
continue;
|
|
562
580
|
}
|
|
563
|
-
console.log(cstyler.
|
|
564
|
-
console.log(cstyler.yellow("Foreign key details are different, updating foreign key for "), cstyler.blue("Database: "), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue(" Table: "), cstyler.hex("#00d9ffff")(tableName), cstyler.blue(" Column Name: "), cstyler.hex("#00d9ffff")(jsoncolumn));
|
|
581
|
+
console.log(cstyler.blue("Database: "), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue(" Table: "), cstyler.hex("#00d9ffff")(tableName), cstyler.blue(" Column Name: "), cstyler.hex("#00d9ffff")(jsoncolumn), cstyler.yellow("- Foreign key details are different, updating foreign key."));
|
|
565
582
|
// need to update foreign key
|
|
566
583
|
const dropfk = await fncs.removeForeignKeyFromColumn(config, databaseName, tableName, jsoncolumn);
|
|
567
584
|
if (dropfk === null) {
|
|
@@ -577,12 +594,20 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
577
594
|
console.error("There was an issue when creating foreign key for", cstyler.blue("Database:"), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue("Table:"), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column:"), cstyler.hex("#00d9ffff")(jsoncolumn));
|
|
578
595
|
return null;
|
|
579
596
|
}
|
|
597
|
+
count += 1;
|
|
598
|
+
} else {
|
|
599
|
+
console.log(cstyler.bold.red("There must be some issue when checking foreignkey details. Please contact support or re-install the module."))
|
|
580
600
|
}
|
|
581
601
|
}
|
|
582
602
|
}
|
|
583
603
|
}
|
|
584
604
|
}
|
|
585
|
-
|
|
605
|
+
if (count > 0) {
|
|
606
|
+
console.log(cstyler.bold.underline.green("Successfully altered " + count + " columns."))
|
|
607
|
+
} else {
|
|
608
|
+
console.log(cstyler.bold.underline("No column were altered at all."))
|
|
609
|
+
}
|
|
610
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Alter Column process to tables are completed successfully."));
|
|
586
611
|
return true;
|
|
587
612
|
} catch (err) {
|
|
588
613
|
console.error(err.message);
|
|
@@ -592,4 +617,4 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
592
617
|
|
|
593
618
|
module.exports = {
|
|
594
619
|
alterColumnIfNeeded
|
|
595
|
-
}
|
|
620
|
+
}
|
package/dropcolumn.js
CHANGED
|
@@ -9,7 +9,7 @@ const cstyler = require("cstyler");
|
|
|
9
9
|
async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
10
10
|
try {
|
|
11
11
|
console.log(cstyler.bold.yellow("Initiating drop column operation"));
|
|
12
|
-
|
|
12
|
+
let count = 0;
|
|
13
13
|
if (!fncs.isJsonObject(tableJson)) {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
@@ -149,7 +149,8 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
149
149
|
);
|
|
150
150
|
return null;
|
|
151
151
|
}
|
|
152
|
-
|
|
152
|
+
console.log(cstyler.blue("Database: "), cstyler.hex("#00d9ffff")(databaseName), cstyler.blue(" Table: "), cstyler.hex("#00d9ffff")(tableName), cstyler.blue("Column: "), cstyler.hex("#00d9ffff")(column), cstyler.green("- dropped successfully."))
|
|
153
|
+
count += 1;
|
|
153
154
|
console.log(
|
|
154
155
|
cstyler.bold.green("Successfully dropped column:"),
|
|
155
156
|
cstyler.hex("#00d9ffff")(column),
|
|
@@ -159,7 +160,11 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
|
-
|
|
163
|
+
if (count > 0) {
|
|
164
|
+
console.log(cstyler.green("Successfully dropped ", count, " columns."));
|
|
165
|
+
} else {
|
|
166
|
+
console.log("There is not column found to be dropped.");
|
|
167
|
+
}
|
|
163
168
|
return true;
|
|
164
169
|
} catch (err) {
|
|
165
170
|
console.error(err?.message || err);
|
package/function.js
CHANGED
|
@@ -187,8 +187,9 @@ async function isMySQLDatabase(config) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
async function checkDatabaseExists(config, dbName) {
|
|
190
|
+
let connection;
|
|
190
191
|
try {
|
|
191
|
-
|
|
192
|
+
connection = await mysql.createConnection({
|
|
192
193
|
host: config.host,
|
|
193
194
|
user: config.user,
|
|
194
195
|
password: config.password,
|
|
@@ -202,6 +203,8 @@ async function checkDatabaseExists(config, dbName) {
|
|
|
202
203
|
} catch (err) {
|
|
203
204
|
console.error(err.message);
|
|
204
205
|
return null;
|
|
206
|
+
} finally {
|
|
207
|
+
if (connection) await connection.end();
|
|
205
208
|
}
|
|
206
209
|
}
|
|
207
210
|
async function dropDatabase(config, databaseName) {
|
|
@@ -1193,7 +1196,7 @@ async function inspectColumnConstraint(config, database, table, column, options
|
|
|
1193
1196
|
console.error(err.message);
|
|
1194
1197
|
return null;
|
|
1195
1198
|
} finally {
|
|
1196
|
-
await conn.end();
|
|
1199
|
+
if (conn) await conn.end();
|
|
1197
1200
|
}
|
|
1198
1201
|
}
|
|
1199
1202
|
async function _fetchIndexes(conn, database, tableName) {
|
|
@@ -1280,7 +1283,7 @@ async function checkIndexExists(config, database, tableName, indexKey) {
|
|
|
1280
1283
|
console.error("Error in checkIndexExists:", err.message);
|
|
1281
1284
|
return null;
|
|
1282
1285
|
} finally {
|
|
1283
|
-
await conn.end();
|
|
1286
|
+
if (conn) await conn.end();
|
|
1284
1287
|
}
|
|
1285
1288
|
}
|
|
1286
1289
|
async function columnHasKey(config, databaseName, tableName, columnName) {
|
|
@@ -1527,7 +1530,7 @@ async function findReferencingFromColumns(config, database, parentTable, parentC
|
|
|
1527
1530
|
console.error("Error in findReferencingColumns:", err.message);
|
|
1528
1531
|
return null;
|
|
1529
1532
|
} finally {
|
|
1530
|
-
await conn.end();
|
|
1533
|
+
if (conn) await conn.end();
|
|
1531
1534
|
}
|
|
1532
1535
|
}
|
|
1533
1536
|
async function addForeignKeyWithIndex(config, dbName, tableName, columnName, refTable, refColumn, options = {}) {
|
|
@@ -1851,8 +1854,64 @@ async function runQuery(config, databaseName, queryText) {
|
|
|
1851
1854
|
if (connection) await connection.end();
|
|
1852
1855
|
}
|
|
1853
1856
|
}
|
|
1857
|
+
async function checkDuplicates(config, databaseName, tableName, columnName) {
|
|
1858
|
+
let connection;
|
|
1859
|
+
|
|
1860
|
+
try {
|
|
1861
|
+
connection = await mysql.createConnection({
|
|
1862
|
+
...config,
|
|
1863
|
+
database: databaseName
|
|
1864
|
+
});
|
|
1865
|
+
|
|
1866
|
+
const sql = `
|
|
1867
|
+
SELECT COUNT(*) as duplicateCount
|
|
1868
|
+
FROM (
|
|
1869
|
+
SELECT \`${columnName}\`
|
|
1870
|
+
FROM \`${tableName}\`
|
|
1871
|
+
GROUP BY \`${columnName}\`
|
|
1872
|
+
HAVING COUNT(\`${columnName}\`) > 1
|
|
1873
|
+
) AS dup_query`;
|
|
1874
|
+
|
|
1875
|
+
const [rows] = await connection.execute(sql);
|
|
1876
|
+
|
|
1877
|
+
// Returns true if duplicates exist, false if not
|
|
1878
|
+
return rows[0].duplicateCount > 0;
|
|
1879
|
+
|
|
1880
|
+
} catch (err) {
|
|
1881
|
+
console.error(`Check Error: ${err.message}`);
|
|
1882
|
+
return null;
|
|
1883
|
+
} finally {
|
|
1884
|
+
if (connection) await connection.end();
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
async function cleanDuplicateRows(config, databaseName, tableName, columnName) {
|
|
1888
|
+
let connection;
|
|
1854
1889
|
|
|
1890
|
+
try {
|
|
1891
|
+
connection = await mysql.createConnection({
|
|
1892
|
+
...config,
|
|
1893
|
+
database: databaseName
|
|
1894
|
+
});
|
|
1855
1895
|
|
|
1896
|
+
// We use a self-join to find rows with matching values but higher IDs
|
|
1897
|
+
const sql = `
|
|
1898
|
+
DELETE t1 FROM \`${tableName}\` t1
|
|
1899
|
+
INNER JOIN \`${tableName}\` t2
|
|
1900
|
+
ON t1.\`${columnName}\` = t2.\`${columnName}\`
|
|
1901
|
+
AND t1.id > t2.id`;
|
|
1902
|
+
|
|
1903
|
+
const [result] = await connection.execute(sql);
|
|
1904
|
+
|
|
1905
|
+
// Returns the number of deleted rows
|
|
1906
|
+
return result.affectedRows;
|
|
1907
|
+
|
|
1908
|
+
} catch (err) {
|
|
1909
|
+
console.error(`Clean Error: ${err.message}`);
|
|
1910
|
+
return null;
|
|
1911
|
+
} finally {
|
|
1912
|
+
if (connection) await connection.end();
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1856
1915
|
|
|
1857
1916
|
|
|
1858
1917
|
module.exports = {
|
|
@@ -1903,4 +1962,6 @@ module.exports = {
|
|
|
1903
1962
|
dropColumn,
|
|
1904
1963
|
writeJsFile,
|
|
1905
1964
|
runQuery,
|
|
1965
|
+
checkDuplicates,
|
|
1966
|
+
cleanDuplicateRows,
|
|
1906
1967
|
}
|
package/index.js
CHANGED
|
@@ -148,7 +148,7 @@ module.exports = async function (allconfig, table_json) {
|
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
150
|
const jsondata = checking.data;
|
|
151
|
-
console.log(cstyler.bold.
|
|
151
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Lets start operation on databases."));
|
|
152
152
|
const dbop = require("./dbop");
|
|
153
153
|
const databaseop = await dbop.databaseAddDeleteAlter(config, jsondata, dropdatabase, donttouchdb, separator);
|
|
154
154
|
if (databaseop === null) {
|
|
@@ -164,18 +164,18 @@ module.exports = async function (allconfig, table_json) {
|
|
|
164
164
|
}
|
|
165
165
|
// Drop tables
|
|
166
166
|
if (droptable) {
|
|
167
|
-
console.log(cstyler.bold.
|
|
167
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Lets drop unlisted table if needed."));
|
|
168
168
|
const droptableifneeded = await tableop.dropTable(config, jsondata, separator);
|
|
169
169
|
if (droptableifneeded === null) {
|
|
170
170
|
console.log(cstyler.bold.underline.red("Error occurred during dropping tables."));
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
|
-
console.log(cstyler.bold.
|
|
174
|
+
console.log(cstyler.bold.underline.green("<<<Lets start working on columns>>>"));
|
|
175
175
|
const colop = require("./dropcolumn");
|
|
176
176
|
|
|
177
177
|
// lets drop columns if needed
|
|
178
|
-
console.log(cstyler.bold.
|
|
178
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Lets drop unlisted columns if needed."));
|
|
179
179
|
if (dropcolumn) {
|
|
180
180
|
const dropcolifneeded = await colop.dropcolumn(config, jsondata, forcedropcolumn, separator);
|
|
181
181
|
if (dropcolifneeded === null) {
|
|
@@ -185,7 +185,7 @@ module.exports = async function (allconfig, table_json) {
|
|
|
185
185
|
}
|
|
186
186
|
// lets add columns if needed
|
|
187
187
|
const addcolumn = require("./addcolumn");
|
|
188
|
-
console.log(cstyler.bold.
|
|
188
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Lets add columns if needed."));
|
|
189
189
|
const addcolifneeded = await addcolumn.addColumnIfNeeded(config, jsondata, separator);
|
|
190
190
|
if (addcolifneeded === null) {
|
|
191
191
|
console.log(cstyler.bold.underline.red("Error occurred during adding columns."));
|
|
@@ -193,17 +193,13 @@ module.exports = async function (allconfig, table_json) {
|
|
|
193
193
|
}
|
|
194
194
|
// lets alter columns if needed
|
|
195
195
|
const altercolop = require("./altercolumn");
|
|
196
|
-
console.log(cstyler.bold.
|
|
196
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Lets alter columns if needed."));
|
|
197
197
|
const altercolifneeded = await altercolop.alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separator);
|
|
198
198
|
if (altercolifneeded === null) {
|
|
199
199
|
console.log(cstyler.bold.underline.red("Error occurred during altering columns."));
|
|
200
200
|
return;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
203
|
console.log(cstyler.bold.underline.green("<<<All database work is done perfectly>>>"));
|
|
208
204
|
} catch (err) {
|
|
209
205
|
console.error(err.message);
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbtasker",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.9",
|
|
4
4
|
"funding": {
|
|
5
5
|
"type": "patreon",
|
|
6
|
-
"url": "https://www.patreon.com/
|
|
6
|
+
"url": "https://www.patreon.com/kormoi/gift"
|
|
7
7
|
},
|
|
8
8
|
"description": "dbtasker is a powerful and developer-friendly MySQL schema automation tool that converts JSON-based definitions into validated SQL that allows developers to declaratively define databases, tables, columns, indexes, and foreign keys using a flexible, case-insensitive JSON schema.",
|
|
9
9
|
"license": "ISC",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
+
"crypto": "^1.0.1",
|
|
41
42
|
"cstyler": "^4.0.0",
|
|
42
43
|
"fs": "^0.0.1-security",
|
|
43
44
|
"mysql2": "^3.14.3",
|
package/tableop.js
CHANGED
|
@@ -158,7 +158,7 @@ async function createTableIfNeeded(config, jsondata, separator) {
|
|
|
158
158
|
return false;
|
|
159
159
|
}
|
|
160
160
|
let foreignkeys = {};
|
|
161
|
-
console.log(cstyler.bold.
|
|
161
|
+
console.log(cstyler.bold.underline.hex("#00fff2ff")("Lets start creating unlisted tables if needed."));
|
|
162
162
|
// Lets check config
|
|
163
163
|
for (const jsdb of Object.keys(jsondata)) {
|
|
164
164
|
let dbname = fncs.perseDatabaseNameWithLoop(jsdb, separator);
|
|
@@ -209,7 +209,7 @@ async function createTableIfNeeded(config, jsondata, separator) {
|
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
|
-
console.log(cstyler.bold.underline.
|
|
212
|
+
console.log(cstyler.bold.underline.green("Create table if needed process completed successfully."));
|
|
213
213
|
return true;
|
|
214
214
|
} catch (err) {
|
|
215
215
|
console.error(cstyler.bold.red("Error occurred in createTableIfNeeded function of ", moduleName, " module. Error details: "), err);
|
|
@@ -254,11 +254,11 @@ async function dropTable(config, json_data, separator = "_") {
|
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
257
|
+
}
|
|
258
|
+
if (count > 0) {
|
|
259
|
+
console.log(cstyler.green("Successfully dropped ", count, " unlisted tables"));
|
|
260
|
+
} else {
|
|
261
|
+
console.log(cstyler.underline("No table found to be dropped"));
|
|
262
262
|
}
|
|
263
263
|
return true;
|
|
264
264
|
} catch (err) {
|