diff --git a/lib/engine.js b/lib/engine.js index 2cbd114..ac29560 100644 --- a/lib/engine.js +++ b/lib/engine.js @@ -82,24 +82,44 @@ Engine.prototype.count = function (criteria){ * @returns {bluebird|exports|module.exports} */ Engine.prototype.update = function (criteria, obj){ - criteria = criteria || {}; + criteria = criteria || {}; var self = this; var data = this._fetch(); return new Promise(function (resolve, reject){ var targets = _.filter(data, criteria); var result = []; _.forEach(targets, function (target){ - var index = _.indexOf(data, target); - // TODO merge - var newObj = obj; - result.push(newObj); - data.splice(index, 1, newObj); + target = _.merge(target, obj); + result.push(target); }); self._flush(data); resolve(result); }); }; +/** + * update (PATCH) an object by its _id (auto-generated) + * @param criteria + * @param obj + * @returns {bluebird|exports|module.exports} + */ +Engine.prototype.updateById = function (_id, obj){ + var self = this; + var data = this._fetch(); + return new Promise(function (resolve, reject){ + var targets = _.filter(data, {_id: _id}); + + if (targets.length > 1) reject(new Error('duplicate _id found')) + if (targets.length === 0) reject(new Error('no object found')) + + var target = targets[0] + target = _.merge(target, obj); + + self._flush(data); + resolve(target); + }); +}; + /** * insert obj * @param obj @@ -129,6 +149,21 @@ Engine.prototype.remove = function (criteria){ }); }; +/** + * removes an object by its _id (auto-generated) + * @param criteria + * @returns {bluebird|exports|module.exports} + */ +Engine.prototype.removeById = function (_id){ + var data = this._fetch(); + var targets = _.remove(data, {_id: _id}); + this._flush(data); + return new Promise(function (resolve, reject){ + if (targets.length > 0) return resolve(targets[0]) + return resolve([]) + }); +}; + /** * fetch data from local file * @private diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ccc5d37 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,138 @@ +{ + "name": "node-localdb", + "version": "0.0.3", + "lockfileVersion": 1, + "dependencies": { + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + }, + "commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", + "dev": true + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "dev": true + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "dev": true, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "dev": true + } + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true + }, + "mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", + "dev": true + }, + "to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", + "dev": true + } + } +} diff --git a/test/removeById.js b/test/removeById.js new file mode 100644 index 0000000..85a7ffc --- /dev/null +++ b/test/removeById.js @@ -0,0 +1,45 @@ +/** + * Created by fpicoitoj on 2017/6/21. + */ + +var path = require('path'); +var assert = require("assert"); +var user = require('..')(path.join(__dirname, 'data/user.json')); +var userId = -1 + +describe('node-localdb', function() { + describe('#removeById()', function () { + before(function() { + // remove all data + user.remove({}).then(function(){}); + }); + after(function() { + // remove all data + user.remove({}).then(function(){}); + }); + + it('should hash method of #removeById()', function(){ + assert.notEqual(undefined, user.removeById); + assert.equal('function', typeof user.removeById); + }); + it('should return object when the there is one user in user document', function (done) { + user.insert({username: 'jf', password: '123'}).then(function(u){ + userId = u._id; // save auto generated _id + + assert.notEqual(undefined, u); + assert.notEqual(undefined, u.username); + assert.notEqual(undefined, u.password); + assert.equal('jf', u.username); + assert.equal('123', u.password); + assert.notEqual(undefined, u._id); + }).then(function(){ + user.removeById(userId); + }).then(function(){ + user.findOne({}).then(function(u){ + assert.equal(undefined, u); + done(); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/update.js b/test/update.js new file mode 100644 index 0000000..8ce95a7 --- /dev/null +++ b/test/update.js @@ -0,0 +1,81 @@ +/** + * Created by fpicoitoj on 2017/6/21. + */ + +var path = require('path'); +var assert = require("assert"); +var user = require('..')(path.join(__dirname, 'data/user.json')); +var _ = require('lodash') + +describe('node-localdb', function() { + describe('#update()', function () { + before(function() { + // remove all data + user.remove({}).then(function(){}); + }); + after(function() { + // remove all data + user.remove({}).then(function(){}); + }); + + it('should hash method of #update()', function(){ + assert.notEqual(undefined, user.update); + assert.equal('function', typeof user.update); + }); + + it('should create two users with same field value', function (done) { + user.insert({username: 'jf', password: '123', active: true}).then(function(u){ + assert.notEqual(undefined, u); + assert.notEqual(undefined, u.username); + assert.notEqual(undefined, u.password); + assert.notEqual(undefined, u.active); + assert.equal('jf', u.username); + assert.equal('123', u.password); + assert.equal(true, u.active); + assert.notEqual(undefined, u._id); + }).then(function(){ + user.insert({username: 'fpj', password: '313', active: true}).then(function(u){ + assert.notEqual(undefined, u); + assert.notEqual(undefined, u.username); + assert.notEqual(undefined, u.password); + assert.notEqual(undefined, u.active); + assert.equal('fpj', u.username); + assert.equal('313', u.password); + assert.equal(true, u.active); + assert.notEqual(undefined, u._id); + }); + }).then(function(){ + user.find({}).then(function(users){ + assert.notEqual(undefined, users); + assert.equal('object', typeof users); + assert.equal(true, users instanceof Array); + assert.equal(2, users.length); + assert.deepEqual(_.pick(users[0], ['username', 'password', 'active']), {username: 'jf', password: '123', active: true}) + assert.deepEqual(_.pick(users[1], ['username', 'password', 'active']), {username: 'fpj', password: '313', active: true}) + done(); + }); + }); + }); + + it('should update two users with same field value and add another field', function (done) { + user.update({active: true}, {active: false, age: 31}).then(function(users){ + assert.notEqual(undefined, users); + assert.equal('object', typeof users); + assert.equal(true, users instanceof Array); + assert.equal(2, users.length); + assert.deepEqual(_.pick(users[0], ['username', 'password', 'active', 'age']), {username: 'jf', password: '123', active: false, age: 31}); + assert.deepEqual(_.pick(users[1], ['username', 'password', 'active', 'age']), {username: 'fpj', password: '313', active: false, age: 31}); + }).then(function(){ + user.find({}).then(function(users){ + assert.notEqual(undefined, users); + assert.equal('object', typeof users); + assert.equal(true, users instanceof Array); + assert.equal(2, users.length); + assert.deepEqual(_.pick(users[0], ['username', 'password', 'active', 'age']), {username: 'jf', password: '123', active: false, age: 31}); + assert.deepEqual(_.pick(users[1], ['username', 'password', 'active', 'age']), {username: 'fpj', password: '313', active: false, age: 31}); + done(); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/updateById.js b/test/updateById.js new file mode 100644 index 0000000..98ebcab --- /dev/null +++ b/test/updateById.js @@ -0,0 +1,72 @@ +/** + * Created by fpicoitoj on 2017/6/21. + */ + +var path = require('path'); +var assert = require("assert"); +var user = require('..')(path.join(__dirname, 'data/user.json')); +var userId = -1 + +describe('node-localdb', function() { + describe('#updateById()', function () { + before(function() { + // remove all data + user.remove({}).then(function(){}); + }); + after(function() { + // remove all data + user.remove({}).then(function(){}); + }); + + it('should hash method of #updateById()', function(){ + assert.notEqual(undefined, user.updateById); + assert.equal('function', typeof user.updateById); + }); + + it('should create a user and update it', function (done) { + user.insert({username: 'jf', password: '123'}).then(function(u){ + userId = u._id; // save auto generated _id + + assert.notEqual(undefined, u); + assert.notEqual(undefined, u.username); + assert.notEqual(undefined, u.password); + assert.equal('jf', u.username); + assert.equal('123', u.password); + assert.notEqual(undefined, u._id); + }).then(function(){ + user.updateById(userId, {username: 'fpj', password: '313', active: true}).then(function(u){ + assert.notEqual(undefined, u); + assert.notEqual(undefined, u.username); + assert.notEqual(undefined, u.password); + assert.notEqual(undefined, u.active); + assert.equal('fpj', u.username); + assert.equal('313', u.password); + assert.equal(true, u.active); + assert.notEqual(undefined, u._id); + }); + }).then(function(){ + user.find({}).then(function(users){ + assert.notEqual(undefined, users); + assert.equal('object', typeof users); + assert.equal(true, users instanceof Array); + assert.equal(1, users.length); + done(); + }); + }); + }); + + it('should not be able to update non-existing user', function (done) { + user.updateById('-1', {username: 'fpj', password: '313'}).then(function(u){ + assert.notEqual(undefined, u); + assert.notEqual(undefined, u.username); + assert.notEqual(undefined, u.password); + assert.equal('fpj', u.username); + assert.equal('313', u.password); + assert.notEqual(undefined, u._id); + }).catch(function(error) { + assert.equal('no object found', error.message) + done(); + }); + }); + }); +}); \ No newline at end of file