Bulk insert works when no constraint is violated

pull/2/head
Louis Chatriot 11 years ago
parent 336d402064
commit 6fb4a61688
  1. 56
      lib/datastore.js
  2. 24
      test/db.test.js

@ -247,28 +247,64 @@ Datastore.prototype.getCandidates = function (query) {
*/ */
Datastore.prototype._insert = function (newDoc, cb) { Datastore.prototype._insert = function (newDoc, cb) {
var callback = cb || function () {} var callback = cb || function () {}
, self = this
, insertedDoc
; ;
// Ensure the document has the right format
try { try {
newDoc._id = customUtils.uid(16); this._insertInCache(newDoc);
model.checkObject(newDoc);
insertedDoc = model.deepCopy(newDoc);
} catch (e) { } catch (e) {
return callback(e); return callback(e);
} }
// Insert in all indexes (also serves to ensure uniqueness) this.persistence.persistNewState(util.isArray(newDoc) ? newDoc : [newDoc], function (err) {
try { self.addToIndexes(insertedDoc); } catch (e) { return callback(e); }
this.persistence.persistNewState([newDoc], function (err) {
if (err) { return callback(err); } if (err) { return callback(err); }
return callback(null, newDoc); return callback(null, newDoc);
}); });
}; };
/**
* If newDoc is an array of documents, this will insert all documents in the cache
* @api private
*/
Datastore.prototype._insertInCache = function (newDoc) {
var insertedDoc;
if (util.isArray(newDoc)) { this._insertMultipleDocsInCache(newDoc); return; }
// Ensure the document has the right format
newDoc._id = customUtils.uid(16);
model.checkObject(newDoc);
insertedDoc = model.deepCopy(newDoc);
// Insert in all indexes (also serves to ensure uniqueness)
this.addToIndexes(insertedDoc);
};
/**
* If one insertion fails (e.g. because of a unique constraint), roll back all previous
* inserts and throws the error
*/
Datastore.prototype._insertMultipleDocsInCache = function (newDocs) {
var i, failingI, error;
for (i = 0; i < newDocs.length; i += 1) {
try {
this._insertInCache(newDocs[i]);
} catch (e) {
error = e;
failingI = i;
break;
}
}
if (error) {
for (i = 0; i < failingI; i += 1) {
this._removeFromCache(newDocs[i]);
}
throw error;
}
};
Datastore.prototype.insert = function () { Datastore.prototype.insert = function () {
this.executor.push({ this: this, fn: this._insert, arguments: arguments }); this.executor.push({ this: this, fn: this._insert, arguments: arguments });
}; };

@ -179,6 +179,30 @@ describe('Database', function () {
}); });
}); });
}); });
it.only('Can insert an array of documents at once', function (done) {
var docs = [{ a: 5, b: 'hello' }, { a: 42, b: 'world' }];
d.insert(docs, function (err) {
d.find({}, function (err, docs) {
var data;
docs.length.should.equal(2);
_.find(docs, function (doc) { return doc.a === 5; }).b.should.equal('hello');
_.find(docs, function (doc) { return doc.a === 42; }).b.should.equal('world');
// The data has been persisted correctly
data = _.filter(fs.readFileSync(testDb, 'utf8').split('\n'), function (line) { return line.length > 0; });
data.length.should.equal(2);
model.deserialize(data[0]).a.should.equal(5);
model.deserialize(data[0]).b.should.equal('hello');
model.deserialize(data[1]).a.should.equal(42);
model.deserialize(data[1]).b.should.equal('world');
done();
});
});
});
}); // ==== End of 'Insert' ==== // }); // ==== End of 'Insert' ==== //

Loading…
Cancel
Save