diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index bd405f56..8724ac55 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -616,8 +616,8 @@ function applyFilter(filter) { testInEquality({lte: example.between[1]}, value)); } - if (example.like || example.nlike) { - var like = example.like || example.nlike; + if (example.like || example.nlike || example.ilike || example.nilike) { + var like = example.like || example.nlike || example.ilike || example.nilike; if (typeof like === 'string') { like = toRegExp(like); } @@ -628,6 +628,14 @@ function applyFilter(filter) { if (example.nlike) { return !new RegExp(like).test(value); } + + if (example.ilike) { + return !!new RegExp(like, 'i').test(value); + } + + if (example.nilike) { + return !new RegExp(like, 'i').test(value); + } } if (testInEquality(example, value)) { diff --git a/lib/dao.js b/lib/dao.js index 99998f7f..57c9ba7e 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -1400,6 +1400,8 @@ var operators = { neq: '!=', like: 'LIKE', nlike: 'NOT LIKE', + ilike: 'ILIKE', + nilike: 'NOT ILIKE', regexp: 'REGEXP', }; @@ -1626,6 +1628,8 @@ DataAccessObject._coerce = function(where) { break; case 'like': case 'nlike': + case 'ilike': + case 'nilike': if (!(typeof val === 'string' || val instanceof RegExp)) { err = new Error(g.f('The %s property has invalid clause %j', p, where[p])); err.statusCode = 400; @@ -1658,7 +1662,8 @@ DataAccessObject._coerce = function(where) { operator = 'regexp'; } else if (operator === 'regexp' && val instanceof RegExp) { // Do not coerce regex literals/objects - } else if (!((operator === 'like' || operator === 'nlike') && val instanceof RegExp)) { + } else if (!((operator === 'like' || operator === 'nlike' || + operator === 'ilike' || operator === 'nilike') && val instanceof RegExp)) { val = DataType(val); } } @@ -1711,6 +1716,8 @@ DataAccessObject._coerce = function(where) { * - neq: != * - like: LIKE * - nlike: NOT LIKE + * - ilike: ILIKE + * - nilike: NOT ILIKE * - regexp: REGEXP * * You can also use `and` and `or` operations. See [Querying models](http://docs.strongloop.com/display/DOC/Querying+models) for more information. diff --git a/test/basic-querying.test.js b/test/basic-querying.test.js index f73c0d6f..a12b0e8a 100644 --- a/test/basic-querying.test.js +++ b/test/basic-querying.test.js @@ -469,6 +469,62 @@ describe('basic-querying', function() { }); }); + var itWhenIlikeSupported = connectorCapabilities.ilike ? it : it.skip.bind(it); + + itWhenIlikeSupported('should support "like" that is satisfied', function(done) { + User.find({where: {name: {like: 'John'}}}, function(err, users) { + if (err) return done(err); + users.length.should.equal(1); + users[0].name.should.equal('John Lennon'); + done(); + }); + }); + + itWhenIlikeSupported('should support "like" that is not satisfied', function(done) { + User.find({where: {name: {like: 'Bob'}}}, function(err, users) { + if (err) return done(err); + users.length.should.equal(0); + done(); + }); + }); + + var itWhenNilikeSupported = connectorCapabilities.nilike ? it : it.skip.bind(it); + + itWhenNilikeSupported('should support "nlike" that is satisfied', function(done) { + User.find({where: {name: {nlike: 'John'}}}, function(err, users) { + if (err) return done(err); + users.length.should.equal(5); + users[0].name.should.equal('Paul McCartney'); + done(); + }); + }); + + itWhenIlikeSupported('should support "ilike" that is satisfied', function(done) { + User.find({where: {name: {ilike: 'john'}}}, function(err, users) { + if (err) return done(err); + users.length.should.equal(1); + users[0].name.should.equal('John Lennon'); + done(); + }); + }); + + itWhenIlikeSupported('should support "ilike" that is not satisfied', function(done) { + User.find({where: {name: {ilike: 'bob'}}}, function(err, users) { + if (err) return done(err); + users.length.should.equal(0); + done(); + }); + }); + + itWhenNilikeSupported('should support "nilike" that is satisfied', function(done) { + User.find({where: {name: {nilike: 'john'}}}, function(err, users) { + if (err) return done(err); + users.length.should.equal(5); + users[0].name.should.equal('Paul McCartney'); + done(); + }); + }); + it('should only include fields as specified', function(done) { var remaining = 0; diff --git a/test/init.js b/test/init.js index cd2cb5c2..e85c9b3f 100644 --- a/test/init.js +++ b/test/init.js @@ -32,3 +32,7 @@ if (!('getModelBuilder' in global)) { return new ModelBuilder(); }; } + +if (!('connectorCapabilities' in global)) { + global.connectorCapabilities = {}; +}