Skip to content

Commit

Permalink
Merge pull request #209 from ryanseys/key-docs
Browse files Browse the repository at this point in the history
Dataset.key() docs + proposal for simpler API
  • Loading branch information
stephenplusplus committed Sep 17, 2014
2 parents 959e92e + 0b7132c commit 379022f
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 152 deletions.
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 : {
namespace: this.namespace,
path: util.arrayize(options)
};
return new entity.Key(options);
};


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) {});
*/
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) {
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

0 comments on commit 379022f

Please sign in to comment.