不要怂,就是干,撸起袖子干!

Commit 381751a6 by Matt Broadstone

fix problems with mssql constraints

temporarily disable on update foreign key constraints, mssql dialect
now passes all current test cases
1 parent bba87023
...@@ -41,3 +41,9 @@ matrix: ...@@ -41,3 +41,9 @@ matrix:
allow_failures: allow_failures:
- node_js: "0.10" - node_js: "0.10"
env: COVERAGE=true env: COVERAGE=true
notifications:
hipchat:
- 40e8850aaba9854ac4c9963bd33f8b@253477
irc:
- "chat.freenode.net#sequelizejs"
...@@ -46,7 +46,7 @@ module.exports = (function() { ...@@ -46,7 +46,7 @@ module.exports = (function() {
primaryKeys.push(attr); primaryKeys.push(attr);
if (Utils._.includes(dataType, 'REFERENCES')) { if (Utils._.includes(dataType, 'REFERENCES')) {
// MySQL doesn't support inline REFERENCES declarations: move to the end // MSSQL doesn't support inline REFERENCES declarations: move to the end
match = dataType.match(/^(.+) (REFERENCES.*)$/); match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(this.quoteIdentifier(attr) + ' ' + match[1].replace(/PRIMARY KEY/, '')); attrStr.push(this.quoteIdentifier(attr) + ' ' + match[1].replace(/PRIMARY KEY/, ''));
foreignKeys[attr] = match[2]; foreignKeys[attr] = match[2];
...@@ -54,7 +54,7 @@ module.exports = (function() { ...@@ -54,7 +54,7 @@ module.exports = (function() {
attrStr.push(this.quoteIdentifier(attr) + ' ' + dataType.replace(/PRIMARY KEY/, '')); attrStr.push(this.quoteIdentifier(attr) + ' ' + dataType.replace(/PRIMARY KEY/, ''));
} }
} else if (Utils._.includes(dataType, 'REFERENCES')) { } else if (Utils._.includes(dataType, 'REFERENCES')) {
// MySQL doesn't support inline REFERENCES declarations: move to the end // MSSQL doesn't support inline REFERENCES declarations: move to the end
match = dataType.match(/^(.+) (REFERENCES.*)$/); match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(this.quoteIdentifier(attr) + ' ' + match[1]); attrStr.push(this.quoteIdentifier(attr) + ' ' + match[1]);
foreignKeys[attr] = match[2]; foreignKeys[attr] = match[2];
...@@ -381,42 +381,28 @@ module.exports = (function() { ...@@ -381,42 +381,28 @@ module.exports = (function() {
attributesToSQL: function(attributes, options) { attributesToSQL: function(attributes, options) {
var result = {} var result = {}
, key , key
, attribute; , attribute
, existingConstraints = [];
//detect multiple cascades associated with the same id
var cascadeCheck = [];
for (key in attributes) { for (key in attributes) {
attribute = attributes[key]; attribute = attributes[key];
if (attribute.onDelete || attribute.onUpdate) {
//handles self referencial keys, first it doesnt make sense, second, what? if (attribute.references) {
if (attribute.Model && attribute.Model.tableName === attribute.references) { if (existingConstraints.indexOf(attribute.references.toString()) !== -1) {
this.sequelize.log('MSSQL does not support self referencial constraints, ' // no cascading constraints to a table more than once
+ 'we will remove it but we recommend restructuring your query');
attribute.onDelete = ''; attribute.onDelete = '';
attribute.onUpdate = ''; attribute.onUpdate = '';
} else { } else {
cascadeCheck.push(key); existingConstraints.push(attribute.references.toString());
}
}
}
for (var i = 0; i < cascadeCheck.length-1; i++) { // NOTE: this really just disables cascading updates for all
var casKey = cascadeCheck[i]; // definitions. Can be made more robust to support the
for (var j = i+1; j < cascadeCheck.length; j++) { // few cases where MSSQL actually supports them
var casKey2 = cascadeCheck[j]; attribute.onUpdate = '';
if (attributes[casKey].referencesKey === attributes[casKey2].referencesKey) {
this.sequelize.log('MSSQL does not support multiple cascade keys on the same reference, '
+ 'we will remove them to make this work but we recommend restructuring your query.');
attributes[casKey].onDelete = '';
attributes[casKey].onUpdate = '';
attributes[casKey2].onDelete = '';
attributes[casKey2].onUpdate = '';
} }
} }
}
for (key in attributes) {
attribute = attributes[key];
if (key && !attribute.field) attribute.field = key; if (key && !attribute.field) attribute.field = key;
result[attribute.field || key] = this.attributeToSQL(attribute, options); result[attribute.field || key] = this.attributeToSQL(attribute, options);
} }
......
...@@ -167,6 +167,8 @@ module.exports = (function() { ...@@ -167,6 +167,8 @@ module.exports = (function() {
match = err.message.match(/Violation of UNIQUE KEY constraint '(.*)'. Cannot insert duplicate key in object '?(.*?)$/); match = err.message.match(/Violation of UNIQUE KEY constraint '(.*)'. Cannot insert duplicate key in object '?(.*?)$/);
match = match || err.message.match(/Cannot insert duplicate key row in object .* with unique index '(.*)'/); match = match || err.message.match(/Cannot insert duplicate key row in object .* with unique index '(.*)'/);
if (match && match.length > 1) { if (match && match.length > 1) {
console.log(err);
return new sequelizeErrors.UniqueConstraintError({ return new sequelizeErrors.UniqueConstraintError({
name: 'SequelizeUniqueConstraintError', name: 'SequelizeUniqueConstraintError',
fields: null, fields: null,
...@@ -179,6 +181,7 @@ module.exports = (function() { ...@@ -179,6 +181,7 @@ module.exports = (function() {
match = err.message.match(/Failed on step '(.*)'.Could not create constraint. See previous errors./); match = err.message.match(/Failed on step '(.*)'.Could not create constraint. See previous errors./);
match = err.message.match(/The DELETE statement conflicted with the REFERENCE constraint "(.*)". The conflict occurred in database "(.*)", table "(.*)", column '(.*)'./); match = err.message.match(/The DELETE statement conflicted with the REFERENCE constraint "(.*)". The conflict occurred in database "(.*)", table "(.*)", column '(.*)'./);
if (match && match.length > 0) { if (match && match.length > 0) {
console.log(err);
return new sequelizeErrors.ForeignKeyConstraintError({ return new sequelizeErrors.ForeignKeyConstraintError({
fields: null, fields: null,
index: match[1], index: match[1],
...@@ -186,6 +189,7 @@ module.exports = (function() { ...@@ -186,6 +189,7 @@ module.exports = (function() {
}); });
} }
console.log(err);
return new sequelizeErrors.DatabaseError(err); return new sequelizeErrors.DatabaseError(err);
}; };
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!