-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
0 parents
commit cbbfb99
Showing
6 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
test: | ||
@./node_modules/.bin/mocha \ | ||
--reporter spec | ||
|
||
.PHONY: test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
# mongo-query | ||
|
||
Get object diff as a MongoDB update query. | ||
|
||
Useful for reducing the size of your queries. | ||
Uses (cloudup/mongo-eql)[https://github.com/cloudup/mongo-eql] to compare values and | ||
and (cloudup/mongo-minify)[https://github.com/cloudup/mongo-minify] to optionally filter | ||
out disallowed operations. | ||
|
||
## Installation | ||
|
||
$ npm install mongo-update | ||
|
||
## Example | ||
|
||
```js | ||
var update = require('mongo-update'); | ||
var query = update({ a: 'hello' }, { b: 'world' }); | ||
// => { $set: { b: 'hello' }, $unset: { a: 1 }} | ||
``` | ||
|
||
Or with a filter (see (cloudup/mongo-minify)[https://github.com/cloudup/mongo-minify] for more examples) | ||
```js | ||
var query = update({ a: 1, b: 2 }, { a: 2, b: 3 }, { a: 1 }); | ||
// => { $set: { a: 2 }} | ||
``` | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
var minify = require('mongo-minify'); | ||
var is = require('component-type'); | ||
var eql = require('mongo-eql'); | ||
|
||
/** | ||
* Get object diff as a MongoDB update query | ||
* | ||
* @param {Object} a | ||
* @param {Object} b | ||
* @param {Object} [filter] | ||
* @return {Object} | ||
* @api public | ||
*/ | ||
|
||
module.exports = function (a, b, filter) { | ||
var ret = {}; | ||
filter = filter || {}; | ||
diff(a, b, ret); | ||
return minify(ret, filter); | ||
} | ||
|
||
/** | ||
* Traverse both objects and put ops on the `query` object | ||
*/ | ||
|
||
function diff (a, b, query, prefix) { | ||
// find removed keys | ||
for (var key in a) { | ||
var path = join(key, prefix); | ||
if (b[key] == null) unset(query, path); | ||
} | ||
|
||
// find changed keys | ||
for (var key in b) { | ||
var path = join(key, prefix); | ||
|
||
// removed | ||
if (b[key] == null) continue; | ||
|
||
// no change | ||
if (eql(a[key], b[key])) continue; | ||
|
||
// new type | ||
if (is(a[key]) != is(b[key])) { | ||
set(query, path, b[key]); | ||
continue; | ||
} | ||
|
||
// object | ||
if (is(a[key]) == 'object') { | ||
diff(a[key], b[key], query, path); | ||
continue; | ||
} | ||
|
||
// default | ||
set(query, path, b[key]); | ||
} | ||
} | ||
|
||
/** | ||
* $set `field` to `val` | ||
*/ | ||
|
||
function set (query, field, val) { | ||
query['$set'] = query['$set'] || {}; | ||
query['$set'][field] = val; | ||
} | ||
|
||
/** | ||
* $unset `field` | ||
*/ | ||
|
||
function unset (query, field) { | ||
query['$unset'] = query['$unset'] || {}; | ||
query['$unset'][field] = 1; | ||
}; | ||
|
||
/** | ||
* Join `key` with `prefix` using dot-notation | ||
*/ | ||
|
||
function join (key, prefix) { | ||
return prefix | ||
? prefix + '.' + key | ||
: key; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "mongo-update", | ||
"version": "0.0.1", | ||
"description": "Get object diff as a MongoDB update query", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "make test" | ||
}, | ||
"license": "MIT", | ||
"dependencies": { | ||
"component-type": "~1.0.0", | ||
"mongo-eql": "~0.1.0", | ||
"mongo-minify": "~0.1.1" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.17.1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/eivindfjeldstad/mongo-update.git" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
var assert = require('assert'); | ||
var diff = require('./'); | ||
|
||
describe('query()', function () { | ||
it('should $set modified keys', function () { | ||
var query = diff({ a: 1 }, { a: 2 }); | ||
assert(query.$set.a == 2); | ||
assert(!('$unset' in query)); | ||
}); | ||
|
||
it('should $unset null-ish keys', function () { | ||
var query = diff({ a: 1 }, { a: null }); | ||
assert(query.$unset.a == 1); | ||
assert(!('$set' in query)); | ||
}); | ||
|
||
it('should work with nested keys', function () { | ||
var query = diff({ a: { b: 1, c: 2 }}, { a: { b: 2 }}); | ||
assert(query.$set['a.b'] == 2); | ||
assert(query.$unset['a.c'] == 1); | ||
}); | ||
|
||
describe('when given a filter', function () { | ||
it('should minify the query', function () { | ||
var query = diff({ a: 1, b: 2 }, { a: 2, b: 3 }, { a: 1 }); | ||
assert(query.$set.a == 2); | ||
assert(!('b' in query.$set)); | ||
}); | ||
|
||
it('should work with nested keys', function () { | ||
var query = diff({ a: { b: 1, c: 2 }}, { a: { b: 2 }}, { 'a.b': 1 }); | ||
assert(query.$set['a.b'] == 2); | ||
assert(!('$unset' in query)); | ||
}); | ||
}); | ||
}) |