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

Commit 64e9b7ac by Sushant

fix(query-generator): regexp operator

1 parent 7b7b23d5
...@@ -2355,10 +2355,6 @@ class QueryGenerator { ...@@ -2355,10 +2355,6 @@ class QueryGenerator {
} }
} }
if (comparator.indexOf(this.OperatorMap[Op.regexp]) !== -1) {
return this._joinKeyValue(key, `'${value}'`, comparator, options.prefix);
}
if (value === null && comparator === this.OperatorMap[Op.eq]) { if (value === null && comparator === this.OperatorMap[Op.eq]) {
return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.is], options.prefix); return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.is], options.prefix);
} else if (value === null && comparator === this.OperatorMap[Op.ne]) { } else if (value === null && comparator === this.OperatorMap[Op.ne]) {
......
'use strict'; 'use strict';
const chai = require('chai'), const chai = require('chai'),
Sequelize = require('../../../../index'), Sequelize = require('../../index'),
Op = Sequelize.Op, Op = Sequelize.Op,
Promise = Sequelize.Promise, Promise = Sequelize.Promise,
expect = chai.expect, expect = chai.expect,
Support = require(__dirname + '/../../support'), Support = require(__dirname + '/../support'),
DataTypes = require(__dirname + '/../../../../lib/data-types'), DataTypes = require(__dirname + '/../../lib/data-types'),
dialect = Support.getTestDialect(); dialect = Support.getTestDialect();
describe(Support.getTestDialectTeaser('Model'), () => { describe(Support.getTestDialectTeaser('Operators'), () => {
describe('attributes', () => {
describe('operators', () => {
describe('REGEXP', () => { describe('REGEXP', () => {
beforeEach(function() { beforeEach(function() {
const queryInterface = this.sequelize.getQueryInterface();
this.User = this.sequelize.define('user', { this.User = this.sequelize.define('user', {
id: { id: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
...@@ -34,7 +30,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -34,7 +30,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}); });
return Promise.all([ return Promise.all([
queryInterface.createTable('users', { this.sequelize.getQueryInterface().createTable('users', {
userId: { userId: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
...@@ -49,13 +45,12 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -49,13 +45,12 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}); });
if (dialect === 'mysql' || dialect === 'postgres') { if (dialect === 'mysql' || dialect === 'postgres') {
describe('case sensitive', () => {
it('should work with a regexp where', function() { it('should work with a regexp where', function() {
const self = this;
return this.User.create({ return this.User.create({
name: 'Foobar' name: 'Foobar'
}).then(() => { }).then(() => {
return self.User.find({ return this.User.find({
where: { where: {
name: { name: {
[Op.regexp]: '^Foo' [Op.regexp]: '^Foo'
...@@ -68,12 +63,10 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -68,12 +63,10 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}); });
it('should work with a not regexp where', function() { it('should work with a not regexp where', function() {
const self = this;
return this.User.create({ return this.User.create({
name: 'Foobar' name: 'Foobar'
}).then(() => { }).then(() => {
return self.User.find({ return this.User.find({
where: { where: {
name: { name: {
[Op.notRegexp]: '^Foo' [Op.notRegexp]: '^Foo'
...@@ -85,7 +78,38 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -85,7 +78,38 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}); });
}); });
it('should properly escape regular expressions', function() {
return this.User.bulkCreate([{
name: 'John'
}, {
name: 'Bob'
}]).then(() => {
return this.User.findAll({
where: {
name: {
[Op.notRegexp]: "Bob'; drop table users --"
}
}
});
}).then(() => {
return this.User.findAll({
where: {
name: {
[Op.regexp]: "Bob'; drop table users --"
}
}
});
}).then(() => {
return this.User.findAll();
}).then(users => {
expect(users).length(2);
});
});
});
}
if (dialect === 'postgres') { if (dialect === 'postgres') {
describe('case insensitive', () => {
it('should work with a case-insensitive regexp where', function() { it('should work with a case-insensitive regexp where', function() {
const self = this; const self = this;
...@@ -121,9 +145,35 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -121,9 +145,35 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(user).to.not.be.ok; expect(user).to.not.be.ok;
}); });
}); });
it('should properly escape regular expressions', function() {
return this.User.bulkCreate([{
name: 'John'
}, {
name: 'Bob'
}]).then(() => {
return this.User.findAll({
where: {
name: {
[Op.iRegexp]: "Bob'; drop table users --"
} }
} }
}); });
}).then(() => {
return this.User.findAll({
where: {
name: {
[Op.notIRegexp]: "Bob'; drop table users --"
}
}
}); });
}).then(() => {
return this.User.findAll();
}).then(users => {
expect(users).length(2);
});
});
});
}
}); });
}); });
...@@ -1014,7 +1014,7 @@ suite(Support.getTestDialectTeaser('SQL'), () => { ...@@ -1014,7 +1014,7 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
testsql('newline', { testsql('newline', {
[Op.regexp]: '^new\nline$' [Op.regexp]: '^new\nline$'
}, { }, {
mysql: "`newline` REGEXP '^new\nline$'", mysql: "`newline` REGEXP '^new\\nline$'",
postgres: '"newline" ~ \'^new\nline$\'' postgres: '"newline" ~ \'^new\nline$\''
}); });
}); });
...@@ -1032,7 +1032,7 @@ suite(Support.getTestDialectTeaser('SQL'), () => { ...@@ -1032,7 +1032,7 @@ suite(Support.getTestDialectTeaser('SQL'), () => {
testsql('newline', { testsql('newline', {
[Op.notRegexp]: '^new\nline$' [Op.notRegexp]: '^new\nline$'
}, { }, {
mysql: "`newline` NOT REGEXP '^new\nline$'", mysql: "`newline` NOT REGEXP '^new\\nline$'",
postgres: '"newline" !~ \'^new\nline$\'' postgres: '"newline" !~ \'^new\nline$\''
}); });
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!