Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datastore: _action_All methods removed. #90

Merged
merged 1 commit into from
Aug 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 32 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,28 @@ If you are not running this client on Google Compute Engine, you need a Google D
* Create a new project or click on an existing project.
* Enable billing if you haven't already.
* On the "APIs & auth" tab, click APIs section and turn on the following. You may need to enable billing in order to use these services.
* Google Cloud Datastore API
* Google Cloud Storage
* Google Cloud Storage JSON API
* Google Cloud Datastore API
* Google Cloud Storage
* Google Cloud Storage JSON API
* Google Cloud Pub/Sub
* Once API access is enabled, switch back to "APIs & auth" section on the navigation panel and switch to "Credentials" page.
* Click on "Create new client ID" to create a new **service account**. Once the account is created, click on "Generate new JSON key" to download
your private key.

The downloaded file contains credentials you'll need for authorization.
* You'll the following for auth configuration:
* Developers Console project's ID (e.g. bamboo-shift-455)
* The path to the JSON key file.
* Developers Console project's ID (e.g. bamboo-shift-455)
* The path to the JSON key file.

## Developer's Guide

* [Google Cloud Datastore](#google-cloud-datastore)
* [Configuration](#configuration)
* [Entities and Keys](#entities-and-keys)
* [Getting, Saving and Deleting Entities](#getting-saving-and-deleting-entities)
* [Querying](#querying)
* [Allocating IDs](#allocating-ids-id-generation)
* [Transactions](#transactions)
* [Configuration](#configuration)
* [Entities and Keys](#entities-and-keys)
* [Getting, Saving and Deleting Entities](#getting-saving-and-deleting-entities)
* [Querying](#querying)
* [Allocating IDs](#allocating-ids-id-generation)
* [Transactions](#transactions)
* [Google Cloud Storage](#google-cloud-storage)
* [Configuration](#configuration-1)
* [Listing Files](#listing-files)
Expand Down Expand Up @@ -83,8 +83,8 @@ Elsewhere, initiate with project ID and private key downloaded from Developer's
~~~~ js
var gcloud = require('gcloud'),
ds = new gcloud.datastore.Dataset({
projectId: YOUR_PROJECT_ID,
keyFilename: '/path/to/the/key.json'
projectId: YOUR_PROJECT_ID,
keyFilename: '/path/to/the/key.json'
});
~~~~

Expand All @@ -97,45 +97,46 @@ TODO
Get operations require a valid key to retrieve the key identified entity from Datastore. Skip to the "Querying" section if you'd like to learn more about querying against Datastore.

~~~~ js
ds.get(['Company', 123], function(err, entities) {
ds.get(['Company', 123], function(err, entity) {});

});
// alternatively, you can retrieve multiple entities at once.
ds.getAll([key1, key2, ...], function(err, entities) {

});
ds.get([
['Company', 123],
['Product', 'Computer']
], function(err, entities) {});
~~~~

You can insert arbitrary objects by providing an incomplete key during saving. If the key is not incomplete, the existing entity is updated or inserted with the provided key.

To learn more about keys and incomplete keys, skip to the Keys section.

~~~~ js
ds.save(['Company', null], obj, function(err, key) {
// First arg is an incomplete key for Company kind.
// console.log(key) will output ['Company', 599900452312].
ds.save({ key: ['Company', null], data: {/*...*/} }, function(err, key) {
// First arg is an incomplete key for Company kind.
// console.log(key) will output ['Company', 599900452312].
});
// alternatively, you can save multiple entities at once.
ds.saveAll([key1, key2, key3], [obj1, obj2, obj3], function(err, keys) {
// if key1 was incomplete, keys[0] will return the generated key.
ds.save([
{ key: ['Company', 123], data: {/*...*/} },
{ key: ['Product', 'Computer'], data: {/*...*/} }
], function(err, keys) {
// if the first key was incomplete, keys[0] will return the generated key.
});
~~~~

Deletion requires the key of the entity to be deleted.

~~~~ js
ds.del(['Company', 599900452312], function(err) {
ds.delete(['Company', 599900452312], function(err) {});

});
// alternatively, you can delete multiple entities of different
// kinds at once.
ds.delAll([
['Company', 599900452312],
['Company', 599900452315],
ds.delete([
['Company', 599900452312],
['Company', 599900452315],
['Office', 'mtv'],
['Company', 123, 'Employee', 'jbd']], function(err) {

});
['Company', 123, 'Employee', 'jbd']
], function(err) {});
~~~~

#### Querying

This comment was marked as spam.

This comment was marked as spam.

Expand Down
146 changes: 41 additions & 105 deletions lib/datastore/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,33 +93,18 @@ Transaction.prototype.finalize = function(callback) {
};

/**
* Get retrieves the objects identified with the specified key in the
* Get retrieves the objects identified with the specified key(s) in the
* current transaction.
* @param {Array} key
* @param {Array} keys
* @param {Function} callback
*/
Transaction.prototype.get = function(key, callback) {
this.getAll([key], function(err, results) {
if (err) {
return callback(err);
}
return callback(null, results[0]);
});
};

/**
* Gets all objects identified with the specified list of keys
* in the current transaction.
* @param {Array<Array>} keys
* @param {Function} callback
*/
Transaction.prototype.getAll = function(keys, callback) {
Transaction.prototype.get = function(keys, callback) {
var isMultipleRequest = Array.isArray(keys[0]);
keys = isMultipleRequest ? keys : [keys];

This comment was marked as spam.

This comment was marked as spam.

callback = callback || util.noop;
keysProto = [];
keys.forEach(function(k) {
keysProto.push(entity.keyToKeyProto(this.id, k));
});
var req = { keys: keysProto };
var req = {
keys: keys.map(entity.keyToKeyProto.bind(null, this.id))
};
if (this.id) {
req.transaction = this.id;
}
Expand All @@ -128,113 +113,76 @@ Transaction.prototype.getAll = function(keys, callback) {
if (err) {
return callback(err);
}

callback(null, entity.formatArray(resp.found));
var response = entity.formatArray(resp.found);
callback(null, isMultipleRequest ? response : response[0]);
});
};

/**
* Inserts or updates the specified the object in the current
* transaction. If the provided key is incomplete, inserts the object
* and returns the generated identifier.
* @param {Array} key
* @param {Object} obj
* @param {Function} callback
*/
Transaction.prototype.save = function(key, obj, callback) {
this.saveAll([key], [obj], function(err, keys) {
if (err || !keys) {
return callback(err);
}
if (keys[0]) {
return callback(err, keys[0]);
}
callback();
});
};

/**
* Inserts or upates the specified objects in the current transaction.
* Inserts or upates the specified object(s) in the current transaction.
* If a key is incomplete, its associated object is inserted and
* generated identifier is returned.
* @param {Array<Array>} keys
* @param {Array<Object>} objs
* @param {Array<Object>} entities
* @param {Function} callback
*/
Transaction.prototype.saveAll = function(keys, objs, callback) {
if (keys.length != objs.length) {
throw new Error('The length of the keys don\'t match the length of the objects');
}
Transaction.prototype.save = function(entities, callback) {
var isMultipleRequest = Array.isArray(entities);
entities = isMultipleRequest ? entities : [entities];
var insertIndexes = [];
var keys = entities.map(function(entityObject) {
return entityObject.key;
});
var req = {
mode: MODE_NON_TRANSACTIONAL,
mutation: {
upsert: [],
insertAutoId: []
}
mutation: entities.reduce(function(acc, entityObject, index) {
var ent = entity.entityToEntityProto(entityObject.data);
ent.key = entity.keyToKeyProto(this.datasetId, entityObject.key);
if (entity.isKeyComplete(entityObject.key)) {
acc.upsert.push(ent);
} else {
insertIndexes.push(index);
acc.insertAutoId.push(ent);
}
return acc;
}, { upsert: [], insertAutoId: [] })
};
if (this.id) {
req.transaction = this.id;
req.mode = MODE_TRANSACTIONAL;
}
for (var i = 0; i < keys.length; i++) {
var e = entity.entityToEntityProto(objs[i]);
e.key = entity.keyToKeyProto(this.datasetId, keys[i]);
if (entity.isKeyComplete(keys[i])) {
req.mutation.upsert.push(e);
} else {
insertIndexes.push(i);
req.mutation.insertAutoId.push(e);
}
}
this.makeReq(
'commit', req, function(err, resp) {
if (err || !resp) {
return callback(err);
}
resp.mutationResult.insertAutoIdKeys = resp.mutationResult.insertAutoIdKeys || [];
var i = 0;
resp.mutationResult.insertAutoIdKeys.forEach(function(item) {
keys[insertIndexes[i++]] = entity.keyFromKeyProto(item);
(resp.mutationResult.insertAutoIdKeys || []).forEach(function(key, index) {
keys[insertIndexes[index]] = entity.keyFromKeyProto(key);
});
callback(null, keys);
callback(null, isMultipleRequest ? keys : keys[0]);
});
};

/**
* Deletes the entitiy identified with the specified key in the
* current transaction.
* @param {Array} key
* @param {Function} callback
*/
Transaction.prototype.del = function(key, callback) {
this.delAll([key], callback);
};

/**
* Deletes all entities identified with the specified list of keys
* Deletes all entities identified with the specified list of key(s)
* in the current transaction.
* @param {Array<Array>} keys
* @param {Function} callback
*/
Transaction.prototype.delAll = function(keys, callback) {
keysProto = [];
keys.forEach(function(k) {
keysProto.push(entity.keyToKeyProto(this.id, k));
});
Transaction.prototype.delete = function(keys, callback) {
var isMultipleRequest = Array.isArray(keys[0]);
keys = isMultipleRequest ? keys : [keys];
callback = callback || util.noop;
var req = {
mode: MODE_NON_TRANSACTIONAL,
mutation: {
'delete': keysProto
delete: keys.map(entity.keyToKeyProto.bind(null, this.id))
}
};
if (this.id) {
req.transaction = this.id;
req.mode = MODE_TRANSACTIONAL;
}
this.makeReq('commit', req, function(err, resp) {
callback && callback(err);
});
this.makeReq('commit', req, callback);
};

/**
Expand Down Expand Up @@ -350,24 +298,12 @@ Dataset.prototype.get = function(key, callback) {
this.transaction.get(key, callback);
};

Dataset.prototype.getAll = function(keys, callback) {
this.transaction.getAll(keys, callback);
};

Dataset.prototype.save = function(key, obj, callback) {
this.transaction.save(key, obj, callback);
};

Dataset.prototype.saveAll = function(keys, objs, callback) {
this.transaction.saveAll(keys, objs, callback);
};

Dataset.prototype.del = function(key, callback) {
this.transaction.del(key, callback);
};

Dataset.prototype.delAll = function(keys, callback) {
this.transaction.delAll(keys, callback);
Dataset.prototype.delete = function(key, callback) {
this.transaction.delete(key, callback);
};

Dataset.prototype.runQuery = function(q, callback) {
Expand Down
Loading