dbtasker 3.1.1 → 3.1.2
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/README.md +2 -2
- package/altercolumn.js +3 -3
- package/dropcolumn.js +12 -56
- package/function.js +28 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,13 +29,13 @@ Property | Description
|
|
|
29
29
|
| **host** | MySQL Host (e.g., `localhost`) |
|
|
30
30
|
| **user** | Database Username |
|
|
31
31
|
| **password** | Database Password |
|
|
32
|
-
| **port** | Connection Port (
|
|
32
|
+
| **port** | Connection Port (e.g., `3306`) |
|
|
33
33
|
| **drop database** | `Boolean`: If true, allows dropping databases. |
|
|
34
34
|
| **drop table** | `Boolean`: If true, allows dropping tables. |
|
|
35
35
|
| **drop column** | `Boolean`: If true, allows dropping columns. |
|
|
36
36
|
| **do not touch** | `Array`: List of database names protected from deletion. |
|
|
37
37
|
| **force delete column** | `Boolean`: If true, allow dropping column even if referanced by any other column. |
|
|
38
|
-
| **force update column** | `Boolean`: It is set `default: false` If true, allow updating column even if referanced by any other column. This one is very powerful. If you turn it on it will remove any foreign key that is referanced to the column is being updated then update the column then add the foreign key to those column again and if the column is set to `UNIQUE` it will remove all the column value that are
|
|
38
|
+
| **force update column** | `Boolean`: It is set `default: false` If true, allow updating column even if referanced by any other column. This one is very powerful. If you turn it on it will remove any foreign key that is referanced to the column is being updated then update the column then add the foreign key to those column again and if the column is set to `UNIQUE` it will remove all the column value that are same. |
|
|
39
39
|
|
|
40
40
|
### Configuration Example
|
|
41
41
|
`JavaScript`
|
package/altercolumn.js
CHANGED
|
@@ -310,7 +310,9 @@ async function alterColumnQuery(dbConfig, columndata, columnName, tableName, dat
|
|
|
310
310
|
}
|
|
311
311
|
if (hasdupes === true) {
|
|
312
312
|
if (forceupdatecolumn) {
|
|
313
|
+
console.log(cstyler.bold.underline.yellow("********************************************************"));
|
|
313
314
|
console.log(cstyler.bold.underline.yellow("***Cleaning duplicate rows before adding UNIQUE index***"));
|
|
315
|
+
console.log(cstyler.bold.underline.yellow("********************************************************"));
|
|
314
316
|
const cleancol = await fncs.cleanDuplicateRows(dbConfig, database, tableName, columnName);
|
|
315
317
|
if (cleancol === null) {
|
|
316
318
|
console.error("Having server connection problem cleaning duplicate rows from database");
|
|
@@ -404,6 +406,7 @@ async function addForeignKeyWithIndexQuery(config, databaseName, tableName, colu
|
|
|
404
406
|
async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separator) {
|
|
405
407
|
try {
|
|
406
408
|
console.log(cstyler.bold.yellow("Let's initiate Alter Column to table if needed..."));
|
|
409
|
+
console.log(cstyler.bold.blue("Please wait..."));
|
|
407
410
|
let count = 0;
|
|
408
411
|
for (const jsondb of Object.keys(jsondata)) {
|
|
409
412
|
const loopdb = fncs.perseTableNameWithLoop(jsondb, separator);
|
|
@@ -550,10 +553,8 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
550
553
|
}
|
|
551
554
|
}
|
|
552
555
|
} else {
|
|
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."));
|
|
554
556
|
// lets check if foreign key need update
|
|
555
557
|
if (fkdetails === false && !columndata.hasOwnProperty("foreign_key")) {
|
|
556
|
-
console.log(cstyler.underline("Column do not have foreign key."));
|
|
557
558
|
continue;
|
|
558
559
|
} else if (fkdetails === false && columndata.hasOwnProperty("foreign_key")) {
|
|
559
560
|
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));
|
|
@@ -575,7 +576,6 @@ async function alterColumnIfNeeded(config, jsondata, forceupdatecolumn, separato
|
|
|
575
576
|
fkdetails.column === fkdt.column &&
|
|
576
577
|
fkdetails.deleteOption === fkdt.deleteOption &&
|
|
577
578
|
(fkdt.updateOption === undefined || fkdetails.updateOption === fkdt.updateOption)) {
|
|
578
|
-
console.log(cstyler.underline("Foreign key details are matched. No changes needed."))
|
|
579
579
|
continue;
|
|
580
580
|
}
|
|
581
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."));
|
package/dropcolumn.js
CHANGED
|
@@ -17,11 +17,7 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
17
17
|
for (const jsDb of Object.keys(tableJson)) {
|
|
18
18
|
const parsedDb = fncs.perseDatabaseNameWithLoop(jsDb, separator);
|
|
19
19
|
if (!parsedDb) {
|
|
20
|
-
console.error(
|
|
21
|
-
cstyler.bold.red("Cannot parse database name."),
|
|
22
|
-
jsDb,
|
|
23
|
-
parsedDb
|
|
24
|
-
);
|
|
20
|
+
console.error(cstyler.bold.red("Cannot parse database name."), jsDb, parsedDb);
|
|
25
21
|
return null;
|
|
26
22
|
}
|
|
27
23
|
|
|
@@ -34,20 +30,13 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
34
30
|
|
|
35
31
|
const parsedTable = fncs.perseTableNameWithLoop(jsTable, separator);
|
|
36
32
|
if (!parsedTable) {
|
|
37
|
-
console.error(
|
|
38
|
-
cstyler.bold.red("Cannot parse table name."),
|
|
39
|
-
jsTable
|
|
40
|
-
);
|
|
33
|
+
console.error(cstyler.bold.red("Cannot parse table name."), jsTable);
|
|
41
34
|
return null;
|
|
42
35
|
}
|
|
43
36
|
|
|
44
37
|
const tableName = parsedTable.loopname;
|
|
45
38
|
|
|
46
|
-
const existingColumns = await fncs.getColumnNames(
|
|
47
|
-
config,
|
|
48
|
-
databaseName,
|
|
49
|
-
tableName
|
|
50
|
-
);
|
|
39
|
+
const existingColumns = await fncs.getColumnNames(config, databaseName, tableName);
|
|
51
40
|
|
|
52
41
|
if (!existingColumns) {
|
|
53
42
|
console.error(
|
|
@@ -60,14 +49,10 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
60
49
|
}
|
|
61
50
|
|
|
62
51
|
for (const column of existingColumns) {
|
|
63
|
-
const definedInJson = Object.prototype.hasOwnProperty.call(
|
|
64
|
-
tableDef,
|
|
65
|
-
column
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const isValidDefinition =
|
|
69
|
-
definedInJson && fncs.isJsonObject(tableDef[column]);
|
|
52
|
+
const definedInJson = Object.prototype.hasOwnProperty.call(tableDef, column);
|
|
70
53
|
|
|
54
|
+
const isValidDefinition = definedInJson && fncs.isJsonObject(tableDef[column]);
|
|
55
|
+
|
|
71
56
|
if (isValidDefinition) continue;
|
|
72
57
|
|
|
73
58
|
console.log(
|
|
@@ -79,19 +64,10 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
79
64
|
cstyler.yellow(column)
|
|
80
65
|
);
|
|
81
66
|
|
|
82
|
-
const referencingColumns =
|
|
83
|
-
await fncs.findReferencingFromColumns(
|
|
84
|
-
config,
|
|
85
|
-
databaseName,
|
|
86
|
-
tableName,
|
|
87
|
-
column
|
|
88
|
-
);
|
|
67
|
+
const referencingColumns = await fncs.findReferencingFromColumns(config, databaseName, tableName, column);
|
|
89
68
|
|
|
90
69
|
if (referencingColumns === null) {
|
|
91
|
-
console.error(
|
|
92
|
-
cstyler.bold.red("Failed to resolve FK references for column:"),
|
|
93
|
-
cstyler.hex("#00d9ffff")(column)
|
|
94
|
-
);
|
|
70
|
+
console.error(cstyler.bold.red("Failed to resolve FK references for column:"), cstyler.hex("#00d9ffff")(column));
|
|
95
71
|
return null;
|
|
96
72
|
}
|
|
97
73
|
|
|
@@ -108,12 +84,7 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
108
84
|
let allFkRemoved = true;
|
|
109
85
|
|
|
110
86
|
for (const ref of referencingColumns) {
|
|
111
|
-
const removed = await fncs.removeForeignKeyFromColumn(
|
|
112
|
-
config,
|
|
113
|
-
ref.child_schema,
|
|
114
|
-
ref.child_table,
|
|
115
|
-
ref.child_columns[0]
|
|
116
|
-
);
|
|
87
|
+
const removed = await fncs.removeForeignKeyFromColumn(config, ref.child_schema, ref.child_table, ref.child_columns[0]);
|
|
117
88
|
|
|
118
89
|
if (removed === null) {
|
|
119
90
|
console.error(
|
|
@@ -127,21 +98,12 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
127
98
|
}
|
|
128
99
|
|
|
129
100
|
if (!allFkRemoved) {
|
|
130
|
-
console.error(
|
|
131
|
-
cstyler.bold.red("Aborting column drop due to FK failures:"),
|
|
132
|
-
cstyler.hex("#00d9ffff")(column)
|
|
133
|
-
);
|
|
101
|
+
console.error(cstyler.bold.red("Aborting column drop due to FK failures:"), cstyler.hex("#00d9ffff")(column));
|
|
134
102
|
continue;
|
|
135
103
|
}
|
|
136
104
|
}
|
|
137
105
|
|
|
138
|
-
const dropped = await fncs.dropColumn(
|
|
139
|
-
config,
|
|
140
|
-
databaseName,
|
|
141
|
-
tableName,
|
|
142
|
-
column
|
|
143
|
-
);
|
|
144
|
-
|
|
106
|
+
const dropped = await fncs.dropColumn(config, databaseName, tableName, column);
|
|
145
107
|
if (dropped === null) {
|
|
146
108
|
console.error(
|
|
147
109
|
cstyler.bold.red("Failed to drop column:"),
|
|
@@ -151,17 +113,11 @@ async function dropcolumn(config, tableJson, forceDropColumn, separator = "_") {
|
|
|
151
113
|
}
|
|
152
114
|
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
115
|
count += 1;
|
|
154
|
-
console.log(
|
|
155
|
-
cstyler.bold.green("Successfully dropped column:"),
|
|
156
|
-
cstyler.hex("#00d9ffff")(column),
|
|
157
|
-
cstyler.bold.green("from table:"),
|
|
158
|
-
cstyler.hex("#00d9ffff")(tableName)
|
|
159
|
-
);
|
|
160
116
|
}
|
|
161
117
|
}
|
|
162
118
|
}
|
|
163
119
|
if (count > 0) {
|
|
164
|
-
console.log(cstyler.green("Successfully dropped "
|
|
120
|
+
console.log(cstyler.bold.green("Successfully dropped " + count + " columns."));
|
|
165
121
|
} else {
|
|
166
122
|
console.log("There is not column found to be dropped.");
|
|
167
123
|
}
|
package/function.js
CHANGED
|
@@ -289,35 +289,33 @@ async function dropTable(config, databaseName, tableName) {
|
|
|
289
289
|
async function dropColumn(config, databaseName, tableName, columnName) {
|
|
290
290
|
let connection;
|
|
291
291
|
try {
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
// Ensure the database is selected in the config
|
|
293
|
+
const dbConfig = { ...config, database: databaseName };
|
|
294
|
+
connection = await mysql.createConnection(dbConfig);
|
|
294
295
|
|
|
295
|
-
// 1️⃣ Check if column exists
|
|
296
|
+
// 1️⃣ Check if column exists and get its metadata
|
|
296
297
|
const [columns] = await connection.query(
|
|
297
|
-
`SELECT COLUMN_NAME, COLUMN_KEY
|
|
298
|
-
FROM INFORMATION_SCHEMA.COLUMNS
|
|
298
|
+
`SELECT COLUMN_NAME, COLUMN_KEY, COLUMN_TYPE, EXTRA
|
|
299
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
|
299
300
|
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?`,
|
|
300
301
|
[databaseName, tableName, columnName]
|
|
301
302
|
);
|
|
302
303
|
|
|
303
|
-
// ❌ Column does not exist → return false
|
|
304
304
|
if (columns.length === 0) {
|
|
305
|
-
console.log(
|
|
306
|
-
`Column '${columnName}' does not exist in ${databaseName}.${tableName}`
|
|
307
|
-
);
|
|
305
|
+
console.log(`Column '${columnName}' does not exist in ${tableName}.`);
|
|
308
306
|
return false;
|
|
309
307
|
}
|
|
310
308
|
|
|
311
|
-
const columnKey = columns[0].COLUMN_KEY;
|
|
309
|
+
const columnKey = columns[0].COLUMN_KEY; // "PRI", "UNI", or ""
|
|
310
|
+
const columnType = columns[0].COLUMN_TYPE; // e.g., "int(11)"
|
|
311
|
+
const isAutoIncrement = columns[0].EXTRA.toLowerCase().includes('auto_increment');
|
|
312
312
|
|
|
313
|
-
// 2️⃣ Drop
|
|
313
|
+
// 2️⃣ Drop Foreign Key constraints first
|
|
314
314
|
const [fkConstraints] = await connection.query(
|
|
315
315
|
`SELECT CONSTRAINT_NAME
|
|
316
316
|
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
|
317
|
-
WHERE TABLE_SCHEMA = ?
|
|
318
|
-
|
|
319
|
-
AND COLUMN_NAME = ?
|
|
320
|
-
AND REFERENCED_TABLE_NAME IS NOT NULL`,
|
|
317
|
+
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?
|
|
318
|
+
AND REFERENCED_TABLE_NAME IS NOT NULL`,
|
|
321
319
|
[databaseName, tableName, columnName]
|
|
322
320
|
);
|
|
323
321
|
|
|
@@ -327,23 +325,28 @@ async function dropColumn(config, databaseName, tableName, columnName) {
|
|
|
327
325
|
);
|
|
328
326
|
}
|
|
329
327
|
|
|
330
|
-
// 3️⃣
|
|
331
|
-
|
|
328
|
+
// 3️⃣ Handle Primary Key and Auto-Increment Conflict
|
|
329
|
+
// If it's Auto-Increment, we MUST remove that attribute before dropping the key
|
|
330
|
+
if (isAutoIncrement) {
|
|
331
|
+
// Modifying without the 'AUTO_INCREMENT' keyword
|
|
332
332
|
await connection.query(
|
|
333
|
-
`ALTER TABLE \`${tableName}\`
|
|
333
|
+
`ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${columnName}\` ${columnType}`
|
|
334
334
|
);
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
//
|
|
337
|
+
// Now it is safe to drop the Primary Key constraint if it was one
|
|
338
|
+
if (columnKey === "PRI") {
|
|
339
|
+
await connection.query(`ALTER TABLE \`${tableName}\` DROP PRIMARY KEY`);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// 4️⃣ Final Step: Drop the column
|
|
338
343
|
await connection.query(
|
|
339
344
|
`ALTER TABLE \`${tableName}\` DROP COLUMN \`${columnName}\``
|
|
340
345
|
);
|
|
341
346
|
|
|
342
|
-
console.log(
|
|
343
|
-
`Column '${columnName}' dropped successfully from ${databaseName}.${tableName}`
|
|
344
|
-
);
|
|
345
|
-
|
|
347
|
+
console.log(`Column '${columnName}' dropped successfully from ${tableName}`);
|
|
346
348
|
return true;
|
|
349
|
+
|
|
347
350
|
} catch (err) {
|
|
348
351
|
console.error("Error dropping column:", err.message);
|
|
349
352
|
return null;
|
|
@@ -1873,7 +1876,7 @@ async function checkDuplicates(config, databaseName, tableName, columnName) {
|
|
|
1873
1876
|
) AS dup_query`;
|
|
1874
1877
|
|
|
1875
1878
|
const [rows] = await connection.execute(sql);
|
|
1876
|
-
|
|
1879
|
+
|
|
1877
1880
|
// Returns true if duplicates exist, false if not
|
|
1878
1881
|
return rows[0].duplicateCount > 0;
|
|
1879
1882
|
|
|
@@ -1901,7 +1904,7 @@ async function cleanDuplicateRows(config, databaseName, tableName, columnName) {
|
|
|
1901
1904
|
AND t1.id > t2.id`;
|
|
1902
1905
|
|
|
1903
1906
|
const [result] = await connection.execute(sql);
|
|
1904
|
-
|
|
1907
|
+
|
|
1905
1908
|
// Returns the number of deleted rows
|
|
1906
1909
|
return result.affectedRows;
|
|
1907
1910
|
|