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; 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..b748db4 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, + name: options.foreignKey ? options.foreignKey : 'fk_' + table + '_' + options.columnName, + 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', 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..9365b08 100644 --- a/tests/migration.tests.js +++ b/tests/migration.tests.js @@ -242,5 +242,144 @@ 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', { + 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`'); + }); + }); });