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

Dataset.key() docs + proposal for simpler API #209

Merged
merged 1 commit into from
Sep 17, 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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Google Cloud Node.js Client
> Node idiomatic client for Google Cloud services.
> Node.js idiomatic client for Google Cloud services.

[![NPM Version](https://img.shields.io/npm/v/gcloud.svg)](https://www.npmjs.org/package/gcloud)
[![Travis Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-node.svg)](https://travis-ci.org/GoogleCloudPlatform/gcloud-node/)
Expand Down Expand Up @@ -65,7 +65,7 @@ dataset = new datastore.Dataset({
keyFilename: '/path/to/keyfile.json'
});

dataset.get(dataset.key('Product', 'Computer'), function(err, entity) {
dataset.get(dataset.key(['Product', 'Computer']), function(err, entity) {
console.log(err || entity);
});
```
Expand Down
62 changes: 39 additions & 23 deletions lib/datastore/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,24 +111,37 @@ function Dataset(options) {
*
* You may also specify a configuration object to define a namespace and path.
*
* @param {...*=} options - Key path. To specify or override a namespace,
* you must use an object here to explicitly state it.
* @param {object=} options - Configuration object.
* @param {...*=} options.path - Key path.
* @param {string=} options.namespace - Optional namespace.
*
* @example
* // Create a key from the dataset's namespace.
* var company123 = dataset.key('Company', 123);
* var key;
*
* // Create an incomplete key from the dataset namespace, kind='Company'
* key = dataset.key('Company');
*
* // A complete key from the dataset namespace, kind='Company', id=123
* key = dataset.key(['Company', 123]);
*
* // Create a key from a provided namespace and path.
* var nsCompany123 = dataset.key({
* // A complete key from the dataset namespace, kind='Company', name='Google'
* // Note: `id` is used for numeric identifiers and `name` is used otherwise
* key = dataset.key(['Company', 'Google']);
*
* // A complete key from a provided namespace and path.
* key = dataset.key({
* namespace: 'My-NS',
* path: ['Company', 123]
* });
*/
Dataset.prototype.key = function(keyConfig) {
if (!util.is(keyConfig, 'object')) {
keyConfig = {
namespace: this.namespace,
path: util.toArray(arguments)
};
}
return new entity.Key(keyConfig);
Dataset.prototype.key = function(options) {
options = util.is(options, 'object') ? options : {

This comment was marked as spam.

namespace: this.namespace,
path: util.arrayize(options)
};
return new entity.Key(options);
};

This comment was marked as spam.



Expand Down Expand Up @@ -165,8 +178,8 @@ Dataset.prototype.createQuery = function(namespace, kinds) {
*
* @example
* dataset.get([
* dataset.key('Company', 123),
* dataset.key('Product', 'Computer')
* dataset.key(['Company', 123]),
* dataset.key(['Product', 'Computer'])
* ], function(err, entities) {});
*/
Dataset.prototype.get = function(key, callback) {
Expand All @@ -188,7 +201,7 @@ Dataset.prototype.get = function(key, callback) {
* @example
* // Save a single entity.
* dataset.save({
* key: dataset.key('Company', null),
* key: dataset.key('Company'),
* data: {
* rating: '10'
* }
Expand All @@ -200,13 +213,13 @@ Dataset.prototype.get = function(key, callback) {
* // Save multiple entities at once.
* dataset.save([
* {
* key: dataset.key('Company', 123),
* key: dataset.key(['Company', 123]),
* data: {
* HQ: 'Dallas, TX'
* }
* },
* {
* key: dataset.key('Product', 'Computer'),
* key: dataset.key(['Product', 'Computer']),
* data: {
* vendor: 'Dell'
* }
Expand All @@ -228,12 +241,12 @@ Dataset.prototype.save = function(key, obj, callback) {
*
* @example
* // Delete a single entity.
* dataset.delete(dataset.key('Company', 123), function(err) {});
* dataset.delete(dataset.key(['Company', 123]), function(err) {});
*
* // Delete multiple entities at once.
* dataset.delete([
* dataset.key('Company', 123),
* dataset.key('Product', 'Computer')
* dataset.key(['Company', 123]),
* dataset.key(['Product', 'Computer'])
* ], function(err) {});
*/
Dataset.prototype.delete = function(key, callback) {
Expand Down Expand Up @@ -277,7 +290,7 @@ Dataset.prototype.runQuery = function(q, callback) {
* dataset.runInTransaction(function(transaction, done) {
* // From the `transaction` object, execute dataset methods as usual.
* // Call `done` when you're ready to commit all of the changes.
* transaction.get(dataset.key('Company', 123), function(err, entity) {
* transaction.get(dataset.key(['Company', 123]), function(err, entity) {
* if (err) {
* transaction.rollback(done);
* return;
Expand Down Expand Up @@ -308,14 +321,17 @@ Dataset.prototype.runInTransaction = function(fn, callback) {
* @example
* // The following call will create 100 new IDs from the Company kind, which
* // exists under the default namespace.
* var incompleteKey = dataset.key('Company', null);
* var incompleteKey = dataset.key('Company');
* dataset.allocateIds(incompleteKey, 100, function(err, keys) {});
*
* // You may prefer to create IDs from a non-default namespace by providing an
* // incomplete key with a namespace. Similar to the previous example, the call
* // below will create 100 new IDs, but from the Company kind that exists under
* // the "ns-test" namespace.
* var incompleteKey = dataset.key('ns-test', 'Company', null);
* var incompleteKey = dataset.key({
* namespace: 'ns-test',
* path: ['Company']
* });
* dataset.allocateIds(incompleteKey, 100, function(err, keys) {});
*/

This comment was marked as spam.

This comment was marked as spam.

Dataset.prototype.allocateIds = function(incompleteKey, n, callback) {
Expand Down
24 changes: 17 additions & 7 deletions lib/datastore/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,21 @@ function keyFromKeyProto(proto) {
var keyOptions = {
path: []
};

if (proto.partition_id && proto.partition_id.namespace) {
keyOptions.namespace = proto.partition_id.namespace;
}
proto.path_element.forEach(function(path) {

proto.path_element.forEach(function(path, index) {
var id = Number(path.id) || path.name;
keyOptions.path.push(path.kind);
keyOptions.path.push(Number(path.id) || path.name || null);
if (id) {
keyOptions.path.push(id);
} else if (index < proto.path_element.length - 1) {
throw new Error('Invalid key. Ancestor keys require an id or name.');
}
});

return new Key(keyOptions);
}

Expand All @@ -216,7 +224,7 @@ module.exports.keyFromKeyProto = keyFromKeyProto;
* @return {object}
*
* @example
* var keyProto = keyToKeyProto(new Key('Company', 1));
* var keyProto = keyToKeyProto(new Key(['Company', 1]));
*
* // keyProto:
* // {
Expand All @@ -230,8 +238,8 @@ module.exports.keyFromKeyProto = keyFromKeyProto;
*/
function keyToKeyProto(key) {
var keyPath = key.path;
if (keyPath.length < 2) {
throw new Error('A key should contain at least a kind and an identifier.');
if (keyPath.length === 0) {

This comment was marked as spam.

This comment was marked as spam.

throw new Error('A key should contain at least a kind.');
}
var path = [];
for (var i = 0; i < keyPath.length; i += 2) {
Expand All @@ -244,6 +252,8 @@ function keyToKeyProto(key) {
} else {
p.id = val;
}
} else if (i < keyPath.length - 2) { // i is second last path item
throw new Error('Invalid key. Ancestor keys require an id or name.');
}
path.push(p);
}
Expand Down Expand Up @@ -300,8 +310,8 @@ module.exports.formatArray = formatArray;
* @return {boolean}
*
* @example
* isKeyComplete(new Key('Company', 'Google')); // true
* isKeyComplete(new Key('Company', null)); // false
* isKeyComplete(new Key(['Company', 'Google'])); // true
* isKeyComplete(new Key('Company')); // false
*/
module.exports.isKeyComplete = function(key) {
var proto = keyToKeyProto(key);
Expand Down
4 changes: 2 additions & 2 deletions lib/datastore/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function Query(namespace, kinds) {
*
* // To filter by key, use `__key__` for the property name. Filter on keys
* // stored as properties is not currently supported.
* var keyQuery = query.filter('__key__ =', dataset.key('Company', 'Google'));
* var keyQuery = query.filter('__key__ =', dataset.key(['Company', 'Google']));
*/
Query.prototype.filter = function(filter, value) {
// TODO: Add filter validation.
Expand All @@ -122,7 +122,7 @@ Query.prototype.filter = function(filter, value) {
* @return {module:datastore/query}
*
* @example
* var ancestoryQuery = query.hasAncestor(dataset.key('Parent', 123));
* var ancestoryQuery = query.hasAncestor(dataset.key(['Parent', 123]));
*/
Query.prototype.hasAncestor = function(key) {
var query = extend(new Query(), this);
Expand Down
23 changes: 11 additions & 12 deletions lib/datastore/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function Transaction(conn, datasetId) {
* @example
* transaction.begin(function(err) {
* // Perform Datastore operations as usual.
* transaction.get(dataset.key('Company', 123), function(err, entity) {
* transaction.get(dataset.key(['Company', 123]), function(err, entity) {
* // Commit the transaction.
* transaction.finalize(function(err) {});
*
Expand Down Expand Up @@ -189,20 +189,19 @@ Transaction.prototype.finalize = function(callback) {
* transaction. Get operations require a valid key to retrieve the
* key-identified entity from Datastore.
*
* @param {Key|Key[]} key -
* Datastore key object(s).
* @param {Key|Key[]} key - Datastore key object(s).
* @param {function} callback - The callback function.
*
* @example
* // These examples work with both a Transaction object and a Dataset object.
*
* // Get a single entity.
* transaction.get(dataset.key('Company', 123), function(err, entity));
* transaction.get(dataset.key(['Company', 123]), function(err, entity) {});
*
* // Get multiple entities at once.
* transaction.get([
* dataset.key('Company', 123),
* dataset.key('Product', 'Computer')
* dataset.key(['Company', 123]),
* dataset.key(['Product', 'Computer'])
* ], function(err, entities) {});
*/
Transaction.prototype.get = function(keys, callback) {
Expand Down Expand Up @@ -256,7 +255,7 @@ Transaction.prototype.get = function(keys, callback) {
*
* // Save a single entity.
* transaction.save({
* key: dataset.key('Company', null),
* key: dataset.key('Company'),
* data: {
* rating: '10'
* }
Expand All @@ -268,13 +267,13 @@ Transaction.prototype.get = function(keys, callback) {
* // Save multiple entities at once.
* transaction.save([
* {
* key: dataset.key('Company', 123),
* key: dataset.key(['Company', 123]),
* data: {
* HQ: 'Dallas, TX'
* }
* },
* {
* key: dataset.key('Product', 'Computer'),
* key: dataset.key(['Product', 'Computer']),
* data: {
* vendor: 'Dell'
* }
Expand Down Expand Up @@ -332,12 +331,12 @@ Transaction.prototype.save = function(entities, callback) {
* // These examples work with both a Transaction object and a Dataset object.
*
* // Delete a single entity.
* transaction.delete(dataset.key('Company', 123), function(err) {});
* transaction.delete(dataset.key(['Company', 123]), function(err) {});
*
* // Delete multiple entities at once.
* transaction.delete([
* dataset.key('Company', 123),
* dataset.key('Product', 'Computer')
* dataset.key(['Company', 123]),
* dataset.key(['Product', 'Computer'])
* ], function(err) {});
*/
Transaction.prototype.delete = function(keys, callback) {
Expand Down
Loading