Просмотр исходного кода

chore: converts date string to date instance in mongodb query

e22m4u 2 лет назад
Родитель
Сommit
0818ca93e9
3 измененных файлов с 187 добавлено и 10 удалено
  1. 44 9
      src/mongodb-adapter.js
  2. 142 0
      src/mongodb-adapter.spec.js
  3. 1 1
      src/utils/is-iso-date.js

+ 44 - 9
src/mongodb-adapter.js

@@ -160,6 +160,20 @@ export class MongodbAdapter extends Adapter {
     return value;
   }
 
+  /**
+   * Coerce date.
+   *
+   * @param value
+   * @returns {Date|*}
+   * @private
+   */
+  _coerceDate(value) {
+    if (value == null) return value;
+    if (value instanceof Date) return value;
+    if (isIsoDate(value)) return new Date(value);
+    return value;
+  }
+
   /**
    * To database.
    *
@@ -401,6 +415,7 @@ export class MongodbAdapter extends Adapter {
       // string
       if (typeof cond === 'string') {
         query[key] = this._coerceId(cond);
+        query[key] = this._coerceDate(query[key]);
         return;
       }
       // ObjectId
@@ -413,27 +428,35 @@ export class MongodbAdapter extends Adapter {
         const opConds = [];
         // eq
         if ('eq' in cond) {
-          opConds.push({$eq: this._coerceId(cond.eq)});
+          let eq = this._coerceId(cond.eq);
+          eq = this._coerceDate(eq);
+          opConds.push({$eq: eq});
         }
         // neq
         if ('neq' in cond) {
-          opConds.push({$ne: this._coerceId(cond.neq)});
+          let neq = this._coerceId(cond.neq);
+          neq = this._coerceDate(neq);
+          opConds.push({$ne: neq});
         }
         // gt
         if ('gt' in cond) {
-          opConds.push({$gt: cond.gt});
+          const gt = this._coerceDate(cond.gt);
+          opConds.push({$gt: gt});
         }
         // lt
         if ('lt' in cond) {
-          opConds.push({$lt: cond.lt});
+          const lt = this._coerceDate(cond.lt);
+          opConds.push({$lt: lt});
         }
         // gte
         if ('gte' in cond) {
-          opConds.push({$gte: cond.gte});
+          const gte = this._coerceDate(cond.gte);
+          opConds.push({$gte: gte});
         }
         // lte
         if ('lte' in cond) {
-          opConds.push({$lte: cond.lte});
+          const lte = this._coerceDate(cond.lte);
+          opConds.push({$lte: lte});
         }
         // inq
         if ('inq' in cond) {
@@ -443,7 +466,12 @@ export class MongodbAdapter extends Adapter {
               'an Array of possible values',
               cond.inq,
             );
-          opConds.push({$in: cond.inq.map(v => this._coerceId(v))});
+          const inq = cond.inq.map(v => {
+            v = this._coerceId(v);
+            v = this._coerceDate(v);
+            return v;
+          });
+          opConds.push({$in: inq});
         }
         // nin
         if ('nin' in cond) {
@@ -453,7 +481,12 @@ export class MongodbAdapter extends Adapter {
               'an Array of possible values',
               cond,
             );
-          opConds.push({$nin: cond.nin.map(v => this._coerceId(v))});
+          const nin = cond.nin.map(v => {
+            v = this._coerceId(v);
+            v = this._coerceDate(v);
+            return v;
+          });
+          opConds.push({$nin: nin});
         }
         // between
         if ('between' in cond) {
@@ -463,7 +496,9 @@ export class MongodbAdapter extends Adapter {
               'an Array of 2 elements',
               cond.between,
             );
-          opConds.push({$gte: cond.between[0], $lte: cond.between[1]});
+          const gte = this._coerceDate(cond.between[0]);
+          const lte = this._coerceDate(cond.between[1]);
+          opConds.push({$gte: gte, $lte: lte});
         }
         // exists
         if ('exists' in cond) {

+ 142 - 0
src/mongodb-adapter.spec.js

@@ -812,6 +812,148 @@ describe('MongodbAdapter', function () {
       expect(res[0]).to.be.eql(oid);
     });
 
+    it('converts property value to an instance of Date', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: isoDate};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const res = A._buildQuery('model', input);
+      expect(res.foo).to.be.instanceof(Date);
+      expect(res.foo).to.be.eql(date);
+    });
+
+    it('the "eq" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {eq: isoDate}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$eq: res},
+      } = A._buildQuery('model', input);
+      expect(res).to.be.instanceOf(Date);
+      expect(res).to.be.eql(date);
+    });
+
+    it('the "neq" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {neq: isoDate}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$ne: res},
+      } = A._buildQuery('model', input);
+      expect(res).to.be.instanceOf(Date);
+      expect(res).to.be.eql(date);
+    });
+
+    it('the "gt" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {gt: isoDate}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$gt: res},
+      } = A._buildQuery('model', input);
+      expect(res).to.be.instanceOf(Date);
+      expect(res).to.be.eql(date);
+    });
+
+    it('the "lt" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {lt: isoDate}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$lt: res},
+      } = A._buildQuery('model', input);
+      expect(res).to.be.instanceOf(Date);
+      expect(res).to.be.eql(date);
+    });
+
+    it('the "gte" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {gte: isoDate}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$gte: res},
+      } = A._buildQuery('model', input);
+      expect(res).to.be.instanceOf(Date);
+      expect(res).to.be.eql(date);
+    });
+
+    it('the "lte" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {lte: isoDate}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$lte: res},
+      } = A._buildQuery('model', input);
+      expect(res).to.be.instanceOf(Date);
+      expect(res).to.be.eql(date);
+    });
+
+    it('the "inq" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {inq: [isoDate]}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$in: res},
+      } = A._buildQuery('model', input);
+      expect(res[0]).to.be.instanceOf(Date);
+      expect(res[0]).to.be.eql(date);
+    });
+
+    it('the "nin" operator converts Date string to an instance', async function () {
+      const date = new Date();
+      const isoDate = date.toISOString();
+      const input = {foo: {nin: [isoDate]}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$nin: res},
+      } = A._buildQuery('model', input);
+      expect(res[0]).to.be.instanceOf(Date);
+      expect(res[0]).to.be.eql(date);
+    });
+
+    it('the "between" operator converts Date string to an instance', async function () {
+      const date1 = new Date();
+      const date2 = new Date();
+      const isoDate1 = date1.toISOString();
+      const isoDate2 = date2.toISOString();
+      const input = {foo: {between: [isoDate1, isoDate2]}};
+      const schema = createSchema();
+      schema.defineModel({name: 'model', datasource: 'mongodb'});
+      const A = await schema.getService(AdapterRegistry).getAdapter('mongodb');
+      const {
+        foo: {$gte: res1, $lte: res2},
+      } = A._buildQuery('model', input);
+      expect(res1).to.be.instanceOf(Date);
+      expect(res1).to.be.eql(date1);
+      expect(res2).to.be.instanceOf(Date);
+      expect(res2).to.be.eql(date2);
+    });
+
     it('combines the given operators by the "and" clause', async function () {
       const input = {
         foo: {

+ 1 - 1
src/utils/is-iso-date.js

@@ -1,5 +1,5 @@
 /**
- * Is iso date string.
+ * Is iso date.
  *
  * @param value
  * @return {boolean}