Autoupdate multicolumn indexes
This commit is contained in:
parent
62d0e459c0
commit
12eadb80ae
|
@ -320,7 +320,9 @@ 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, null, done, true);
|
||||
self.query('SHOW INDEXES FROM ' + model, function (err, indexes) {
|
||||
self.alterTable(model, fields, indexes, done, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -341,7 +343,25 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
|||
var propNames = Object.keys(m.properties).filter(function (name) {
|
||||
return !!m.properties[name];
|
||||
});
|
||||
var indexNames = m.settings.indexes ? Object.keys(m.settings.indexes).filter(function (name) {
|
||||
return !!m.settings.indexes[name];
|
||||
}) : [];
|
||||
var sql = [];
|
||||
var ai = {};
|
||||
|
||||
if (actualIndexes) {
|
||||
actualIndexes.forEach(function (i) {
|
||||
var name = i.Key_name;
|
||||
if (!ai[name]) {
|
||||
ai[name] = {
|
||||
info: i,
|
||||
columns: []
|
||||
};
|
||||
}
|
||||
ai[name].columns[i.Seq_in_index - 1] = i.Column_name;
|
||||
});
|
||||
}
|
||||
var aiNames = Object.keys(ai);
|
||||
|
||||
// change/add new fields
|
||||
propNames.forEach(function (propName) {
|
||||
|
@ -368,34 +388,74 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
|||
}
|
||||
});
|
||||
|
||||
// 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 indexes
|
||||
aiNames.forEach(function (indexName) {
|
||||
if (indexName === 'id' || indexName === 'PRIMARY') return;
|
||||
if (indexNames.indexOf(indexName) === -1 || m.properties[indexName] && !m.properties[indexName].index) {
|
||||
sql.push('DROP INDEX `' + indexName + '`');
|
||||
} else {
|
||||
// first: check single (only type and kind)
|
||||
if (m.properties[indexName] && !m.properties[indexName].index) {
|
||||
// TODO
|
||||
}
|
||||
// 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;
|
||||
});
|
||||
}
|
||||
if (!orderMatched) {
|
||||
sql.push('DROP INDEX `' + indexName + '`');
|
||||
delete ai[indexName];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 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 + '`');
|
||||
// add single-column indexes
|
||||
propNames.forEach(function (propName) {
|
||||
var i = m.properties[propName].index;
|
||||
if (!i) {
|
||||
return;
|
||||
}
|
||||
var found = ai[propName] && ai[propName].info;
|
||||
if (!found) {
|
||||
var type = '';
|
||||
var kind = '';
|
||||
if (i.type) {
|
||||
type = 'USING ' + i.type;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (i.kind) {
|
||||
// kind = i.kind;
|
||||
}
|
||||
if (kind && type) {
|
||||
sql.push('ADD ' + kind + ' INDEX `' + propName + '` (`' + propName + '`) ' + type);
|
||||
} else {
|
||||
sql.push('ADD ' + kind + ' INDEX `' + propName + '` ' + type + ' (`' + propName + '`) ');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// add multi-column indexes
|
||||
indexNames.forEach(function (indexName) {
|
||||
var i = m.settings.indexes[indexName];
|
||||
var found = ai[indexName] && ai[indexName].info;
|
||||
if (!found) {
|
||||
var type = '';
|
||||
var kind = '';
|
||||
if (i.type) {
|
||||
type = 'USING ' + i.kind;
|
||||
}
|
||||
if (i.kind) {
|
||||
kind = i.kind;
|
||||
}
|
||||
if (kind && type) {
|
||||
sql.push('ADD ' + kind + ' INDEX `' + indexName + '` (' + i.columns + ') ' + type);
|
||||
} else {
|
||||
sql.push('ADD ' + kind + ' INDEX ' + type + ' `' + indexName + '` (' + i.columns + ')');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (sql.length) {
|
||||
if (checkOnly) {
|
||||
|
|
|
@ -23,6 +23,9 @@ User = schema.define 'User',
|
|||
birthDate: Date
|
||||
pendingPeriod: Number
|
||||
createdByAdmin: Boolean
|
||||
, indexes:
|
||||
index1:
|
||||
columns: 'email, createdByAdmin'
|
||||
|
||||
withBlankDatabase = (cb) ->
|
||||
db = schema.settings.database = DBNAME
|
||||
|
@ -45,7 +48,7 @@ getIndexes = (model, cb) ->
|
|||
cb err
|
||||
else
|
||||
indexes = {}
|
||||
res.forEach (index) -> indexes[index.Key_name] = index
|
||||
res.forEach (index) -> indexes[index.Key_name] = index if index.Seq_in_index == 1
|
||||
cb err, indexes
|
||||
|
||||
it 'should run migration', (test) ->
|
||||
|
@ -146,18 +149,32 @@ it 'should autoupgrade', (test) ->
|
|||
it 'should check actuality of schema', (test) ->
|
||||
# drop column
|
||||
User.schema.isActual (err, ok) ->
|
||||
test.ok ok
|
||||
test.ok ok, 'schema is actual'
|
||||
User.defineProperty 'email', false
|
||||
User.schema.isActual (err, ok) ->
|
||||
test.ok not ok
|
||||
test.ok not ok, 'schema is not actual'
|
||||
test.done()
|
||||
|
||||
it 'should add single-column index', (test) ->
|
||||
User.defineProperty 'email', type: String, index: true
|
||||
User.defineProperty 'email', type: String, index: { kind: 'FULLTEXT', type: 'HASH'}
|
||||
User.schema.autoupdate (err) ->
|
||||
return console.log(err) if err
|
||||
getIndexes 'User', (err, ixs) ->
|
||||
test.ok ixs.email && ixs.email.Column_name == 'email'
|
||||
console.log(ixs)
|
||||
test.equal ixs.email.Index_type, 'BTREE' # default
|
||||
test.done()
|
||||
|
||||
it 'should change type of single-column index', (test) ->
|
||||
User.defineProperty 'email', type: String, index: { type: 'BTREE' }
|
||||
User.schema.isActual (err, ok) ->
|
||||
test.ok not ok, 'schema is not actual'
|
||||
User.schema.autoupdate (err) ->
|
||||
return console.log(err) if err
|
||||
getIndexes 'User', (err, ixs) ->
|
||||
console.log ixs.email
|
||||
test.ok ixs.email && ixs.email.Column_name == 'email'
|
||||
test.equal ixs.email.Index_type, 'BTREE'
|
||||
test.done()
|
||||
|
||||
it 'should remove single-column index', (test) ->
|
||||
|
@ -168,6 +185,16 @@ it 'should remove single-column index', (test) ->
|
|||
test.ok !ixs.email
|
||||
test.done()
|
||||
|
||||
it 'should update multi-column index when order of columns changed', (test) ->
|
||||
User.schema.adapter._models.User.settings.indexes.index1.columns = 'createdByAdmin, email'
|
||||
User.schema.isActual (err, ok) ->
|
||||
test.ok not ok, 'schema is not actual'
|
||||
User.schema.autoupdate (err) ->
|
||||
return console.log(err) if err
|
||||
getIndexes 'User', (err, ixs) ->
|
||||
test.equals ixs.index1.Column_name, 'createdByAdmin'
|
||||
test.done()
|
||||
|
||||
it 'should disconnect when done', (test) ->
|
||||
schema.disconnect()
|
||||
test.done()
|
||||
|
|
Loading…
Reference in New Issue