From 75addaf6e6165e6cfd30d864d5087b95608afa2f Mon Sep 17 00:00:00 2001 From: Andrew Smiley Date: Mon, 23 Oct 2017 18:35:55 -0700 Subject: [PATCH 1/3] Properly support null values used within WHERE conditions. --- src/index.js | 2 +- test/index.test.js | 108 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 89c0d24..bc906e0 100644 --- a/src/index.js +++ b/src/index.js @@ -103,7 +103,7 @@ class Service { return query[method].call(query, column, value); } - return query.where(column, operator, value); + return operator === '=' ? query.where(column, value) : query.where(column, operator, value); }); } diff --git a/test/index.test.js b/test/index.test.js index 9c5d398..7f3f678 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -141,6 +141,114 @@ describe('Feathers Knex Service', () => { app.service('/people').remove(null); }); }); + + it('where conditions support NULL values properly', () => { + app.service('/people').create([{ + name: 'Dave without age', + age: null + }, { + name: 'Dave', + age: 32 + }, { + name: 'Dada', + age: 1 + }]); + + return app.service('/people').find({ + query: { + age: null + } + }).then(data => { + expect(data.length).to.equal(1); + expect(data[0].name).to.be.equal('Dave without age'); + expect(data[0].age).to.be.equal(null); + app.service('/people').remove(null); + }); + }); + + it('where conditions support NOT NULL case properly', () => { + app.service('/people').create([{ + name: 'Dave without age', + age: null + }, { + name: 'Dave', + age: 32 + }, { + name: 'Dada', + age: 1 + }]); + + return app.service('/people').find({ + query: { + age: {$ne: null} + } + }).then(data => { + expect(data.length).to.equal(2); + expect(data[0].name).to.be.equal('Dave'); + expect(data[0].age).to.be.equal(32); + expect(data[1].name).to.be.equal('Dada'); + expect(data[1].age).to.be.equal(1); + app.service('/people').remove(null); + }); + }); + + it('where conditions support NULL values within AND conditions', () => { + app.service('/people').create([{ + name: 'Dave', + age: null + }, { + name: 'Dave', + age: 32 + }, { + name: 'Dada', + age: 1 + }]); + + return app.service('/people').find({ + query: { + age: null, + name: 'Dave' + } + }).then(data => { + expect(data.length).to.equal(1); + expect(data[0].name).to.be.equal('Dave'); + expect(data[0].age).to.be.equal(null); + app.service('/people').remove(null); + }); + }); + + it('where conditions support NULL values within OR conditions', () => { + app.service('/people').create([{ + name: 'Dave', + age: null + }, { + name: 'Dave', + age: 32 + }, { + name: 'Dada', + age: 1 + }]); + + return app.service('/people').find({ + query: { + $or: [ + { + age: null + }, + { + name: 'Dada' + } + ] + } + }).then(data => { + expect(data.length).to.equal(2); + expect(data[0].name).to.be.equal('Dave'); + expect(data[0].age).to.be.equal(null); + expect(data[1].name).to.be.equal('Dada'); + expect(data[1].age).to.be.equal(1); + app.service('/people').remove(null); + }); + }); }); }); From 003be44c746104e8983cf3590d0175866722a276 Mon Sep 17 00:00:00 2001 From: Andrew Smiley Date: Tue, 24 Oct 2017 14:15:14 -0700 Subject: [PATCH 2/3] Made new NULL where condition test not rely on specific result ordering. --- package-lock.json | 172 +++++++++++---------------------------------- test/index.test.js | 10 +-- 2 files changed, 45 insertions(+), 137 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7267104..a2a996e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1410,12 +1410,6 @@ "repeating": "2.0.1" } }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, "doctrine": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", @@ -3505,18 +3499,6 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, "handlebars": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", @@ -3598,6 +3580,12 @@ "sntp": "1.0.9" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, "hoek": { "version": "2.16.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", @@ -4134,12 +4122,6 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -4334,80 +4316,12 @@ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", "dev": true }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, "lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", "dev": true }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._basecreate": "3.0.3", - "lodash._isiterateecall": "3.0.9" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -4508,63 +4422,57 @@ } }, "mocha": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", - "integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", "dev": true, "requires": { "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", - "json3": "3.3.2", - "lodash.create": "3.1.1", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", "mkdirp": "0.5.1", - "supports-color": "3.1.2" + "supports-color": "4.4.0" }, "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - }, "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" } }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true }, "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "2.0.0" } } } diff --git a/test/index.test.js b/test/index.test.js index 7f3f678..e0bdb5c 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -219,7 +219,7 @@ describe('Feathers Knex Service', () => { it('where conditions support NULL values within OR conditions', () => { app.service('/people').create([{ - name: 'Dave', + name: 'Dave without age', age: null }, { name: 'Dave', @@ -242,10 +242,10 @@ describe('Feathers Knex Service', () => { } }).then(data => { expect(data.length).to.equal(2); - expect(data[0].name).to.be.equal('Dave'); - expect(data[0].age).to.be.equal(null); - expect(data[1].name).to.be.equal('Dada'); - expect(data[1].age).to.be.equal(1); + expect(data[0].name).not.be.equal('Dave'); + expect(data[0].age).not.be.equal(32); + expect(data[1].name).not.be.equal('Dave'); + expect(data[1].age).not.be.equal(32); app.service('/people').remove(null); }); }); From 3cdaeb0ea4245820dfa35e2ec0e546945a6b3b6e Mon Sep 17 00:00:00 2001 From: Andrew Smiley Date: Tue, 24 Oct 2017 14:31:09 -0700 Subject: [PATCH 3/3] Make another NULL where condition test not rely on specific result ordering. --- test/index.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/index.test.js b/test/index.test.js index e0bdb5c..96d92c2 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -184,10 +184,10 @@ describe('Feathers Knex Service', () => { } }).then(data => { expect(data.length).to.equal(2); - expect(data[0].name).to.be.equal('Dave'); - expect(data[0].age).to.be.equal(32); - expect(data[1].name).to.be.equal('Dada'); - expect(data[1].age).to.be.equal(1); + expect(data[0].name).to.not.be.equal('Dave without age'); + expect(data[0].age).to.not.be.equal(null); + expect(data[1].name).to.not.be.equal('Dave without age'); + expect(data[1].age).to.not.be.equal(null); app.service('/people').remove(null); }); });