|
|
|
@ -2,6 +2,7 @@ |
|
|
|
|
* The datastore itself |
|
|
|
|
* TODO |
|
|
|
|
* Queue operations |
|
|
|
|
* Enable upserts |
|
|
|
|
* Update and removes should only modify the corresponding part of the database |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
@ -9,6 +10,7 @@ var fs = require('fs') |
|
|
|
|
, path = require('path') |
|
|
|
|
, customUtils = require('./customUtils') |
|
|
|
|
, model = require('./model') |
|
|
|
|
, async = require('async') |
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -107,11 +109,6 @@ Datastore.match = function (obj, query) { |
|
|
|
|
//, queryKeys = Object.keys(query)
|
|
|
|
|
, 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) { |
|
|
|
|
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} options Optional options |
|
|
|
|
* 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) { |
|
|
|
|
var callback |
|
|
|
|
, self = this |
|
|
|
|
, numReplaced = 0 |
|
|
|
|
, multi |
|
|
|
|
, multi, upsert |
|
|
|
|
, newData = []; |
|
|
|
|
|
|
|
|
|
if (typeof options === 'function') { cb = options; options = {}; } |
|
|
|
|
callback = cb || function () {}; |
|
|
|
|
multi = options.multi !== undefined ? options.multi : false; |
|
|
|
|
upsert = options.upsert !== undefined ? options.upsert : false; |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
async.waterfall([ |
|
|
|
|
function (cb) { // If upsert option is set, check whether we need to insert the doc
|
|
|
|
|
if (!upsert) { return cb(); } |
|
|
|
|
|
|
|
|
|
self.persistWholeDatabase(newData, function (err) { |
|
|
|
|
if (err) { return callback(err); } |
|
|
|
|
self.data = newData; |
|
|
|
|
return callback(null, numReplaced); |
|
|
|
|
}); |
|
|
|
|
self.findOne(query, function (err, doc) { |
|
|
|
|
if (err) { return callback(err); } |
|
|
|
|
if (doc) { |
|
|
|
|
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); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
]); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|