Skip to content

Commit

Permalink
Batch create
Browse files Browse the repository at this point in the history
  • Loading branch information
1602 committed Mar 31, 2013
1 parent 1749782 commit 0776c51
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
9 changes: 9 additions & 0 deletions docs/model.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ instance.
console.log(user instanceof User);
});

When called with array of objects as first argument `Model.create` creates bunch
of records. Both `err` and `model instance` arguments passed to callback will be
arrays then. When no errors happened `err` argument will be null.

The value returned from `Model.create` depends on second argument too. In case
of Array it will return an array of instances, otherwise single instance. But be
away, this instance(s) aren't save to database yet and you have to wait until
callback called to be able to do id-sensitive stuff.

### Model.prototype.save([options[, callback]]);

Save instance to database, options is an object {validate: true, throws: false},
Expand Down
34 changes: 31 additions & 3 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ AbstractClass.prototype.whatTypeName = function (propName) {
AbstractClass.create = function (data, callback) {
if (stillConnecting(this.schema, this, arguments)) return;

var modelName = this.modelName;
var Model = this;
var modelName = Model.modelName;

if (typeof data === 'function') {
callback = data;
Expand All @@ -171,12 +172,39 @@ AbstractClass.create = function (data, callback) {
callback = function () {};
}

if (data instanceof Array) {
var instances = [];
var errors = new Array(data.length);
var gotError = false;
var wait = data.length;
if (wait === 0) callback(null, []);

var instances = data.map(function(d, i) {
return Model.create(d, function(err, inst) {
// console.log('got', i, err, inst, inst.errors);
if (err) {
errors[i] = err;
gotError = true;
}
modelCreated();
});
});

return instances;

function modelCreated() {
if (--wait === 0) {
callback(gotError ? errors : null, instances);
}
}
}

var obj;
// if we come from save
if (data instanceof this && !data.id) {
if (data instanceof Model && !data.id) {
obj = data;
} else {
obj = new this(data);
obj = new Model(data);
}
data = obj.toObject(true);

Expand Down
27 changes: 26 additions & 1 deletion test/manipulation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,35 @@ describe('manipulation', function() {
should.exist(this.id);
Person.afterCreate = null;
next();
setTimeout(done, 10);
setTimeout(done, 30);
};
Person.create();
});

it('should create batch of objects', function(done) {
var batch = [{name: 'Shaltay'}, {name: 'Boltay'}, {}];
Person.create(batch, function(e, ps) {
should.not.exist(e);
should.exist(ps);
ps.should.be.instanceOf(Array);
ps.should.have.lengthOf(batch.length);

Person.validatesPresenceOf('name');
Person.create(batch, function(errors, persons) {
delete Person._validations;
should.exist(errors);
errors.should.have.lengthOf(batch.length);
should.not.exist(errors[0]);
should.not.exist(errors[1]);
should.exist(errors[2]);

should.exist(persons);
persons.should.have.lengthOf(batch.length);
persons[0].errors.should.be.false;
done();
}).should.be.instanceOf(Array);
}).should.have.lengthOf(3);
});
});

describe('save', function() {
Expand Down

0 comments on commit 0776c51

Please sign in to comment.