diff --git a/README.md b/README.md index 43b204f..08b4e7b 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Documentation * [.getMany(keys, callback)](#module_storage.getMany) * [.getAll(callback)](#module_storage.getAll) * [.set(key, json, callback)](#module_storage.set) + * [.setMany(keys, callback)](#module_storage.setMany) * [.has(key, callback)](#module_storage.has) * [.keys(callback)](#module_storage.keys) * [.remove(key, callback)](#module_storage.remove) @@ -141,6 +142,37 @@ storage.set('foobar', { foo: 'bar' }, function(error) { if (error) throw error; }); ``` + + +### storage.setMany(keys, callback) +**Kind**: static method of [storage](#module_storage) +**Summary**: Write multiple sets of user data +**Access:** public + +| Param | Type | Description | +| --- | --- | --- | +| keys | Object | json object | +| callback | function | callback (error, finished) | + +**Example** +```js +const storage = require('electron-json-storage'); + +storage.setMany({ foo: { bar: 'baz' }, baz: { bar: 'foo' } }, function(error, finished) { + if (error) { + console.log('Error saving ' + error.key); + throw error.error; + } + if (finished) console.log('finished'); +}); +``` +The `error` property of the callback is an object with two properties: + - `error` (object), the error object + - `key` (string), the key that failed to save that failed to save). + +This function will set each key one by one, for each error that occurs the callback will be invoked. Therefore the `finished` +parameter of the callback indicates if the function has finished saving all the data. + ### storage.has(key, callback) diff --git a/lib/storage.js b/lib/storage.js index f726a49..1a17e7d 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -208,6 +208,60 @@ exports.set = function(key, json, callback) { ], callback); }; +/** + * @summary Write multiple sets of user data + * @function + * @public + * + * @param {Object} keys + * @param {Function} callback - callback (error, done) + * + * @example + * const storage = require('electron-json-storage'); + * + * storage.setMany({ foo: 'bar', bar: 'foo' }, function(error, done) { + * if (error) { + * console.log('Error saving ' + error.key); + * throw error.error; + * } + * if (finished) console.log('finished'); + * }); + */ +exports.setMany = function(keys, callback) { + if (!keys || keys.constructor !== Object) { + callback(new Error('Invalid keys'), true); + return; + } + + const entries = _.map(keys, function(value, key) { + return { key: key, value: value }; + }); + + function process() { + const entry = entries.shift(); + const key = entry.key; + const value = entry.value; + + exports.set(key, value, function(error) { + if (error) { + callback({ error: error, key: key }, entries.length === 0); + } + + if (entries.length > 0) { + process(); + } else if (!error) { + callback(null, true); + } + }); + } + + if (entries.length > 0) { + process(); + } else { + callback(null, true); + } +}; + /** * @summary Check if a key exists * @function diff --git a/tests/storage.spec.js b/tests/storage.spec.js index 9af301f..5181c52 100644 --- a/tests/storage.spec.js +++ b/tests/storage.spec.js @@ -476,7 +476,46 @@ describe('Electron JSON Storage', function() { }); }); + + describe('.setMany()', function() { + it('should yield an error if no key', function(done) { + storage.setMany(null, function(error, finished) { + m.chai.expect(error).to.be.an.instanceof(Error); + m.chai.expect(error.message).to.equal('Invalid keys'); + done(); + }); + }); + + it('should be able to store multiple valid JSON objects', function(done) { + async.waterfall([ + function(callback) { + storage.setMany({ + foo: { bar: 'baz' }, + baz: { bar: 'foo' } + }, callback); + }, + function(finished, callback) { + m.chai.expect(finished).to.be.true; + storage.getMany(['foo', 'baz'], callback); + } + ], function(error, data) { + m.chai.expect(data.foo).to.deep.equal({ bar: 'baz' }); + m.chai.expect(data.baz).to.deep.equal({ bar: 'foo' }); + done(); + }); + }); + + it('should ignore keys that are empty objects', function(done) { + storage.setMany({}, function(error, finished) { + m.chai.expect(error).to.not.exist; + m.chai.expect(finished).to.be.true; + done(); + }); + }) + + }); + describe('.has()', function() { it('should yield an error if no key', function(done) {