Merge branch 'release/1.2.3' into production
This commit is contained in:
commit
39445698e9
66
lib/mysql.js
66
lib/mysql.js
|
@ -203,7 +203,7 @@ MySQL.prototype.create = function (model, data, callback) {
|
||||||
* @param {Object} data The model instance data
|
* @param {Object} data The model instance data
|
||||||
* @param {Function} [callback] The callback function
|
* @param {Function} [callback] The callback function
|
||||||
*/
|
*/
|
||||||
MySQL.prototype.updateOrCreate = function (model, data, callback) {
|
MySQL.prototype.updateOrCreate = MySQL.prototype.save = function (model, data, callback) {
|
||||||
var mysql = this;
|
var mysql = this;
|
||||||
var fieldsNames = [];
|
var fieldsNames = [];
|
||||||
var fieldValues = [];
|
var fieldValues = [];
|
||||||
|
@ -244,7 +244,9 @@ MySQL.prototype.toFields = function (model, data) {
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
if (props[key]) {
|
if (props[key]) {
|
||||||
var value = this.toDatabase(props[key], data[key]);
|
var value = this.toDatabase(props[key], data[key]);
|
||||||
if ('undefined' === typeof value) return;
|
if (undefined === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
fields.push(self.columnEscaped(model, key) + ' = ' + value);
|
fields.push(self.columnEscaped(model, key) + ' = ' + value);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -271,8 +273,9 @@ function dateToMysql(val) {
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
MySQL.prototype.toDatabase = function (prop, val) {
|
MySQL.prototype.toDatabase = function (prop, val) {
|
||||||
if (val === null) return 'NULL';
|
if (val === null || val === undefined) {
|
||||||
if (val === undefined) return 'NULL';
|
return 'NULL';
|
||||||
|
}
|
||||||
if (val.constructor.name === 'Object') {
|
if (val.constructor.name === 'Object') {
|
||||||
var operator = Object.keys(val)[0]
|
var operator = Object.keys(val)[0]
|
||||||
val = val[operator];
|
val = val[operator];
|
||||||
|
@ -280,27 +283,36 @@ MySQL.prototype.toDatabase = function (prop, val) {
|
||||||
return this.toDatabase(prop, val[0]) +
|
return this.toDatabase(prop, val[0]) +
|
||||||
' AND ' +
|
' AND ' +
|
||||||
this.toDatabase(prop, val[1]);
|
this.toDatabase(prop, val[1]);
|
||||||
} else if (operator == 'inq' || operator == 'nin') {
|
} else if (operator === 'inq' || operator === 'nin') {
|
||||||
if (!(val.propertyIsEnumerable('length')) && typeof val === 'object' && typeof val.length === 'number') { //if value is array
|
if (Array.isArray(val)) { //if value is array
|
||||||
for (var i = 0; i < val.length; i++) {
|
for (var i = 0; i < val.length; i++) {
|
||||||
val[i] = this.client.escape(val[i]);
|
val[i] = this.toDatabase(prop, val[i]);
|
||||||
}
|
}
|
||||||
return val.join(',');
|
return val.join(',');
|
||||||
} else {
|
} else {
|
||||||
return val;
|
return this.toDatabase(prop, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!prop) return val;
|
if (!prop) {
|
||||||
if (prop.type.name === 'Number') return Number(val);
|
return this.client.escape(val);
|
||||||
if (prop.type.name === 'Date') {
|
}
|
||||||
if (!val) return 'NULL';
|
if (prop.type === Number) {
|
||||||
|
val = Number(val);
|
||||||
|
return isNaN(val) ? 'NULL' : val;
|
||||||
|
}
|
||||||
|
if (prop.type === Date) {
|
||||||
|
if (!val) {
|
||||||
|
return 'NULL';
|
||||||
|
}
|
||||||
if (!val.toUTCString) {
|
if (!val.toUTCString) {
|
||||||
val = new Date(val);
|
val = new Date(val);
|
||||||
}
|
}
|
||||||
return '"' + dateToMysql(val) + '"';
|
return '"' + dateToMysql(val) + '"';
|
||||||
}
|
}
|
||||||
if (prop.type.name == "Boolean") return val ? 1 : 0;
|
if (prop.type === Boolean) {
|
||||||
|
return val ? 1 : 0;
|
||||||
|
}
|
||||||
if (prop.type.name === 'GeoPoint') {
|
if (prop.type.name === 'GeoPoint') {
|
||||||
return val ? 'Point(' + val.lat + ',' + val.lng + ')' : 'NULL';
|
return val ? 'Point(' + val.lat + ',' + val.lng + ')' : 'NULL';
|
||||||
}
|
}
|
||||||
|
@ -399,6 +411,9 @@ MySQL.prototype.buildWhere = function (model, conds) {
|
||||||
};
|
};
|
||||||
|
|
||||||
MySQL.prototype._buildWhere = function (model, conds) {
|
MySQL.prototype._buildWhere = function (model, conds) {
|
||||||
|
if (conds === null || conds === undefined || (typeof conds !== 'object')) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
var self = this;
|
var self = this;
|
||||||
var props = self._models[model].properties;
|
var props = self._models[model].properties;
|
||||||
|
|
||||||
|
@ -483,7 +498,13 @@ function buildOrderBy(self, model, order) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildLimit(limit, offset) {
|
function buildLimit(limit, offset) {
|
||||||
return 'LIMIT ' + (offset ? (offset + ', ' + limit) : limit);
|
if (isNaN(limit)) {
|
||||||
|
limit = 0;
|
||||||
|
}
|
||||||
|
if (isNaN(offset)) {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
return 'LIMIT ' + (offset ? (offset + ',' + limit) : limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -517,7 +538,7 @@ MySQL.prototype.all = function all(model, filter, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter.limit) {
|
if (filter.limit) {
|
||||||
sql += ' ' + buildLimit(filter.limit, filter.skip || 0);
|
sql += ' ' + buildLimit(filter.limit, filter.skip || filter.offset || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -541,6 +562,21 @@ MySQL.prototype.all = function all(model, filter, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MySQL.prototype.count = function count(model, callback, where) {
|
||||||
|
|
||||||
|
this.query('SELECT count(*) as cnt FROM ' +
|
||||||
|
this.tableEscaped(model) + ' ' + this.buildWhere(model, where),
|
||||||
|
function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
var c = (res && res[0] && res[0].cnt) || 0;
|
||||||
|
callback(err, c);
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete instances for the given model
|
* Delete instances for the given model
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-connector-mysql",
|
"name": "loopback-connector-mysql",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "MySQL connector for loopback-datasource-juggler",
|
"description": "MySQL connector for loopback-datasource-juggler",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
"loopback-datasource-juggler": "1.x.x",
|
"loopback-datasource-juggler": "1.x.x",
|
||||||
"should": "~1.3.0",
|
"should": "~1.3.0",
|
||||||
"mocha": "~1.18.0",
|
"mocha": "~1.18.0",
|
||||||
"rc": "~0.3.1"
|
"rc": "~0.4.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -0,0 +1,434 @@
|
||||||
|
var should = require('./init.js');
|
||||||
|
|
||||||
|
var Post, PostWithStringId, db;
|
||||||
|
|
||||||
|
describe('mysql', function () {
|
||||||
|
|
||||||
|
before(function (done) {
|
||||||
|
db = getDataSource();
|
||||||
|
|
||||||
|
Post = db.define('PostWithDefaultId', {
|
||||||
|
title: { type: String, length: 255, index: true },
|
||||||
|
content: { type: String },
|
||||||
|
stars: Number
|
||||||
|
});
|
||||||
|
|
||||||
|
PostWithStringId = db.define('PostWithStringId', {
|
||||||
|
id: {type: String, id: true},
|
||||||
|
title: { type: String, length: 255, index: true },
|
||||||
|
content: { type: String }
|
||||||
|
});
|
||||||
|
|
||||||
|
db.automigrate(['PostWithDefaultId', 'PostWithStringId'], function (err) {
|
||||||
|
should.not.exist(err);
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(function (done) {
|
||||||
|
Post.destroyAll(function () {
|
||||||
|
PostWithStringId.destroyAll(function () {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updateOrCreate should update the instance', function (done) {
|
||||||
|
Post.create({title: 'a', content: 'AAA'}, function (err, post) {
|
||||||
|
post.title = 'b';
|
||||||
|
Post.updateOrCreate(post, function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
|
||||||
|
Post.findById(post.id, function (err, p) {
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.title.should.be.equal('b');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updateOrCreate should update the instance without removing existing properties', function (done) {
|
||||||
|
Post.create({title: 'a', content: 'AAA'}, function (err, post) {
|
||||||
|
post = post.toObject();
|
||||||
|
delete post.title;
|
||||||
|
Post.updateOrCreate(post, function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
Post.findById(post.id, function (err, p) {
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.title.should.be.equal('a');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updateOrCreate should create a new instance if it does not exist', function (done) {
|
||||||
|
var post = {id: 123, title: 'a', content: 'AAA'};
|
||||||
|
Post.updateOrCreate(post, function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.title.should.be.equal(post.title);
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
Post.findById(p.id, function (err, p) {
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.title.should.be.equal(post.title);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('save should update the instance with the same id', function (done) {
|
||||||
|
Post.create({title: 'a', content: 'AAA'}, function (err, post) {
|
||||||
|
post.title = 'b';
|
||||||
|
post.save(function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
|
||||||
|
Post.findById(post.id, function (err, p) {
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.title.should.be.equal('b');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('save should update the instance without removing existing properties', function (done) {
|
||||||
|
Post.create({title: 'a', content: 'AAA'}, function (err, post) {
|
||||||
|
delete post.title;
|
||||||
|
post.save(function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
|
||||||
|
Post.findById(post.id, function (err, p) {
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.title.should.be.equal('a');
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('save should create a new instance if it does not exist', function (done) {
|
||||||
|
var post = new Post({id: 123, title: 'a', content: 'AAA'});
|
||||||
|
post.save(post, function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.title.should.be.equal(post.title);
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
Post.findById(p.id, function (err, p) {
|
||||||
|
should.not.exist(err);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
p.content.should.be.equal(post.content);
|
||||||
|
p.title.should.be.equal(post.title);
|
||||||
|
p.id.should.be.equal(post.id);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('all return should honor filter.fields', function (done) {
|
||||||
|
var post = new Post({title: 'b', content: 'BBB'})
|
||||||
|
post.save(function (err, post) {
|
||||||
|
Post.all({fields: ['title'], where: {title: 'b'}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.lengthOf(1);
|
||||||
|
post = posts[0];
|
||||||
|
post.should.have.property('title', 'b');
|
||||||
|
post.should.not.have.property('content');
|
||||||
|
should.not.exist(post.id);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('find should order by id if the order is not set for the query filter',
|
||||||
|
function (done) {
|
||||||
|
PostWithStringId.create({id: '2', title: 'c', content: 'CCC'}, function (err, post) {
|
||||||
|
PostWithStringId.create({id: '1', title: 'd', content: 'DDD'}, function (err, post) {
|
||||||
|
PostWithStringId.find(function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.length.should.be.equal(2);
|
||||||
|
posts[0].id.should.be.equal('1');
|
||||||
|
|
||||||
|
PostWithStringId.find({limit: 1, offset: 0}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.length.should.be.equal(1);
|
||||||
|
posts[0].id.should.be.equal('1');
|
||||||
|
|
||||||
|
PostWithStringId.find({limit: 1, offset: 1}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.length.should.be.equal(1);
|
||||||
|
posts[0].id.should.be.equal('2');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow to find using like', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {title: {like: 'M%st'}}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support like for no match', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {title: {like: 'M%XY'}}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow to find using nlike', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {title: {nlike: 'M%st'}}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support nlike for no match', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {title: {nlike: 'M%XY'}}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "and" operator that is satisfied', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {and: [
|
||||||
|
{title: 'My Post'},
|
||||||
|
{content: 'Hello'}
|
||||||
|
]}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "and" operator that is not satisfied', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {and: [
|
||||||
|
{title: 'My Post'},
|
||||||
|
{content: 'Hello1'}
|
||||||
|
]}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "or" that is satisfied', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {or: [
|
||||||
|
{title: 'My Post'},
|
||||||
|
{content: 'Hello1'}
|
||||||
|
]}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "or" operator that is not satisfied', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.find({where: {or: [
|
||||||
|
{title: 'My Post1'},
|
||||||
|
{content: 'Hello1'}
|
||||||
|
]}}, function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// The where object should be parsed by the connector
|
||||||
|
it('should support where for count', function (done) {
|
||||||
|
Post.create({title: 'My Post', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.count({and: [
|
||||||
|
{title: 'My Post'},
|
||||||
|
{content: 'Hello'}
|
||||||
|
]}, function (err, count) {
|
||||||
|
should.not.exist(err);
|
||||||
|
count.should.be.equal(1);
|
||||||
|
Post.count({and: [
|
||||||
|
{title: 'My Post1'},
|
||||||
|
{content: 'Hello'}
|
||||||
|
]}, function (err, count) {
|
||||||
|
should.not.exist(err);
|
||||||
|
count.should.be.equal(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// The where object should be parsed by the connector
|
||||||
|
it('should support where for destroyAll', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello'}, function (err, post) {
|
||||||
|
Post.destroyAll({and: [
|
||||||
|
{title: 'My Post1'},
|
||||||
|
{content: 'Hello'}
|
||||||
|
]}, function (err) {
|
||||||
|
should.not.exist(err);
|
||||||
|
Post.count(function (err, count) {
|
||||||
|
should.not.exist(err);
|
||||||
|
count.should.be.equal(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow SQL injection for inq operator', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello', stars: 5},
|
||||||
|
function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello', stars: 20},
|
||||||
|
function (err, post) {
|
||||||
|
Post.find({where: {title: {inq: 'SELECT title from PostWithDefaultId'}}},
|
||||||
|
function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow SQL injection for lt operator', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello', stars: 5},
|
||||||
|
function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello', stars: 20},
|
||||||
|
function (err, post) {
|
||||||
|
Post.find({where: {stars: {lt: 'SELECT title from PostWithDefaultId'}}},
|
||||||
|
function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow SQL injection for nin operator', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello', stars: 5},
|
||||||
|
function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello', stars: 20},
|
||||||
|
function (err, post) {
|
||||||
|
Post.find({where: {title: {nin: 'SELECT title from PostWithDefaultId'}}},
|
||||||
|
function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should not allow SQL injection for inq operator with number column', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello', stars: 5},
|
||||||
|
function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello', stars: 20},
|
||||||
|
function (err, post) {
|
||||||
|
Post.find({where: {stars: {inq: 'SELECT title from PostWithDefaultId'}}},
|
||||||
|
function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow SQL injection for inq operator with array value', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello', stars: 5},
|
||||||
|
function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello', stars: 20},
|
||||||
|
function (err, post) {
|
||||||
|
Post.find({where: {stars: {inq: [5, 'SELECT title from PostWithDefaultId']}}},
|
||||||
|
function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not allow SQL injection for between operator', function (done) {
|
||||||
|
Post.create({title: 'My Post1', content: 'Hello', stars: 5},
|
||||||
|
function (err, post) {
|
||||||
|
Post.create({title: 'My Post2', content: 'Hello', stars: 20},
|
||||||
|
function (err, post) {
|
||||||
|
Post.find({where: {stars: {between: [5, 'SELECT title from PostWithDefaultId']}}},
|
||||||
|
function (err, posts) {
|
||||||
|
should.not.exist(err);
|
||||||
|
posts.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function (done) {
|
||||||
|
Post.destroyAll(function () {
|
||||||
|
PostWithStringId.destroyAll(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue