From 62d0e459c0d0d9e34c4c4ae3d1370ab70f587a7c Mon Sep 17 00:00:00 2001 From: Anatoliy Chakkaev Date: Fri, 17 Aug 2012 23:39:22 +0400 Subject: [PATCH] Single-column indexes in mysql (autoupdate) --- lib/adapters/mysql.js | 45 ++++++++++++++++++++++++++++++++------ test/migration_test.coffee | 25 +++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/lib/adapters/mysql.js b/lib/adapters/mysql.js index 2b22271d..6d682aa2 100644 --- a/lib/adapters/mysql.js +++ b/lib/adapters/mysql.js @@ -293,11 +293,13 @@ MySQL.prototype.autoupdate = function (cb) { Object.keys(this._models).forEach(function (model) { wait += 1; self.query('SHOW FIELDS FROM ' + self.tableEscaped(model), function (err, fields) { - if (!err && fields.length) { - self.alterTable(model, fields, done); - } else { - self.createTable(model, done); - } + self.query('SHOW INDEXES FROM ' + self.tableEscaped(model), function (err, indexes) { + if (!err && fields.length) { + self.alterTable(model, fields, indexes, done); + } else { + self.createTable(model, done); + } + }); }); }); @@ -318,7 +320,7 @@ MySQL.prototype.isActual = function (cb) { Object.keys(this._models).forEach(function (model) { wait += 1; self.query('SHOW FIELDS FROM ' + model, function (err, fields) { - self.alterTable(model, fields, done, true); + self.alterTable(model, fields, null, done, true); }); }); @@ -333,7 +335,7 @@ MySQL.prototype.isActual = function (cb) { } }; -MySQL.prototype.alterTable = function (model, actualFields, done, checkOnly) { +MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done, checkOnly) { var self = this; var m = this._models[model]; var propNames = Object.keys(m.properties).filter(function (name) { @@ -366,6 +368,35 @@ MySQL.prototype.alterTable = function (model, actualFields, done, checkOnly) { } }); + // add single-column indexes + propNames.forEach(function (propName) { + if (!m.properties[propName].index) { + return; + } + var found; + if (actualIndexes) { + actualIndexes.forEach(function (f) { + if (f.Column_name === propName) { + found = f; + } + }); + } + if (!found) { + sql.push('ADD INDEX `' + propName + '` (`' + propName + '`)'); + } + }); + + // remove single-column indexes + if (actualIndexes) { + actualIndexes.forEach(function (f) { + var propName = f.Key_name; + if (propName === 'id') return; + if (m.properties[propName] && !m.properties[propName].index) { + sql.push('DROP INDEX `' + propName + '`'); + } + }); + } + if (sql.length) { if (checkOnly) { done(null, true); diff --git a/test/migration_test.coffee b/test/migration_test.coffee index 65f618a5..b90646f0 100644 --- a/test/migration_test.coffee +++ b/test/migration_test.coffee @@ -39,6 +39,15 @@ getFields = (model, cb) -> res.forEach (field) -> fields[field.Field] = field cb err, fields +getIndexes = (model, cb) -> + query 'SHOW INDEXES FROM ' + model, (err, res) -> + if err + cb err + else + indexes = {} + res.forEach (index) -> indexes[index.Key_name] = index + cb err, indexes + it 'should run migration', (test) -> withBlankDatabase (err) -> schema.automigrate -> @@ -143,6 +152,22 @@ it 'should check actuality of schema', (test) -> test.ok not ok test.done() +it 'should add single-column index', (test) -> + User.defineProperty 'email', type: String, index: true + User.schema.autoupdate (err) -> + return console.log(err) if err + getIndexes 'User', (err, ixs) -> + test.ok ixs.email && ixs.email.Column_name == 'email' + test.done() + +it 'should remove single-column index', (test) -> + User.defineProperty 'email', type: String, index: false + User.schema.autoupdate (err) -> + return console.log(err) if err + getIndexes 'User', (err, ixs) -> + test.ok !ixs.email + test.done() + it 'should disconnect when done', (test) -> schema.disconnect() test.done()