From e04f7f7919f34869bd7ac8bd6bafbc8de2288d26 Mon Sep 17 00:00:00 2001 From: Nazar Gargol Date: Thu, 6 Dec 2018 11:07:31 +0100 Subject: [PATCH 1/3] Extended base fixture and same table test suite showing comparison operator support --- test/integration/same-table.test.js | 59 ++++++++++++++++++++++ test/integration/suite1/fixtures/base.json | 8 +++ test/integration/suite1/schema.js | 1 + 3 files changed, 68 insertions(+) diff --git a/test/integration/same-table.test.js b/test/integration/same-table.test.js index 6084191..c3c55e5 100644 --- a/test/integration/same-table.test.js +++ b/test/integration/same-table.test.js @@ -85,4 +85,63 @@ describe('Same Table', function () { }); }); }); + + describe('COMPARISONS $gt / $gte / $lt / $lte', function () { + it('published_at is > 2015-06-04', function () { + const mongoJSON = {published_at: { + $gt: '2015-06-04' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(1); + result.should.matchIds([8]); + }); + }); + + it('published_at is >= 2015-06-04', function () { + const mongoJSON = {published_at: { + $gte: '2015-06-04' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(2); + result.should.matchIds([7, 8]); + }); + }); + + it('published_at is < 2015-06-04', function () { + const mongoJSON = {published_at: { + $lt: '2015-06-04' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(5); + result.should.matchIds([1, 3, 4, 5, 6]); + }); + }); + + it('published_at is <= 2015-06-04', function () { + const mongoJSON = {published_at: { + $lte: '2015-06-04' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(6); + result.should.matchIds([1, 3, 4, 5, 6, 7]); + }); + }); + }); }); + diff --git a/test/integration/suite1/fixtures/base.json b/test/integration/suite1/fixtures/base.json index 5301307..82b0e5e 100644 --- a/test/integration/suite1/fixtures/base.json +++ b/test/integration/suite1/fixtures/base.json @@ -23,6 +23,7 @@ "featured": false, "image": null, "status": "published", + "published_at": "2015-01-01", "author_id": 1 }, { @@ -31,6 +32,7 @@ "featured": false, "image": "myimage.jpg", "status": "draft", + "published_at": null, "author_id": 2 }, { @@ -39,6 +41,7 @@ "featured": true, "image": null, "status": "published", + "published_at": "2015-01-03", "author_id": 1 }, { @@ -47,6 +50,7 @@ "featured": true, "image": null, "status": "published", + "published_at": "2015-06-01", "author_id": 2 }, { @@ -55,6 +59,7 @@ "featured": true, "image": null, "status": "published", + "published_at": "2015-06-02", "author_id": 1 }, { @@ -63,6 +68,7 @@ "featured": true, "image": null, "status": "published", + "published_at": "2015-06-03", "author_id": 1 }, { @@ -71,6 +77,7 @@ "featured": true, "image": null, "status": "published", + "published_at": "2015-06-04", "author_id": 1 }, { @@ -79,6 +86,7 @@ "featured": true, "image": null, "status": "published", + "published_at": "2015-06-05", "author_id": 2 } ], diff --git a/test/integration/suite1/schema.js b/test/integration/suite1/schema.js index 50b092b..4bf9767 100644 --- a/test/integration/suite1/schema.js +++ b/test/integration/suite1/schema.js @@ -15,6 +15,7 @@ module.exports.up = function (knex) { table.boolean('featured').defaultsTo(false); table.string('image', 191).nullable(); table.string('status', 191).nullable(); + table.dateTime('published_at').nullable(); table.integer('author_id').unsigned().references('users.id'); })) .then(() => knex.schema.createTable('tags', (table) => { From a17e0dc3ffb20b5b01af07e01678ad8f00e30ec8 Mon Sep 17 00:00:00 2001 From: Nazar Gargol Date: Thu, 6 Dec 2018 11:55:34 +0100 Subject: [PATCH 2/3] Added comparison operation support in relations --- lib/convertor.js | 8 +-- test/integration/relations.test.js | 60 +++++++++++++++++++++- test/integration/suite1/fixtures/base.json | 12 +++-- test/integration/suite1/schema.js | 1 + 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/lib/convertor.js b/lib/convertor.js index 9ec8e0d..83d78a5 100644 --- a/lib/convertor.js +++ b/lib/convertor.js @@ -252,9 +252,11 @@ class MongoToKnex { if (negateGroup) { statementOp = compOps.$in; } else { - statementOp = isNegationOp(statement.operator) - ? compOps.$nin - : compOps.$in; + if (isNegationOp(statement.operator)) { + statementOp = compOps.$nin; + } else { + statementOp = compOps[statement.operator]; + } } const statementValue = !_.isArray(statement.value) ? [statement.value] : statement.value; diff --git a/test/integration/relations.test.js b/test/integration/relations.test.js index 28d945d..167f4fa 100644 --- a/test/integration/relations.test.js +++ b/test/integration/relations.test.js @@ -112,6 +112,64 @@ describe('Relations', function () { }); }); + describe('COMPARISONS $gt / $gte / $lt / $lte', function () { + it('tags.created_at is > 2015-06-21', function () { + const mongoJSON = {'tags.created_at': { + $gt: '2015-06-21' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(1); + result.should.matchIds([8]); + }); + }); + + it('tags.created_at is >= 2015-06-21', function () { + const mongoJSON = {'tags.created_at': { + $gte: '2015-06-21' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(2); + result.should.matchIds([3, 8]); + }); + }); + + it('tags.created_at is < 2015-01-02', function () { + const mongoJSON = {'tags.created_at': { + $lt: '2015-01-02' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(4); + result.should.matchIds([1, 4, 5, 6]); + }); + }); + + it('tags.created_at is <= 2015-01-02', function () { + const mongoJSON = {'tags.created_at': { + $lte: '2015-01-02' + }}; + + const query = makeQuery(mongoJSON); + + return query + .then((result) => { + result.length.should.eql(5); + result.should.matchIds([1, 2, 4, 5, 6]); + }); + }); + }); + describe('AND $and', function () { it('tags.slug is animal and classic', function () { const mongoJSON = { @@ -248,7 +306,7 @@ describe('Relations', function () { }; const query = makeQuery(mongoJSON); - + console.log(query.toSQL()); return query .select() .then((result) => { diff --git a/test/integration/suite1/fixtures/base.json b/test/integration/suite1/fixtures/base.json index 82b0e5e..32141c2 100644 --- a/test/integration/suite1/fixtures/base.json +++ b/test/integration/suite1/fixtures/base.json @@ -95,25 +95,29 @@ "id": 1, "name": "Classic", "slug": "classic", - "visibility": "public" + "visibility": "public", + "created_at": "2015-01-01" }, { "id": 2, "name": "Animal", "slug": "animal", - "visibility": "public" + "visibility": "public", + "created_at": "2015-01-02" }, { "id": 3, "name": "CGI", "slug": "cgi", - "visibility": "public" + "visibility": "public", + "created_at": "2015-06-21" }, { "id": 4, "name": "#internal", "slug": "hash-internal", - "visibility": "internal" + "visibility": "internal", + "created_at": "2015-06-22" } ] } diff --git a/test/integration/suite1/schema.js b/test/integration/suite1/schema.js index 4bf9767..764dde1 100644 --- a/test/integration/suite1/schema.js +++ b/test/integration/suite1/schema.js @@ -23,6 +23,7 @@ module.exports.up = function (knex) { table.string('name', 191); table.string('slug', 191); table.string('visibility', 191).defaultTo('public'); + table.dateTime('created_at'); })) .then(() => knex.schema.createTable('posts_tags', (table) => { table.increments('id').primary(); From 9254612f0be670ba3d31e54d447a2b66a6124029 Mon Sep 17 00:00:00 2001 From: Nazar Gargol Date: Thu, 6 Dec 2018 14:45:31 +0100 Subject: [PATCH 3/3] Fixed statement value normalization for group operations --- lib/convertor.js | 9 ++++++++- test/integration/relations.test.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/convertor.js b/lib/convertor.js index 83d78a5..67d5ba9 100644 --- a/lib/convertor.js +++ b/lib/convertor.js @@ -22,6 +22,7 @@ const isOp = key => key.charAt(0) === '$'; const isLogicOp = key => isOp(key) && _.includes(logicOps, key); const isCompOp = key => isOp(key) && _.includes(_.keys(compOps), key); const isNegationOp = key => isOp(key) && _.includes(['$ne', '$nin'], key); +const isStatementGroupOp = key => _.includes([compOps.$in, compOps.$nin], key); class MongoToKnex { constructor(options = {}, config = {}) { @@ -258,7 +259,13 @@ class MongoToKnex { statementOp = compOps[statement.operator]; } } - const statementValue = !_.isArray(statement.value) ? [statement.value] : statement.value; + + let statementValue = statement.value; + + // CASE: need to normalize value to array when it's a group operation + if (isStatementGroupOp(statementOp)) { + statementValue = !_.isArray(statement.value) ? [statement.value] : statement.value; + } innerQB[statement.whereType](statementColumn, statementOp, statementValue); }); diff --git a/test/integration/relations.test.js b/test/integration/relations.test.js index 167f4fa..322fc6e 100644 --- a/test/integration/relations.test.js +++ b/test/integration/relations.test.js @@ -306,7 +306,7 @@ describe('Relations', function () { }; const query = makeQuery(mongoJSON); - console.log(query.toSQL()); + return query .select() .then((result) => {