added update command execution to collections

This commit is contained in:
Ritchie Martori
2012-07-02 16:32:55 -07:00
parent faa800a5f5
commit 702d2a2b0b
4 changed files with 125 additions and 3 deletions

View File

@@ -3,7 +3,8 @@ var db = module.exports = {}
, EventEmitter = require('events').EventEmitter
, mongodb = require('mongodb')
, uuid = require('./util/uuid')
, scrub = require('scrubber').scrub;
, scrub = require('scrubber').scrub
, debug = require('debug')('db');
/**
* Create a new database connection with the given options. You can start making
@@ -368,6 +369,10 @@ Store.prototype.update = function (query, object, fn) {
});
command.$set = object;
debug('update - query', query);
debug('update - object', object);
debug('update - command', command);
collection(this, function (err, col) {
col.update(query, command, function(err) {
store.identify(query);

View File

@@ -387,8 +387,20 @@ Collection.prototype.save = function (session, item, query, client, fn) {
if(!item) return fn('You must include an object when saving or updating.');
// build command object
var commands = {};
Object.keys(item).forEach(function (key) {
if(typeof item[key] === 'object') {
Object.keys(item[key]).forEach(function (k) {
if(k[0] == '$') {
commands[key] = item[key];
}
})
}
});
item = this.sanitize(item);
// handle id on either body or query
if(item.id) {
query.id = item.id;
@@ -410,6 +422,8 @@ Collection.prototype.save = function (session, item, query, client, fn) {
if(typeof item[key] == 'undefined') item[key] = obj[key];
});
collection.execCommands('update', item, commands);
var errors = collection.validate(item);
if(errors) return fn(errors);
@@ -481,6 +495,47 @@ Collection.prototype.changed = function(ctx, fn) {
fn(null, ctx.body);
}
Collection.prototype.execCommands = function (type, obj, commands) {
try {
if(type === 'update') {
Object.keys(commands).forEach(function (key) {
if(typeof commands[key] == 'object') {
Object.keys(commands[key]).forEach(function (k) {
if(k[0] !== '$') return;
var val = commands[key][k];
if(k === '$inc') {
obj[key] += val;
}
if(k === '$push') {
if(Array.isArray(obj[key])) {
obj[key].push(val);
} else {
obj[key] = [val];
}
}
if(k === '$pushAll') {
if(Array.isArray(obj[key])) {
if(Array.isArray(val)) {
for(var i = 0; i < val.length; i++) {
obj[key].push(val[i]);
}
}
} else {
obj[key] = val;
}
}
})
}
})
}
} catch(e) {
debug('error while executing commands', type, obj, commands);
}
return this;
}
Collection.prototype.clientGeneration = true;
module.exports = Collection;

View File

@@ -232,4 +232,66 @@ describe('collection', function(){
})
})
})
describe('.save()', function() {
it('should save the provided data', function(done) {
var c = new Collection({path: '/counts', db: db.connect(TEST_DB), properties: {count: {type: 'number'}}});
c.save({}, {count: 1}, {}, {}, function (err, item) {
expect(item.id).to.exist;
expect(err).to.not.exist;
done();
});
});
it('should pass commands like $inc', function(done) {
var c = new Collection({path: '/counts', db: db.connect(TEST_DB), properties: {count: {type: 'number'}}});
c.save({}, {count: 1}, {}, {}, function (err, item) {
expect(item.id).to.exist;
expect(err).to.not.exist;
c.save({}, {count: {$inc: 100}}, {id: item.id}, {}, function (err, updated) {
expect(err).to.not.exist;
expect(updated).to.exist;
expect(updated.count).to.equal(101);
done(err);
});
});
});
});
describe('.execCommands(type, obj)', function() {
it('$inc - should increment numbers', function() {
var c = new Collection()
, item = {count: 7};
c.execCommands('update', item, {count: {$inc: 7}});
expect(item.count).to.equal(14);
c.execCommands('update', item, {count: {$inc: -7}});
expect(item.count).to.equal(7);
});
it('$push - should add an object to an array', function() {
var c = new Collection()
, item = {names: ['joe', 'bob']};
c.execCommands('update', item, {names: {$push: 'sam'}});
expect(item.names).to.eql(['joe', 'bob', 'sam']);
});
it('$pushAll - should add an array of objects to an array', function() {
var c = new Collection()
, item = {names: ['joe', 'bob']};
c.execCommands('update', item, {names: {$pushAll: ['jim', 'sam']}});
expect(item.names).to.eql(['joe', 'bob', 'jim', 'sam']);
});
it('should not throw', function() {
var c = new Collection()
, item = {names: 78};
c.execCommands('update', item, {names: {$pushAll: ['jim', 'sam']}});
});
});
})

File diff suppressed because one or more lines are too long