From 168a7f063c81499d92207f8adad4e5b192753c9e Mon Sep 17 00:00:00 2001 From: axiosleo Date: Mon, 23 Feb 2026 10:22:23 +0800 Subject: [PATCH 1/5] feat(migration): add dropIndex and dropIndexWithName methods for enhanced index management --- src/builder.js | 9 +++++++++ src/migration.js | 22 +++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/builder.js b/src/builder.js index c14ab5c..36c5c1c 100644 --- a/src/builder.js +++ b/src/builder.js @@ -622,6 +622,15 @@ class ManageSQLBuilder extends Builder { } dropIndex(options) { + _validate(options, { + columns: 'required|array', + table: 'required|string', + }); + options.name = 'idx_' + options.table + '_' + options.columns.join('_'); + return _render('DROP INDEX `${name}` ON `${table}`', options); + } + + dropIndexWithName(options) { _validate(options, { name: 'required|string', table: 'required|string', diff --git a/src/migration.js b/src/migration.js index 8f65925..3b821a8 100644 --- a/src/migration.js +++ b/src/migration.js @@ -220,12 +220,12 @@ function _initMigration(file, queries = {}) { }); Object.defineProperty(migration, 'createForeignKey', { - value: function (options = {}) { + value: function (table, options = {}) { _assign(options, { operator: 'create', target: 'foreignKey', name: options.foreignKey ? options.foreignKey : 'fk_' + options.tableName + '_' + options.columnName, - table: options.tableName, + table: table, column: options.columnName, reference: options.reference }); @@ -246,7 +246,7 @@ function _initMigration(file, queries = {}) { }); Object.defineProperty(migration, 'dropColumn', { - value: function (name, table) { + value: function (table, name) { const builder = new ManageSQLBuilder({ operator: 'drop', target: 'column', @@ -258,10 +258,22 @@ function _initMigration(file, queries = {}) { }); Object.defineProperty(migration, 'dropIndex', { - value: function (name, table) { + value: function (table, columns) { const builder = new ManageSQLBuilder({ operator: 'drop', target: 'index', + columns, + table + }); + queries[file].push({ sql: builder.sql, values: builder.values }); + }, ...baseAttr + }); + + Object.defineProperty(migration, 'dropIndexWithName', { + value: function (table, name) { + const builder = new ManageSQLBuilder({ + operator: 'drop', + target: 'indexWithName', name, table }); @@ -270,7 +282,7 @@ function _initMigration(file, queries = {}) { }); Object.defineProperty(migration, 'dropForeignKey', { - value: function (name, table) { + value: function (table, name) { const builder = new ManageSQLBuilder({ operator: 'drop', target: 'foreignKey', From 967f83e1b5fe065ddd570afd77050eb64340f438 Mon Sep 17 00:00:00 2001 From: axiosleo Date: Mon, 23 Feb 2026 10:22:32 +0800 Subject: [PATCH 2/5] refactor(migration): update method signatures for createForeignKey, dropColumn, dropIndex, and dropForeignKey to improve clarity and consistency --- index.d.ts | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9d31983..42cd9ac 100644 --- a/index.d.ts +++ b/index.d.ts @@ -637,9 +637,8 @@ export declare class MigrationInterface { spatial?: boolean }): void; - createForeignKey(options: { + createForeignKey(table: string, options: { foreignKey?: string, - tableName: string, columnName: string, reference: { tableName: string, @@ -649,13 +648,34 @@ export declare class MigrationInterface { } }): void; + /** + * drop table from database + * @param tableName + */ dropTable(tableName: string): void; - dropColumn(columnName: string, tableName: string): void; + /** + * drop column from table + * @param columnName + * @param tableName + */ + dropColumn(tableName: string, columnName: string): void; + + /** + * drop index from table + * @param indexName + * @param tableName + */ + dropIndex(tableName: string, columns: string[]): void; - dropIndex(indexName: string, tableName: string): void; + dropIndexWithName(tableName: string, indexName: string): void; - dropForeignKey(foreign_key: string, tableName: string): void; + /** + * drop foreign key from table + * @param foreign_key + * @param tableName + */ + dropForeignKey(tableName: string, foreign_key: string): void; insertData(table: string, data: any[]): void; From 3d1f9aebc1a08220dc884318c03ada525828e963 Mon Sep 17 00:00:00 2001 From: axiosleo Date: Mon, 23 Feb 2026 10:22:40 +0800 Subject: [PATCH 3/5] feat(tests): enhance builder and migration tests with additional cases for dropIndex and createForeignKey methods --- tests/builder.tests.js | 28 +++++++- tests/migration.tests.js | 140 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 3 deletions(-) diff --git a/tests/builder.tests.js b/tests/builder.tests.js index 1b0c192..216e897 100644 --- a/tests/builder.tests.js +++ b/tests/builder.tests.js @@ -872,15 +872,37 @@ describe('builder test case', () => { expect(sql).to.include('`name` DESC'); }); - it('should handle dropIndex', () => { + it('should handle dropIndex with columns', () => { const options = { operator: 'drop', target: 'index', table: 'test_table', - name: 'idx_name' + columns: ['name'] }; const sql = (new ManageSQLBuilder(options)).sql; - expect(sql).to.be.equal('DROP INDEX `idx_name` ON `test_table`'); + expect(sql).to.be.equal('DROP INDEX `idx_test_table_name` ON `test_table`'); + }); + + it('should handle dropIndex with multiple columns', () => { + const options = { + operator: 'drop', + target: 'index', + table: 'test_table', + columns: ['first_name', 'last_name'] + }; + const sql = (new ManageSQLBuilder(options)).sql; + expect(sql).to.be.equal('DROP INDEX `idx_test_table_first_name_last_name` ON `test_table`'); + }); + + it('should handle dropIndexWithName', () => { + const options = { + operator: 'drop', + target: 'indexWithName', + table: 'test_table', + name: 'idx_custom_name' + }; + const sql = (new ManageSQLBuilder(options)).sql; + expect(sql).to.be.equal('DROP INDEX `idx_custom_name` ON `test_table`'); }); it('should handle dropForeignKey', () => { diff --git a/tests/migration.tests.js b/tests/migration.tests.js index ce7db4d..5a33481 100644 --- a/tests/migration.tests.js +++ b/tests/migration.tests.js @@ -242,5 +242,145 @@ describe('migration test case', () => { expect(queries[file][2].sql).to.be.equal('SET FOREIGN_KEY_CHECKS = 1'); }); }); + + describe('createForeignKey method', () => { + it('should create foreign key with auto-generated name', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.createForeignKey('orders', { + tableName: 'orders', + columnName: 'user_id', + reference: { + tableName: 'users', + columnName: 'id', + onDelete: 'CASCADE', + onUpdate: 'RESTRICT' + } + }); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.include('orders'); + expect(queries[file][0].sql).to.include('FOREIGN KEY'); + expect(queries[file][0].sql).to.include('fk_orders_user_id'); + }); + + it('should create foreign key with custom name', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.createForeignKey('orders', { + foreignKey: 'fk_custom_key', + columnName: 'user_id', + reference: { + tableName: 'users', + columnName: 'id' + } + }); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.include('fk_custom_key'); + }); + }); + + describe('dropTable method', () => { + it('should drop table', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropTable('users'); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.be.equal('DROP TABLE `users`'); + }); + }); + + describe('dropColumn method', () => { + it('should drop column with table as first param', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropColumn('users', 'email'); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.be.equal('ALTER TABLE `users` DROP COLUMN `email`'); + }); + + it('should drop multiple columns separately', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropColumn('users', 'email'); + migrationObj.dropColumn('users', 'phone'); + + expect(queries[file].length).to.be.equal(2); + expect(queries[file][0].sql).to.include('DROP COLUMN `email`'); + expect(queries[file][1].sql).to.include('DROP COLUMN `phone`'); + }); + }); + + describe('dropIndex method', () => { + it('should drop index by columns with auto-generated name', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropIndex('users', ['email']); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.be.equal('DROP INDEX `idx_users_email` ON `users`'); + }); + + it('should drop index by multiple columns', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropIndex('users', ['first_name', 'last_name']); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.be.equal('DROP INDEX `idx_users_first_name_last_name` ON `users`'); + }); + }); + + describe('dropIndexWithName method', () => { + it('should drop index by explicit name', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropIndexWithName('users', 'idx_custom_name'); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.be.equal('DROP INDEX `idx_custom_name` ON `users`'); + }); + }); + + describe('dropForeignKey method', () => { + it('should drop foreign key with table as first param', () => { + const queries = {}; + const file = 'test_migration.js'; + queries[file] = []; + const migrationObj = _initMigration(file, queries); + + migrationObj.dropForeignKey('orders', 'fk_orders_user_id'); + + expect(queries[file].length).to.be.equal(1); + expect(queries[file][0].sql).to.be.equal('ALTER TABLE `orders` DROP FOREIGN KEY `fk_orders_user_id`'); + }); + }); }); From b1b09d5edd205f51a0c91bbe4b6a21ab9ca6009f Mon Sep 17 00:00:00 2001 From: axiosleo Date: Mon, 23 Feb 2026 10:46:20 +0800 Subject: [PATCH 4/5] fix(migration): correct foreign key name generation to use 'table' instead of 'tableName' --- src/migration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/migration.js b/src/migration.js index 3b821a8..0077013 100644 --- a/src/migration.js +++ b/src/migration.js @@ -224,7 +224,7 @@ function _initMigration(file, queries = {}) { _assign(options, { operator: 'create', target: 'foreignKey', - name: options.foreignKey ? options.foreignKey : 'fk_' + options.tableName + '_' + options.columnName, + name: options.foreignKey ? options.foreignKey : 'fk_' + options.table + '_' + options.columnName, table: table, column: options.columnName, reference: options.reference From 062d559060ab9bfb2d64b8b698a66eb54d545a2f Mon Sep 17 00:00:00 2001 From: axiosleo Date: Mon, 23 Feb 2026 10:47:22 +0800 Subject: [PATCH 5/5] fix(migration): update foreign key name generation to use 'table' variable in _initMigration function --- src/migration.js | 2 +- tests/migration.tests.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/migration.js b/src/migration.js index 0077013..b748db4 100644 --- a/src/migration.js +++ b/src/migration.js @@ -224,7 +224,7 @@ function _initMigration(file, queries = {}) { _assign(options, { operator: 'create', target: 'foreignKey', - name: options.foreignKey ? options.foreignKey : 'fk_' + options.table + '_' + options.columnName, + name: options.foreignKey ? options.foreignKey : 'fk_' + table + '_' + options.columnName, table: table, column: options.columnName, reference: options.reference diff --git a/tests/migration.tests.js b/tests/migration.tests.js index 5a33481..9365b08 100644 --- a/tests/migration.tests.js +++ b/tests/migration.tests.js @@ -251,7 +251,6 @@ describe('migration test case', () => { const migrationObj = _initMigration(file, queries); migrationObj.createForeignKey('orders', { - tableName: 'orders', columnName: 'user_id', reference: { tableName: 'users',