Skip to content

Commit

Permalink
Merge pull request #11 from Avocarrot/feature/getSingleAndFilter
Browse files Browse the repository at this point in the history
feat(filter) Adds filter(query) method for store
  • Loading branch information
giorgosera committed Nov 24, 2015
2 parents 9ce9303 + 8c68d8e commit 6b19804
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 28 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
10 changes: 7 additions & 3 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
Expand All @@ -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) {
Expand All @@ -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;
34 changes: 25 additions & 9 deletions lib/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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'));
};

/**
Expand All @@ -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'));
};

/**
Expand All @@ -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;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stormer",
"version": "0.5.0",
"version": "0.6.0",
"description": "The flexible Node.js ORM",
"main": "index.js",
"directories": {
Expand Down
33 changes: 24 additions & 9 deletions test/model.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand All @@ -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();
});
Expand All @@ -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) {
Expand All @@ -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);
Expand Down
16 changes: 16 additions & 0 deletions test/store.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'};
Expand Down

0 comments on commit 6b19804

Please sign in to comment.