diff --git a/lib/migration.js b/lib/migration.js index fb82cd7..5b0ff4e 100644 --- a/lib/migration.js +++ b/lib/migration.js @@ -185,10 +185,28 @@ function mixinMigration(MySQL, mysql) { // second: check multiple indexes var orderMatched = true; if (indexNames.indexOf(indexName) !== -1) { - m.settings.indexes[indexName].columns.split(/,\s*/).forEach( - function(columnName, i) { - if (ai[indexName].columns[i] !== columnName) orderMatched = false; - }); + //check if indexes are configured as "columns" + if (m.settings.indexes[indexName].columns) { + m.settings.indexes[indexName].columns.split(/,\s*/).forEach( + function(columnName, i) { + if (ai[indexName].columns[i] !== columnName) orderMatched = false; + }); + } else if (m.settings.indexes[indexName].keys) { + //if indexes are configured as "keys" + var index = 0; + for (var key in m.settings.indexes[indexName].keys) { + var sortOrder = m.settings.indexes[indexName].keys[key]; + if (ai[indexName].columns[index] !== key) { + orderMatched = false; + break; + } + index++; + } + //if number of columns differ between new and old index + if (index !== ai[indexName].columns.length) { + orderMatched = false; + } + } } if (!orderMatched) { sql.push('DROP INDEX ' + self.client.escapeId(indexName)); @@ -237,13 +255,35 @@ function mixinMigration(MySQL, mysql) { } if (i.kind) { kind = i.kind; + } else if (i.options && i.options.unique && i.options.unique == true) { + //if index unique indicator is configured + kind = 'UNIQUE'; + } + + var indexedColumns = []; + var columns = ''; + //if indexes are configured as "keys" + if (i.keys) { + for (var key in i.keys) { + if (i.keys[key] !== -1) { + indexedColumns.push(key); + } else { + indexedColumns.push(key + ' DESC '); + } + } + } + if (indexedColumns.length > 0) { + columns = indexedColumns.join(','); + } else if (i.columns) { + //if indexes are configured as "columns" + columns = i.columns; } if (kind && type) { sql.push('ADD ' + kind + ' INDEX ' + iName + - ' (' + i.columns + ') ' + type); + ' (' + columns + ') ' + type); } else { sql.push('ADD ' + kind + ' INDEX ' + type + ' ' + iName + - ' (' + i.columns + ')'); + ' (' + columns + ')'); } } }); @@ -370,23 +410,43 @@ function mixinMigration(MySQL, mysql) { type = 'USING ' + i.type; } if (i.kind) { + //if index uniqueness is configured as "kind" kind = i.kind; + } else if (i.options && i.options.unique && i.options.unique == true) { + //if index unique indicator is configured + kind = 'UNIQUE'; } var indexedColumns = []; var indexName = this.escapeName(index); - if (Array.isArray(i.keys)) { - indexedColumns = i.keys.map(function(key) { - return self.columnEscaped(model, key); - }); + var columns = ''; + //if indexes are configured as "keys" + if (i.keys) { + //for each field in "keys" object + for (var key in i.keys) { + if (i.keys[key] !== -1) { + indexedColumns.push(key); + } else { + //mysql does not support index sorting Currently + //but mysql has added DESC keyword for future support + indexedColumns.push(key + ' DESC '); + } + } } - var columns = indexedColumns.join(',') || i.columns; - if (kind && type) { - indexClauses.push(kind + ' INDEX ' + indexName + ' (' + columns + ') ' + type); - } else { - indexClauses.push(kind + ' INDEX ' + type + ' ' + indexName + ' (' + columns + ')'); + if (indexedColumns.length) { + columns = indexedColumns.join(','); + } else if (i.columns) { + columns = i.columns; + } + if (columns.length) { + if (kind && type) { + indexClauses.push(kind + ' INDEX ' + + indexName + ' (' + columns + ') ' + type); + } else { + indexClauses.push(kind + ' INDEX ' + type + + ' ' + indexName + ' (' + columns + ')'); + } } } - // Define index for each of the properties for (var p in definition.properties) { var propIndex = self.buildIndex(model, p); diff --git a/test/mysql.autoupdate.test.js b/test/mysql.autoupdate.test.js index aa933a5..b9e5114 100644 --- a/test/mysql.autoupdate.test.js +++ b/test/mysql.autoupdate.test.js @@ -23,6 +23,16 @@ describe('MySQL connector', function() { 'schema': 'myapp_test', 'table': 'customer_test', }, + 'indexes': { + 'name_index': { + 'keys': { + 'name': 1, + }, + 'options': { + 'unique': true, + }, + }, + }, }, 'properties': { 'id': { @@ -56,6 +66,17 @@ describe('MySQL connector', function() { 'schema': 'myapp_test', 'table': 'customer_test', }, + 'indexes': { + 'updated_name_index': { + 'keys': { + 'firstName': 1, + 'lastName': -1, + }, + 'options': { + 'unique': true, + }, + }, + }, }, 'properties': { 'id': { @@ -104,19 +125,38 @@ describe('MySQL connector', function() { assert.equal(names[2], 'email'); assert.equal(names[3], 'age'); - ds.createModel(schema_v2.name, schema_v2.properties, schema_v2.options); - - ds.autoupdate(function(err, result) { - ds.discoverModelProperties('customer_test', function(err, props) { - assert.equal(props.length, 4); - var names = props.map(function(p) { - return p.columnName; + ds.connector.execute('SHOW INDEXES FROM customer_test', function(err, indexes) { + if (err) return done (err); + assert(indexes); + assert(indexes.length.should.be.above(1)); + assert.equal(indexes[1].Key_name, 'name_index'); + assert.equal(indexes[1].Non_unique, 0); + ds.createModel(schema_v2.name, schema_v2.properties, schema_v2.options); + ds.autoupdate(function(err, result) { + if (err) return done (err); + ds.discoverModelProperties('customer_test', function(err, props) { + if (err) return done (err); + assert.equal(props.length, 4); + var names = props.map(function(p) { + return p.columnName; + }); + assert.equal(names[0], 'id'); + assert.equal(names[1], 'email'); + assert.equal(names[2], 'firstName'); + assert.equal(names[3], 'lastName'); + ds.connector.execute('SHOW INDEXES FROM customer_test', function(err, updatedindexes) { + if (err) return done (err); + assert(updatedindexes); + assert(updatedindexes.length.should.be.above(2)); + assert.equal(updatedindexes[1].Key_name, 'updated_name_index'); + assert.equal(updatedindexes[2].Key_name, 'updated_name_index'); + //Mysql supports only index sorting in ascending; DESC is ignored + assert.equal(updatedindexes[1].Collation, 'A'); + assert.equal(updatedindexes[2].Collation, 'A'); + assert.equal(updatedindexes[1].Non_unique, 0); + done(err, result); + }); }); - assert.equal(names[0], 'id'); - assert.equal(names[1], 'email'); - assert.equal(names[2], 'firstName'); - assert.equal(names[3], 'lastName'); - done(err, result); }); }); });