From 8c68d8ec4f69e9e6eb99bf0dee46e80498e7a561 Mon Sep 17 00:00:00 2001 From: George Eracleous Date: Tue, 24 Nov 2015 12:43:44 +0200 Subject: [PATCH] feat(filter) Adds filter(query) method for store --- README.md | 28 ++++++++++++++++++++++------ lib/model.js | 10 +++++++--- lib/store.js | 34 +++++++++++++++++++++++++--------- package.json | 2 +- test/model.spec.js | 33 ++++++++++++++++++++++++--------- test/store.spec.js | 16 ++++++++++++++++ 6 files changed, 95 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 7690eeb..7faf45c 100644 --- a/README.md +++ b/README.md @@ -53,14 +53,20 @@ store.define('users', userSchema); **3. Implement the required store methods** ```javascript -store.getEntry = function(query) { - // Use query to fetch entry from your db of choice +store._get = function(pk) { + // Use pk to fetch single entry from your db of choice // Returns a Promise // Resolve the promise with the entry as the value if found // Resolve the promise with empty value if not found or reject with a NotFoundError }; -store.setEntry = function(obj) { +store._filter = function(query) { + // Use query to fetch multiple entries matching the query from your db of choice + // Returns a Promise + // Resolve the promise with an array of entries or an empty array if none is mathcing +}; + +store._set = function(obj) { // Use obj to create or update the entry in the db of choice // Returns a Promise // Resolve the promise with an empty value @@ -86,9 +92,7 @@ store.create('users', { ## Get instance ```javascript -store.get('users', { - id: '1234' -}).then(function(instance) { +store.get('users', '1234').then(function(instance) { // Do something with the instance }).catch(NotFoundError, function(err) { //Handle NotFoundError @@ -97,6 +101,18 @@ store.get('users', { }); ``` +## Filter instances + +```javascript +store.filter('users', { + name: 'George' +}).then(function(instances) { + // Do something with the instances +}).catch(function(err) { + // Handle generic error +}); +``` + ## Update instance ```javascript diff --git a/lib/model.js b/lib/model.js index 1039596..694cd0b 100644 --- a/lib/model.js +++ b/lib/model.js @@ -12,7 +12,7 @@ var Model = function(schema) { Model.prototype.get = function(pk, store) { return new Promise(function(resolve, reject) { - store.getEntry(pk).then(function(obj) { + store._get(pk).then(function(obj) { if (!obj) { return reject(new NotFoundError(util.format('Instance with pk %s is not found', pk))); } @@ -23,13 +23,17 @@ Model.prototype.get = function(pk, store) { }); }; +Model.prototype.filter = function(query, store) { + return store._filter(query); +}; + Model.prototype.set = function(obj, operation, store) { obj = obj || {}; var that = this; return new Promise(function(resolve, reject) { that.schema.create(obj).then(function(instance) { this.instance = instance; - return store.setEntry(instance, operation); + return store._set(instance, operation); }).then(function() { resolve(this.instance); }).catch(function(err) { @@ -39,7 +43,7 @@ Model.prototype.set = function(obj, operation, store) { }; Model.prototype.delete = function(pk, store) { - return store.deleteEntry(pk); + return store._delete(pk); }; module.exports = Model; \ No newline at end of file diff --git a/lib/store.js b/lib/store.js index 3acc018..ccee7d5 100644 --- a/lib/store.js +++ b/lib/store.js @@ -41,8 +41,12 @@ Store.prototype.callModelFunction = function(modelName, funcName, args) { }); }; -Store.prototype.get = function(modelName, query) { - return this.callModelFunction(modelName, 'get', [query]); +Store.prototype.get = function(modelName, pk) { + return this.callModelFunction(modelName, 'get', [pk]); +}; + +Store.prototype.filter = function(modelName, query) { + return this.callModelFunction(modelName, 'filter', [query]); }; Store.prototype.create = function(modelName, obj) { @@ -60,13 +64,25 @@ Store.prototype.delete = function(modelName, query) { /** * Handles the logic for getting an entry from the storage * - * @param {String} query - The query object + * @param {String} pk - The object's primary key * @return {Promise} - A Promise * */ -Store.prototype.getEntry = function(query) { - return Promise.reject(new Error('Store.prototype.getEntry(query) is not implemented')); +Store.prototype._get = function(pk) { + return Promise.reject(new Error('Store.prototype._get(pk) is not implemented')); +}; + +/** + * Handles the logic for filtering entries from the storage + * + * @param {String} query - The query object + * @return {Promise} - A Promise. The resolved value should be an array. Return empty array if none is natching the query. + * + */ + +Store.prototype._filter = function(query) { + return Promise.reject(new Error('Store.prototype._filter(query) is not implemented')); }; /** @@ -76,8 +92,8 @@ Store.prototype.getEntry = function(query) { * @return {Promise} - A Promise * */ -Store.prototype.setEntry = function(obj, operation) { - return Promise.reject(new Error('Store.prototype.setEntry(obj, operation) is not implemented')); +Store.prototype._set = function(obj, operation) { + return Promise.reject(new Error('Store.prototype._set(obj, operation) is not implemented')); }; /** @@ -87,8 +103,8 @@ Store.prototype.setEntry = function(obj, operation) { * @return {Promise} - A Promise * */ -Store.prototype.deleteEntry = function(query) { - return Promise.reject(new Error('Store.prototype.deleteEntry(query) is not implemented')); +Store.prototype._delete = function(query) { + return Promise.reject(new Error('Store.prototype._delete(query) is not implemented')); }; module.exports = Store; \ No newline at end of file diff --git a/package.json b/package.json index 1765589..ccdba02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stormer", - "version": "0.5.0", + "version": "0.6.0", "description": "The flexible Node.js ORM", "main": "index.js", "directories": { diff --git a/test/model.spec.js b/test/model.spec.js index 36bebc7..c10489b 100644 --- a/test/model.spec.js +++ b/test/model.spec.js @@ -46,11 +46,11 @@ describe('Model Tests', function() { it('return the instance if it is found', function(done) { var that = this; - sandbox.stub(this.mockStore, 'getEntry').returns(Promise.resolve(this.instance)); + sandbox.stub(this.mockStore, '_get').returns(Promise.resolve(this.instance)); this.model.get('1234', this.mockStore).then(function(instance){ - that.mockStore.getEntry.calledOnce.should.be.true; - that.mockStore.getEntry.calledWith(that.instance.pk).should.be.true; + that.mockStore._get.calledOnce.should.be.true; + that.mockStore._get.calledWith(that.instance.pk).should.be.true; instance.should.equal(that.instance); done(); }); @@ -60,11 +60,11 @@ describe('Model Tests', function() { it('return an error if the instance is not found', function(done) { var that = this; - sandbox.stub(this.mockStore, 'getEntry').returns(Promise.reject(new NotFoundError('Instance with pk 1234 is not found'))); + sandbox.stub(this.mockStore, '_get').returns(Promise.reject(new NotFoundError('Instance with pk 1234 is not found'))); this.model.get('1234', this.mockStore).catch(function(err){ - that.mockStore.getEntry.calledOnce.should.be.true; - that.mockStore.getEntry.calledWith(that.instance.pk).should.be.true; + that.mockStore._get.calledOnce.should.be.true; + that.mockStore._get.calledWith(that.instance.pk).should.be.true; err.message.should.equal('Instance with pk 1234 is not found'); done(); }); @@ -73,6 +73,21 @@ describe('Model Tests', function() { }); + it('Model.prototype.filter(query) should call Store.prototype._filter(query)', function() { + var that = this; + var query = { + fieldA: 1 + }; + sandbox.stub(this.mockStore, '_filter').returns(Promise.resolve([this.instance, this.instance])); + + this.model.filter(query, this.mockStore).then(function(instances){ + that.mockStore._filter.calledOnce.should.be.true; + that.mockStore._filter.calledWith(query).should.be.true; + instances.length.should.equal(2); + done(); + }); + }); + describe('Model.prototype.set() should', function() { it('return an error if schema has failed to create new instance', function(done) { @@ -93,12 +108,12 @@ describe('Model Tests', function() { var that = this; var schema = this.model.schema; - sandbox.stub(this.mockStore, 'setEntry').returns(Promise.resolve(this.instance)); + sandbox.stub(this.mockStore, '_set').returns(Promise.resolve(this.instance)); sandbox.stub(schema, 'create').returns(Promise.resolve(this.instance)); this.model.set(this.instance, 'create', this.mockStore).then(function(createdInstance) { - that.mockStore.setEntry.calledOnce.should.be.true; - that.mockStore.setEntry.calledWith(that.instance).should.be.true; + that.mockStore._set.calledOnce.should.be.true; + that.mockStore._set.calledWith(that.instance).should.be.true; schema.create.calledOnce.should.be.true; schema.create.calledWith(that.instance).should.be.true; createdInstance.should.equal(that.instance); diff --git a/test/store.spec.js b/test/store.spec.js index 724c998..2960ed3 100644 --- a/test/store.spec.js +++ b/test/store.spec.js @@ -41,6 +41,22 @@ describe('Store Tests', function() { }).catch(done); }); + it('Store.prototype.filter() should call Model.prototype.filter()', function(done) { + var store = new Store(); + var query = { + fieldA: 1 + }; + var filterSpy = sandbox.spy(); + + store.define('myModel', {}); + store.models.myModel.filter = filterSpy; + store.filter('myModel', query).then(function() { + filterSpy.called.should.be.true; + filterSpy.calledWith(query, store).should.be.true; + done(); + }).catch(done); + }); + it('Store.prototype.create() should call Model.prototype.set()', function(done) { var store = new Store(); var fakeObj = { pk: '1234'};