Enable upserts and bump version

pull/2/head
Louis Chatriot 12 years ago
parent d8119ad923
commit 7096cdb144
  1. 58
      lib/datastore.js
  2. 2
      package.json
  3. 25
      test/db.test.js

@ -2,6 +2,7 @@
* The datastore itself * The datastore itself
* TODO * TODO
* Queue operations * Queue operations
* Enable upserts
* Update and removes should only modify the corresponding part of the database * Update and removes should only modify the corresponding part of the database
*/ */
@ -9,6 +10,7 @@ var fs = require('fs')
, path = require('path') , path = require('path')
, customUtils = require('./customUtils') , customUtils = require('./customUtils')
, model = require('./model') , model = require('./model')
, async = require('async')
; ;
@ -107,11 +109,6 @@ Datastore.match = function (obj, query) {
//, queryKeys = Object.keys(query) //, queryKeys = Object.keys(query)
, i, k; , i, k;
//for (i = 0; i < queryKeys.length; i += 1) {
//k = queryKeys[i]
//if (obj[k] !== query[k]) { match = false; }
//}
Object.keys(query).forEach(function (k) { Object.keys(query).forEach(function (k) {
if (obj[k] !== query[k]) { match = false; } if (obj[k] !== query[k]) { match = false; }
}); });
@ -206,33 +203,54 @@ Datastore.modify = function (obj, updateQuery) {
* @param {Object} newDoc Will replace the former docs * @param {Object} newDoc Will replace the former docs
* @param {Object} options Optional options * @param {Object} options Optional options
* options.multi If true, can update multiple documents (defaults to false) * options.multi If true, can update multiple documents (defaults to false)
* @param {Function} cb Optional callback, signature: err, numReplaced * options.upsert If true, document is inserted if the query doesn't match anything
* @param {Function} cb Optional callback, signature: err, numReplaced, upsert (set to true if the update was in fact an upsert)
*/ */
Datastore.prototype.update = function (query, newDoc, options, cb) { Datastore.prototype.update = function (query, newDoc, options, cb) {
var callback var callback
, self = this , self = this
, numReplaced = 0 , numReplaced = 0
, multi , multi, upsert
, newData = []; , newData = [];
if (typeof options === 'function') { cb = options; options = {}; } if (typeof options === 'function') { cb = options; options = {}; }
callback = cb || function () {}; callback = cb || function () {};
multi = options.multi !== undefined ? options.multi : false; multi = options.multi !== undefined ? options.multi : false;
upsert = options.upsert !== undefined ? options.upsert : false;
self.data.forEach(function (d) { async.waterfall([
if (Datastore.match(d, query) && (multi || numReplaced === 0)) { function (cb) { // If upsert option is set, check whether we need to insert the doc
numReplaced += 1; if (!upsert) { return cb(); }
newData.push(Datastore.modify(d, newDoc));
} else {
newData.push(d);
}
});
self.persistWholeDatabase(newData, function (err) { self.findOne(query, function (err, doc) {
if (err) { return callback(err); } if (err) { return callback(err); }
self.data = newData; if (doc) {
return callback(null, numReplaced); return cb();
}); } else {
return self.insert(newDoc, function (err) {
if (err) { return callback(err); }
return callback(null, 1, true);
});
}
});
}
, function () { // Perform the update
self.data.forEach(function (d) {
if (Datastore.match(d, query) && (multi || numReplaced === 0)) {
numReplaced += 1;
newData.push(Datastore.modify(d, newDoc));
} else {
newData.push(d);
}
});
self.persistWholeDatabase(newData, function (err) {
if (err) { return callback(err); }
self.data = newData;
return callback(null, numReplaced);
});
}
]);
}; };

@ -1,6 +1,6 @@
{ {
"name": "nedb", "name": "nedb",
"version": "0.0.3", "version": "0.0.4",
"author": { "author": {
"name": "tldr.io", "name": "tldr.io",
"email": "hello@tldr.io" "email": "hello@tldr.io"

@ -355,6 +355,31 @@ describe('Database', function () {
], done); ], done);
}); });
it('Can perform upserts if needed', function (done) {
d.update({ impossible: 'db is empty anyway' }, { newDoc: true }, {}, function (err, nr, upsert) {
assert.isNull(err);
nr.should.equal(0);
assert.isUndefined(upsert);
d.find({}, function (err, docs) {
docs.length.should.equal(0); // Default option for upsert is false
d.update({ impossible: 'db is empty anyway' }, { newDoc: true }, { upsert: true }, function (err, nr, upsert) {
assert.isNull(err);
nr.should.equal(1);
upsert.should.equal(true);
d.find({}, function (err, docs) {
docs.length.should.equal(1); // Default option for upsert is false
docs[0].newDoc.should.equal(true);
done();
});
});
});
});
});
}); // ==== End of 'Update' ==== // }); // ==== End of 'Update' ==== //

Loading…
Cancel
Save