Merge branch 'release/1.5.0' into production
This commit is contained in:
commit
a20b35edfd
10
CHANGES.md
10
CHANGES.md
|
@ -1,3 +1,13 @@
|
||||||
|
2015-01-09, Version 1.5.0
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* Use mysql.escape/escapeId() (Raymond Feng)
|
||||||
|
|
||||||
|
* Fix bad CLA URL in CONTRIBUTING.md (Ryan Graham)
|
||||||
|
|
||||||
|
* (cherry picked from commit a6d31e8) (yogesh)
|
||||||
|
|
||||||
|
|
||||||
2014-12-05, Version 1.4.9
|
2014-12-05, Version 1.4.9
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ Contributing to `loopback-connector-mysql` is easy. In a few simple steps:
|
||||||
* Adhere to code style outlined in the [Google C++ Style Guide][] and
|
* Adhere to code style outlined in the [Google C++ Style Guide][] and
|
||||||
[Google Javascript Style Guide][].
|
[Google Javascript Style Guide][].
|
||||||
|
|
||||||
* Sign the [Contributor License Agreement](https://cla.strongloop.com/strongloop/loopback-connector-mysql)
|
* Sign the [Contributor License Agreement](https://cla.strongloop.com/agreements/strongloop/loopback-connector-mysql)
|
||||||
|
|
||||||
* Submit a pull request through Github.
|
* Submit a pull request through Github.
|
||||||
|
|
||||||
|
|
33
lib/mysql.js
33
lib/mysql.js
|
@ -171,7 +171,7 @@ MySQL.prototype.query = function (sql, callback) {
|
||||||
}
|
}
|
||||||
if (self.settings.createDatabase) {
|
if (self.settings.createDatabase) {
|
||||||
// Call USE db ...
|
// Call USE db ...
|
||||||
connection.query('USE `' + db + '`', function (err) {
|
connection.query('USE ' + client.escapeId(db), function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err && err.message.match(/(^|: )unknown database/i)) {
|
if (err && err.message.match(/(^|: )unknown database/i)) {
|
||||||
var charset = self.settings.charset;
|
var charset = self.settings.charset;
|
||||||
|
@ -179,7 +179,7 @@ MySQL.prototype.query = function (sql, callback) {
|
||||||
var q = 'CREATE DATABASE ' + db + ' CHARACTER SET ' + charset + ' COLLATE ' + collation;
|
var q = 'CREATE DATABASE ' + db + ' CHARACTER SET ' + charset + ' COLLATE ' + collation;
|
||||||
connection.query(q, function (err) {
|
connection.query(q, function (err) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
connection.query('USE `' + db + '`', function (err) {
|
connection.query('USE ' + client.escapeId(db), function (err) {
|
||||||
runQuery(connection);
|
runQuery(connection);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,8 +324,7 @@ MySQL.prototype.toDatabase = function (prop, val, forCreate) {
|
||||||
return this.client.escape(val);
|
return this.client.escape(val);
|
||||||
}
|
}
|
||||||
if (prop.type === Number) {
|
if (prop.type === Number) {
|
||||||
val = Number(val);
|
return this.client.escape(val);
|
||||||
return isNaN(val) ? 'NULL' : val;
|
|
||||||
}
|
}
|
||||||
if (prop.type === Date) {
|
if (prop.type === Date) {
|
||||||
if (!val) {
|
if (!val) {
|
||||||
|
@ -400,7 +399,7 @@ MySQL.prototype.fromDatabase = function (model, data) {
|
||||||
};
|
};
|
||||||
|
|
||||||
MySQL.prototype.escapeName = function (name) {
|
MySQL.prototype.escapeName = function (name) {
|
||||||
return '`' + name.replace(/\./g, '`.`') + '`';
|
return this.client.escapeId(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
MySQL.prototype.getColumns = function (model, props) {
|
MySQL.prototype.getColumns = function (model, props) {
|
||||||
|
@ -771,7 +770,8 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
if (found) {
|
if (found) {
|
||||||
actualize(propName, found);
|
actualize(propName, found);
|
||||||
} else {
|
} else {
|
||||||
sql.push('ADD COLUMN `' + propName + '` ' + self.propertySettingsSQL(model, propName));
|
sql.push('ADD COLUMN ' + self.client.escapeId(propName) + ' ' +
|
||||||
|
self.propertySettingsSQL(model, propName));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -781,7 +781,7 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
var notFound = !~propNames.indexOf(f.Field);
|
var notFound = !~propNames.indexOf(f.Field);
|
||||||
if (m.properties[f.Field] && self.id(model, f.Field)) return;
|
if (m.properties[f.Field] && self.id(model, f.Field)) return;
|
||||||
if (notFound || !m.properties[f.Field]) {
|
if (notFound || !m.properties[f.Field]) {
|
||||||
sql.push('DROP COLUMN `' + f.Field + '`');
|
sql.push('DROP COLUMN ' + self.client.escapeId(f.Field));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -790,7 +790,7 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
aiNames.forEach(function (indexName) {
|
aiNames.forEach(function (indexName) {
|
||||||
if (indexName === 'PRIMARY' || (m.properties[indexName] && self.id(model, indexName))) return;
|
if (indexName === 'PRIMARY' || (m.properties[indexName] && self.id(model, indexName))) return;
|
||||||
if (indexNames.indexOf(indexName) === -1 && !m.properties[indexName] || m.properties[indexName] && !m.properties[indexName].index) {
|
if (indexNames.indexOf(indexName) === -1 && !m.properties[indexName] || m.properties[indexName] && !m.properties[indexName].index) {
|
||||||
sql.push('DROP INDEX `' + indexName + '`');
|
sql.push('DROP INDEX ' + self.client.escapeId(indexName));
|
||||||
} else {
|
} else {
|
||||||
// first: check single (only type and kind)
|
// first: check single (only type and kind)
|
||||||
if (m.properties[indexName] && !m.properties[indexName].index) {
|
if (m.properties[indexName] && !m.properties[indexName].index) {
|
||||||
|
@ -805,7 +805,7 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!orderMatched) {
|
if (!orderMatched) {
|
||||||
sql.push('DROP INDEX `' + indexName + '`');
|
sql.push('DROP INDEX ' + self.client.escapeId(indexName));
|
||||||
delete ai[indexName];
|
delete ai[indexName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,6 +819,7 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
}
|
}
|
||||||
var found = ai[propName] && ai[propName].info;
|
var found = ai[propName] && ai[propName].info;
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
var pName = self.client.escapeId(propName);
|
||||||
var type = '';
|
var type = '';
|
||||||
var kind = '';
|
var kind = '';
|
||||||
if (i.type) {
|
if (i.type) {
|
||||||
|
@ -828,9 +829,10 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
// kind = i.kind;
|
// kind = i.kind;
|
||||||
}
|
}
|
||||||
if (kind && type) {
|
if (kind && type) {
|
||||||
sql.push('ADD ' + kind + ' INDEX `' + propName + '` (`' + propName + '`) ' + type);
|
sql.push('ADD ' + kind + ' INDEX ' + pName + ' (' + pName + ') ' + type);
|
||||||
} else {
|
} else {
|
||||||
sql.push('ADD ' + kind + ' INDEX `' + propName + '` ' + type + ' (`' + propName + '`) ');
|
(typeof i === 'object' && i.unique && i.unique === true) && (kind = "UNIQUE");
|
||||||
|
sql.push('ADD ' + kind + ' INDEX ' + pName + ' ' + type + ' (' + pName + ') ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -840,6 +842,7 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
var i = m.settings.indexes[indexName];
|
var i = m.settings.indexes[indexName];
|
||||||
var found = ai[indexName] && ai[indexName].info;
|
var found = ai[indexName] && ai[indexName].info;
|
||||||
if (!found) {
|
if (!found) {
|
||||||
|
var iName = self.client.escapeId(indexName);
|
||||||
var type = '';
|
var type = '';
|
||||||
var kind = '';
|
var kind = '';
|
||||||
if (i.type) {
|
if (i.type) {
|
||||||
|
@ -849,9 +852,9 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
kind = i.kind;
|
kind = i.kind;
|
||||||
}
|
}
|
||||||
if (kind && type) {
|
if (kind && type) {
|
||||||
sql.push('ADD ' + kind + ' INDEX `' + indexName + '` (' + i.columns + ') ' + type);
|
sql.push('ADD ' + kind + ' INDEX ' + iName + ' (' + i.columns + ') ' + type);
|
||||||
} else {
|
} else {
|
||||||
sql.push('ADD ' + kind + ' INDEX ' + type + ' `' + indexName + '` (' + i.columns + ')');
|
sql.push('ADD ' + kind + ' INDEX ' + type + ' ' + iName + ' (' + i.columns + ')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -870,7 +873,8 @@ MySQL.prototype.alterTable = function (model, actualFields, actualIndexes, done,
|
||||||
function actualize(propName, oldSettings) {
|
function actualize(propName, oldSettings) {
|
||||||
var newSettings = m.properties[propName];
|
var newSettings = m.properties[propName];
|
||||||
if (newSettings && changed(newSettings, oldSettings)) {
|
if (newSettings && changed(newSettings, oldSettings)) {
|
||||||
sql.push('CHANGE COLUMN `' + propName + '` `' + propName + '` ' +
|
var pName = self.client.escapeId(propName);
|
||||||
|
sql.push('CHANGE COLUMN ' + pName + ' ' + pName + ' ' +
|
||||||
self.propertySettingsSQL(model, propName));
|
self.propertySettingsSQL(model, propName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -967,6 +971,7 @@ MySQL.prototype.singleIndexSettingsSQL = function (model, prop) {
|
||||||
if (kind && type) {
|
if (kind && type) {
|
||||||
return (kind + ' INDEX ' + columnName + ' (' + columnName + ') ' + type);
|
return (kind + ' INDEX ' + columnName + ' (' + columnName + ') ' + type);
|
||||||
} else {
|
} else {
|
||||||
|
(typeof i === 'object' && i.unique && i.unique === true) && (kind = "UNIQUE");
|
||||||
return (kind + ' INDEX ' + columnName + ' ' + type + ' (' + columnName + ') ');
|
return (kind + ' INDEX ' + columnName + ' ' + type + ' (' + columnName + ') ');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-connector-mysql",
|
"name": "loopback-connector-mysql",
|
||||||
"version": "1.4.9",
|
"version": "1.5.0",
|
||||||
"description": "MySQL connector for loopback-datasource-juggler",
|
"description": "MySQL connector for loopback-datasource-juggler",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -27,6 +27,6 @@
|
||||||
"url": "https://github.com/strongloop/loopback-connector-mysql/blob/master/LICENSE"
|
"url": "https://github.com/strongloop/loopback-connector-mysql/blob/master/LICENSE"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"sl-blip": "http://blip.strongloop.com/loopback-connector-mysql@1.4.9"
|
"sl-blip": "http://blip.strongloop.com/loopback-connector-mysql@1.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var should = require('./init.js');
|
var should = require('./init.js');
|
||||||
|
|
||||||
var Post, PostWithStringId, db;
|
var Post, PostWithStringId, PostWithUniqueTitle, db;
|
||||||
|
|
||||||
describe('mysql', function () {
|
describe('mysql', function () {
|
||||||
|
|
||||||
|
@ -21,7 +21,12 @@ describe('mysql', function () {
|
||||||
content: { type: String }
|
content: { type: String }
|
||||||
});
|
});
|
||||||
|
|
||||||
db.automigrate(['PostWithDefaultId', 'PostWithStringId'], function (err) {
|
PostWithUniqueTitle = db.define('PostWithUniqueTitle', {
|
||||||
|
title: { type: String, length: 255, index: {unique: true} },
|
||||||
|
content: { type: String }
|
||||||
|
});
|
||||||
|
|
||||||
|
db.automigrate(['PostWithDefaultId', 'PostWithStringId', 'PostWithUniqueTitle'], function (err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
|
@ -30,7 +35,9 @@ describe('mysql', function () {
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
Post.destroyAll(function () {
|
Post.destroyAll(function () {
|
||||||
PostWithStringId.destroyAll(function () {
|
PostWithStringId.destroyAll(function () {
|
||||||
done();
|
PostWithUniqueTitle.destroyAll(function () {
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -448,9 +455,22 @@ describe('mysql', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not allow duplicate titles', function (done) {
|
||||||
|
var data = {title: 'a', content: 'AAA'};
|
||||||
|
PostWithUniqueTitle.create(data, function (err, post) {
|
||||||
|
should.not.exist(err);
|
||||||
|
PostWithUniqueTitle.create(data, function (err, post) {
|
||||||
|
should.exist(err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
Post.destroyAll(function () {
|
Post.destroyAll(function () {
|
||||||
PostWithStringId.destroyAll(done);
|
PostWithStringId.destroyAll(function () {
|
||||||
|
PostWithUniqueTitle.destroyAll(done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue