Skip to content

Commit

Permalink
Allow append to existing object; allow user-provided read/write funct…
Browse files Browse the repository at this point in the history
…ions

The following changes are included here:

1. New Method: append

A new `append` method has been added. Whereas the traditional calls such as
```
store.set('a', { b : c });
store.set('a', { d : e });
```
allows the second call to overwrite the entire value of 'a', yielding
```
{
  d : e
}
```

this sequence:
```
store.append('a', { b : c });
store.append('a', { d : e });
```
ratains prior values, and thus yields:
```
{
  b : c,
  d : e
}
```

2. The means of reading (and parsing), and writing to files can now be
overridden by the caller, in the `options` argument. This allows adding
additional error handling, in the simple case, or reading and writing entirely
different types of files in the more sophisticated case. An example is
provided in `examples/ini.js` that shows the store reading and writing an INI
file, while allowing it to be manipulated programmatically in the standard
data-store fashion.
  • Loading branch information
derrell committed Oct 3, 2019
1 parent 037d1b7 commit d1688f8
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
51 changes: 49 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,20 @@ class Store {

const opts = { debounce: 0, indent: 2, home: os.homedir(), name, ...options };

this.name = opts.name || (opts.path ? utils.stem(opts.path) : 'data-store')
this.name = opts.name || (opts.path ? utils.stem(opts.path) : 'data-store');
this.path = opts.path || path.join(opts.home, `${this.name}.json`);
this.indent = opts.indent;
this.debounce = opts.debounce;
this.defaults = defaults || opts.default;
this.timeouts = {};

// Allow override of read and write methods
if (typeof options.readParseFile == "function") {
this.readParseFile = options.readParseFile;
}
if (typeof options.writeFile == "function") {
this.writeFile = options.writeFile;
}
}

/**
Expand Down Expand Up @@ -91,6 +99,29 @@ class Store {
return this;
}

/**
* Assign `value` to `key` while retaining prior members of `value` if
* `value` is a map.
*
* ```js
* store.set('a', { b: c });
* //=> {a: { b: c }}
*
* store.append('a', { d: e });
* //=> {a: { b: c, d: e }}
* ```
*
* @name .append
* @param {String} `key`
* @param {any} `val` The value to append to `key`. Must be a valid JSON type: String, Number, Array or Object.
* @return {Object} `Store` for chaining
* @api public
*/

append(key, val) {
return this.set(key, Object.assign(this.get(key) || {}, val));
}

/**
* Add the given `value` to the array at `key`. Creates a new array if one
* doesn't exist, and only adds unique values to the array.
Expand Down Expand Up @@ -323,14 +354,30 @@ class Store {
utils.tryUnlink(this.path);
}

/**
* Read and parse the data from the file system store. This method should
* probably not be called directly. Unless you are familiar with the inner
* workings of the code it's recommended that you use .load() instead.
*
* ```js
* data = store.readPraseFile();
* ```
* @name .readParseFile
* @return {undefined}
*/

readParseFile() {
return JSON.parsefs.readFileSync(this.path);
}

/**
* Load the store.
* @return {Object}
*/

load() {
try {
return (this[kData] = JSON.parse(fs.readFileSync(this.path)));
return (this[kData] = this.readParseFile());
} catch (err) {
if (err.code === 'EACCES') {
err.message += '\ndata-store does not have permission to load this file\n';
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"devDependencies": {
"delete": "^1.1.0",
"gulp-format-md": "^2.0.0",
"mocha": "^6.2.0"
"mocha": "^6.2.1"
},
"keywords": [
"app",
Expand Down
20 changes: 20 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,26 @@ describe('store', () => {
});
});

describe('append', () => {
it('should allow adding to an existing map', () => {
store.append('a', { b : 'c' });
store.append('d', { e : 'f' });
store.set('g', { h : 'i' });
assert.equal(store.data.a.b, 'c');
assert.equal(store.data.d.e, 'f');
assert.equal(store.data.g.h, 'i');
});
it('should allow overriding an existing key in an existing map', () => {
store.append('a', { b : 'c' });
store.append('d', { e : 'f' });
store.set('g', { h : 'i' });
store.append('d', { e : 'j' });
assert.equal(store.data.a.b, 'c');
assert.equal(store.data.d.e, 'j');
assert.equal(store.data.g.h, 'i');
});
});

describe('union', () => {
it('should add and arrayify a new value', () => {
store.union('one', 'two');
Expand Down

0 comments on commit d1688f8

Please sign in to comment.