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 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 (Default: `3306`) |
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 simillar. |
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 ", count, " columns."));
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
- config.database = databaseName;
293
- connection = await mysql.createConnection(config);
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 foreign key constraints
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
- AND TABLE_NAME = ?
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️⃣ Drop primary key if needed
331
- if (columnKey === "PRI") {
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}\` DROP PRIMARY KEY`
333
+ `ALTER TABLE \`${tableName}\` MODIFY COLUMN \`${columnName}\` ${columnType}`
334
334
  );
335
335
  }
336
336
 
337
- // 4️⃣ Drop column
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbtasker",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "funding": {
5
5
  "type": "patreon",
6
6
  "url": "https://www.patreon.com/kormoi/gift"