Skip to content

Commit

Permalink
Merge pull request #387 from ryanseys/datastore-method
Browse files Browse the repository at this point in the history
Allow explicit set of method on Dataset#save
  • Loading branch information
ryanseys committed Feb 13, 2015
2 parents b52b28b + 30bd7be commit e8b17a2
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 5 deletions.
49 changes: 44 additions & 5 deletions lib/datastore/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ DatastoreRequest.prototype.get = function(keys, callback) {
*
* @param {object|object[]} entities - Datastore key object(s).
* @param {Key} entities.key - Datastore key object.
* @param {string=} entities.method - Optional method to explicity use for save.
* The choices include 'insert', 'update', 'upsert' and 'auto_insert_id'.
* @param {object|object[]} entities.data - Data to save with the provided key.
* If you provide an array of objects, you must use the explicit syntax:
* `name` for the name of the property and `value` for its value. You may
Expand Down Expand Up @@ -209,7 +211,7 @@ DatastoreRequest.prototype.get = function(keys, callback) {
* //-
* var companyKey = dataset.key(['Company', 123]);
* var productKey = dataset.key(['Product', 'Computer']);
*
*
* dataset.save([
* {
* key: companyKey,
Expand All @@ -224,6 +226,21 @@ DatastoreRequest.prototype.get = function(keys, callback) {
* }
* }
* ], function(err) {});
*
* //-
* // Explicitly attempt to 'insert' a specific entity.
* //-
* var userKey = dataset.key(['User', 'chilts']);
*
* dataset.save([
* {
* key: userKey,
* method: 'insert', // force the method to 'insert'
* data: {
* fullName: 'Andrew Chilton'
* }
* }
* ], function(err) {});
*/
DatastoreRequest.prototype.save = function(entities, callback) {
var isMultipleRequest = Array.isArray(entities);
Expand All @@ -234,6 +251,8 @@ DatastoreRequest.prototype.save = function(entities, callback) {
var req = {
mutation: entities.reduce(function(acc, entityObject, index) {
var ent = {};
var method = entityObject.method;
delete entityObject.method;

if (Array.isArray(entityObject.data)) {
ent.property = entityObject.data.map(function(data) {
Expand All @@ -252,15 +271,35 @@ DatastoreRequest.prototype.save = function(entities, callback) {

ent.key = entity.keyToKeyProto(entityObject.key);

if (entity.isKeyComplete(entityObject.key)) {
acc.upsert.push(ent);
if (method) {
switch (method) {
case 'insert':
acc.insert.push(ent);
break;
case 'update':
acc.update.push(ent);
break;
case 'upsert':
acc.upsert.push(ent);
break;
case 'insert_auto_id':
insertIndexes.push(index);
acc.insert_auto_id.push(ent);
break;
}
} else {
insertIndexes.push(index);
acc.insert_auto_id.push(ent);
if (entity.isKeyComplete(entityObject.key)) {
acc.upsert.push(ent);
} else {
insertIndexes.push(index);
acc.insert_auto_id.push(ent);
}
}

return acc;
}, {
insert: [],
update: [],
upsert: [],
insert_auto_id: []
})
Expand Down
32 changes: 32 additions & 0 deletions regression/datastore.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,38 @@ describe('datastore', function() {
});
});

it('should fail explicitly set second insert on save', function(done) {
var postKey = ds.key('Post');

ds.save({ key: postKey, data: post }, function(err) {
assert.ifError(err);

// The key's path should now be complete.
assert(postKey.path[1]);

ds.save({ key: postKey, method: 'insert', data: post }, function(err) {
assert.notEqual(err, null); // should fail insert

ds.get(postKey, function(err, entity) {
assert.ifError(err);

assert.deepEqual(entity.data, post);

ds.delete(postKey, done);
});
});
});
});

it('should fail explicitly set first update on save', function(done) {
var postKey = ds.key('Post');

ds.save({ key: postKey, method: 'update', data: post }, function(err) {
assert.notEqual(err, null);
done();
});
});

it('should save/get/delete multiple entities at once', function(done) {
var post2 = {
title: 'How to make the perfect homemade pasta',
Expand Down
19 changes: 19 additions & 0 deletions test/datastore/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,25 @@ describe('Request', function() {
], done);
});

it('should save with specific method', function(done) {
request.makeReq_ = function(method, req, callback) {
assert.equal(method, 'commit');
assert.equal(req.mutation.insert.length, 1);
assert.equal(req.mutation.update.length, 1);
assert.equal(req.mutation.insert[0].property[0].name, 'k');
assert.equal(
req.mutation.insert[0].property[0].value.string_value, 'v');
assert.equal(req.mutation.update[0].property[0].name, 'k2');
assert.equal(
req.mutation.update[0].property[0].value.string_value, 'v2');
callback();
};
request.save([
{ key: key, method: 'insert', data: { k: 'v' } },
{ key: key, method: 'update', data: { k2: 'v2' } }
], done);
});

it('should not set an indexed value by default', function(done) {
request.makeReq_ = function(method, req) {
var property = req.mutation.upsert[0].property[0];
Expand Down

0 comments on commit e8b17a2

Please sign in to comment.