From 874a147ce7d81e348ca39cd1fc533fddf3d27655 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Thu, 7 Aug 2014 14:37:46 -0700 Subject: [PATCH 1/6] datastore: Introduce Key type. --- lib/datastore/entity.js | 29 ++++++++++++++++++----------- lib/datastore/index.js | 7 +++++++ lib/datastore/transaction.js | 5 +++-- test/datastore/dataset.js | 30 ++++++++++++++++-------------- test/datastore/entity.js | 31 ++++++++++++++----------------- 5 files changed, 58 insertions(+), 44 deletions(-) diff --git a/lib/datastore/entity.js b/lib/datastore/entity.js index e0b1bcbefc8..0089e3ed7ea 100644 --- a/lib/datastore/entity.js +++ b/lib/datastore/entity.js @@ -43,6 +43,12 @@ var signToOrderDict = { '+': 'ASCENDING' }; +function Key(path) { + this.path_ = path; +} + +module.exports.Key = Key; + function Int(val) { this.val = val; } @@ -78,34 +84,35 @@ var entityFromEntityProto = function(proto) { module.exports.entityFromEntityProto = entityFromEntityProto; var keyFromKeyProto = function(proto) { - var key = []; + var path = []; if (proto.partitionId.namespace) { - key.push(proto.partitionId.namespace); + path.push(proto.partitionId.namespace); } proto.path.forEach(function(p) { - key.push(p.kind); - key.push(Number(p.id) || p.name || null); + path.push(p.kind); + path.push(Number(p.id) || p.name || null); }); - return key; + return new Key(path); }; module.exports.keyFromKeyProto = keyFromKeyProto; var keyToKeyProto = function(key) { - if (key.length < 2) { + var keyPath = key.path_; + if (keyPath.length < 2) { throw new Error('A key should contain at least a kind and an identifier.'); } var namespace = null; var start = 0; - if (key.length % 2 === 1) { + if (keyPath.length % 2 === 1) { // the first item is the namespace - namespace = key[0]; + namespace = keyPath[0]; start = 1; } var path = []; - for (var i = start; i < (key.length - start); i += 2) { - var p = { kind: key[i] }; - var val = key[i+1]; + for (var i = start; i < (keyPath.length - start); i += 2) { + var p = { kind: keyPath[i] }; + var val = keyPath[i+1]; if (val) { // if not numeric, set key name. if (isNaN(val)) { diff --git a/lib/datastore/index.js b/lib/datastore/index.js index 3eccac9a204..f985648ea91 100644 --- a/lib/datastore/index.js +++ b/lib/datastore/index.js @@ -20,6 +20,13 @@ var entity = require('./entity'); module.exports = { Dataset: require('./dataset'), + Key: function(path) { + // TODO(jbd): Handle arguments in entity.Key constructor. + if (Array.isArray(path)) { + return new entity.Key(path); + } + return new entity.Key([].slice.call(arguments)); + }, Int: function(value) { return new entity.Int(value); }, diff --git a/lib/datastore/transaction.js b/lib/datastore/transaction.js index bbcb7c3593c..e4206eaa77c 100644 --- a/lib/datastore/transaction.js +++ b/lib/datastore/transaction.js @@ -100,7 +100,7 @@ Transaction.prototype.finalize = function(callback) { * @param {Function} callback */ Transaction.prototype.get = function(keys, callback) { - var isMultipleRequest = Array.isArray(keys[0]); + var isMultipleRequest = Array.isArray(keys); keys = isMultipleRequest ? keys : [keys]; callback = callback || util.noop; var req = { @@ -170,9 +170,10 @@ Transaction.prototype.save = function(entities, callback) { * @param {Function} callback */ Transaction.prototype.delete = function(keys, callback) { - var isMultipleRequest = Array.isArray(keys[0]); + var isMultipleRequest = Array.isArray(keys); keys = isMultipleRequest ? keys : [keys]; callback = callback || util.noop; + var req = { mode: MODE_NON_TRANSACTIONAL, mutation: { diff --git a/test/datastore/dataset.js b/test/datastore/dataset.js index 305a6d19a53..7d577a3fb87 100644 --- a/test/datastore/dataset.js +++ b/test/datastore/dataset.js @@ -31,9 +31,9 @@ describe('Dataset', function() { assert.equal(proto.keys.length, 1); callback(null, mockRespGet); }; - ds.get(['Kind', 123], function(err, entity) { + ds.get(datastore.Key('Kind', 123), function(err, entity) { var properties = entity.data; - assert.deepEqual(entity.key, ['Kind', 5732568548769792]); + assert.deepEqual(entity.key.path_, ['Kind', 5732568548769792]); assert.strictEqual(properties.name, 'Burcu'); assert.deepEqual(properties.bytes, new Buffer('hello')); assert.strictEqual(properties.done, false); @@ -50,10 +50,11 @@ describe('Dataset', function() { assert.equal(proto.keys.length, 1); callback(null, mockRespGet); }; - ds.get([['Kind', 123]], function(err, entities) { + var key = datastore.Key('Kind', 5732568548769792); + ds.get([key], function(err, entities) { var entity = entities[0]; var properties = entity.data; - assert.deepEqual(entity.key, ['Kind', 5732568548769792]); + assert.deepEqual(entity.key.path_, ['Kind', 5732568548769792]); assert.strictEqual(properties.name, 'Burcu'); assert.deepEqual(properties.bytes, new Buffer('hello')); assert.strictEqual(properties.done, false); @@ -70,7 +71,7 @@ describe('Dataset', function() { assert.equal(!!proto.mutation.delete, true); callback(); }; - ds.delete(['Kind', 123], done); + ds.delete(datastore.Key('Kind', 123), done); }); it('should multi delete by keys', function(done) { @@ -81,8 +82,8 @@ describe('Dataset', function() { callback(); }; ds.delete([ - ['Kind', 123], - ['Kind', 345] + datastore.Key('Kind', 123), + datastore.Key('Kind', 345) ], done); }); @@ -93,7 +94,8 @@ describe('Dataset', function() { assert.equal(proto.mutation.insertAutoId.length, 1); callback(); }; - ds.save({ key: ['Kind', 123, null], data: {} }, done); + var key = datastore.Key('Kind', 123, null); + ds.save({ key: key, data: {} }, done); }); it('should save with keys', function(done) { @@ -105,8 +107,8 @@ describe('Dataset', function() { callback(); }; ds.save([ - { key: ['Kind', 123], data: { k: 'v' } }, - { key: ['Kind', 456], data: { k: 'v' } } + { key: datastore.Key('Kind', 123), data: { k: 'v' } }, + { key: datastore.Key('Kind', 456), data: { k: 'v' } } ], done); }); @@ -127,8 +129,8 @@ describe('Dataset', function() { ] }); }; - ds.allocateIds(['Kind', null], 1, function(err, ids) { - assert.deepEqual(ids[0], ['Kind', 123]); + ds.allocateIds(datastore.Key('Kind', null), 1, function(err, ids) { + assert.deepEqual(ids[0], datastore.Key('Kind', 123)); done(); }); }); @@ -136,7 +138,7 @@ describe('Dataset', function() { it('should throw if trying to allocate IDs with complete keys', function() { var ds = new datastore.Dataset({ projectId: 'test' }); assert.throws(function() { - ds.allocateIds(['Kind', 123]); + ds.allocateIds(datastore.Key('Kind', 123)); }); }); @@ -229,7 +231,7 @@ describe('Dataset', function() { assert.ifError(err); var properties = entities[0].data; - assert.deepEqual(entities[0].key, ['Kind', 5732568548769792]); + assert.deepEqual(entities[0].key.path_, ['Kind', 5732568548769792]); assert.strictEqual(properties.name, 'Burcu'); assert.deepEqual(properties.bytes, new Buffer('hello')); assert.strictEqual(properties.done, false); diff --git a/test/datastore/entity.js b/test/datastore/entity.js index 224f23d83ae..0eff8413e49 100644 --- a/test/datastore/entity.js +++ b/test/datastore/entity.js @@ -149,26 +149,26 @@ describe('keyFromKeyProto', function() { it('should handle keys hierarchically', function(done) { var key = entity.keyFromKeyProto(protoH); - assert.deepEqual(key, ['Test', 'Kind', 111, 'Kind2', 'name']); + assert.deepEqual(key, datastore.Key('Test', 'Kind', 111, 'Kind2', 'name')); done(); }); it('should handle incomplete keys hierarchically', function(done) { var key = entity.keyFromKeyProto(protoHIncomplete); - assert.deepEqual(key, ['Test', 'Kind', null, 'Kind2', null]); + assert.deepEqual(key, datastore.Key('Test', 'Kind', null, 'Kind2', null)); done(); }); it('should not set namespace if default', function(done) { var key = entity.keyFromKeyProto(proto); - assert.deepEqual(key, ['Kind', 'Name']); + assert.deepEqual(key, datastore.Key('Kind', 'Name')); done(); }); }); describe('keyToKeyProto', function() { it('should handle hierarchical key definitions', function(done) { - var key = ['Kind1', 1, 'Kind2', 'name']; + var key = datastore.Key('Kind1', 1, 'Kind2', 'name'); var proto = entity.keyToKeyProto(key); assert.strictEqual(proto.partitionId, undefined); assert.strictEqual(proto.path[0].kind, 'Kind1'); @@ -181,7 +181,7 @@ describe('keyToKeyProto', function() { }); it('should detect the namespace of the hierarchical keys', function(done) { - var key = ['Namespace', 'Kind1', 1, 'Kind2', 'name']; + var key = datastore.Key('Namespace', 'Kind1', 1, 'Kind2', 'name'); var proto = entity.keyToKeyProto(key); assert.strictEqual(proto.partitionId.namespace, 'Namespace'); assert.strictEqual(proto.path[0].kind, 'Kind1'); @@ -194,8 +194,8 @@ describe('keyToKeyProto', function() { }); it('should handle incomplete keys with & without namespaces', function(done) { - var key = ['Kind1', null]; - var keyWithNS = ['Namespace', 'Kind1', null]; + var key = datastore.Key('Kind1', null); + var keyWithNS = datastore.Key('Namespace', 'Kind1', null); var proto = entity.keyToKeyProto(key); var protoWithNS = entity.keyToKeyProto(keyWithNS); @@ -222,10 +222,10 @@ describe('keyToKeyProto', function() { describe('isKeyComplete', function() { it('should ret true if kind and an identifier have !0 vals', function(done) { [ - { key: ['Kind1', null], expected: false }, - { key: ['Kind1', 3], expected: true }, - { key: ['Namespace', 'Kind1', null], expected: false }, - { key: ['Namespace', 'Kind1', 'name'], expected: true } + { key: datastore.Key('Kind1', null), expected: false }, + { key: datastore.Key('Kind1', 3), expected: true }, + { key: datastore.Key('Namespace', 'Kind1', null), expected: false }, + { key: datastore.Key('Namespace', 'Kind1', 'name'), expected: true } ].forEach(function(test) { assert.strictEqual(entity.isKeyComplete(test.key), test.expected); }); @@ -234,15 +234,12 @@ describe('isKeyComplete', function() { }); describe('entityFromEntityProto', function() { - it( - 'should support boolean, integer, double, string, entity and list values', + it('should support boolean, integer, double, string, entity and list values', function(done) { var obj = entity.entityFromEntityProto(entityProto); assert.strictEqual( obj.createdAt.getTime(), new Date('2001-01-01').getTime()); - assert.strictEqual(obj.linkedTo.ns, undefined); - assert.strictEqual(obj.linkedTo[0], 'Kind'); - assert.strictEqual(obj.linkedTo[1], 4790047639339008); + assert.deepEqual(obj.linkedTo, datastore.Key('Kind', 4790047639339008)); assert.strictEqual(obj.name, 'Name'); assert.strictEqual(obj.flagged, true); assert.strictEqual(obj.count, 5); @@ -297,7 +294,7 @@ describe('queryToQueryProto', function() { var ds = new datastore.Dataset({ projectId: 'project-id' }); var q = ds.createQuery('Kind1') .filter('name =', 'John') - .hasAncestor(['Kind2', 'somename']); + .hasAncestor(datastore.Key('Kind2', 'somename')); var proto = entity.queryToQueryProto(q); assert.deepEqual(proto, queryFilterProto); done(); From 9c8b153602dbb133069f09ffc680cbddd08880ce Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Thu, 7 Aug 2014 15:30:59 -0700 Subject: [PATCH 2/6] datastore: Fixing regression test to support the Key type. --- regression/datastore.js | 67 ++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/regression/datastore.js b/regression/datastore.js index 2a2212f0d92..2293f343ad8 100644 --- a/regression/datastore.js +++ b/regression/datastore.js @@ -37,15 +37,14 @@ describe('datastore', function() { }; it('should save/get/delete with a key name', function(done) { - var postKeyName = 'post1'; - - ds.save({ key: ['Post', postKeyName], data: post }, function(err, key) { + var postKey = datastore.Key('Post', 'post1'); + ds.save({ key: postKey, data: post }, function(err, key) { assert.ifError(err); - assert.equal(key[1], postKeyName); - ds.get(['Post', postKeyName], function(err, entity) { + assert.equal(key.path_[1], 'post1'); + ds.get(key, function(err, entity) { assert.ifError(err); assert.deepEqual(entity.data, post); - ds.delete(['Post', postKeyName], function(err) { + ds.delete(key, function(err) { assert.ifError(err); done(); }); @@ -54,15 +53,17 @@ describe('datastore', function() { }); it('should save/get/delete with a numeric key id', function(done) { - var postKeyId = '123456789'; - - ds.save({ key: ['Post', postKeyId], data: post }, function(err, key) { + var postKey = datastore.Key('Post', 123456789) + ds.save({ + key: postKey, + data: post + }, function(err, key) { assert.ifError(err); - assert.equal(key[1], postKeyId); - ds.get(['Post', postKeyId], function(err, entity) { + assert.equal(key.path_[1], 123456789); + ds.get(key, function(err, entity) { assert.ifError(err); assert.deepEqual(entity.data, post); - ds.delete(['Post', postKeyId], function(err) { + ds.delete(key, function(err) { assert.ifError(err); done(); }); @@ -71,14 +72,17 @@ describe('datastore', function() { }); it('should save/get/delete with a generated key id', function(done) { - ds.save({ key: ['Post', null], data: post }, function(err, key) { + ds.save({ + key: datastore.Key('Post', null), + data: post + }, function(err, key) { assert.ifError(err); - assert(key[1]); - var assignedId = key[1]; - ds.get(['Post', assignedId], function(err, entity) { + var assignedId = key.path_[1]; + assert(assignedId); + ds.get(datastore.Key('Post', assignedId), function(err, entity) { assert.ifError(err); assert.deepEqual(entity.data, post); - ds.delete(['Post', assignedId], function(err) { + ds.delete(datastore.Key('Post', assignedId), function(err) { assert.ifError(err); done(); }); @@ -96,15 +100,15 @@ describe('datastore', function() { wordCount: 450, rating: 4.5, }; - var key = ['Post', null]; + var key = datastore.Key('Post', null); ds.save([ { key: key, data: post }, { key: key, data: post2 } ], function(err, keys) { assert.ifError(err); assert.equal(keys.length,2); - var firstKey = ['Post', keys[0][1]]; - var secondKey = ['Post', keys[1][1]]; + var firstKey = datastore.Key('Post', keys[0].path_[1]); + var secondKey = datastore.Key('Post', keys[1].path_[1]); ds.get([firstKey, secondKey], function(err, entities) { assert.ifError(err); assert.equal(entities.length, 2); @@ -121,14 +125,14 @@ describe('datastore', function() { describe('querying the datastore', function() { var keys = [ - ['Character', 'Rickard'], - ['Character', 'Rickard', 'Character', 'Eddard'], - ['Character', 'Catelyn'], - ['Character', 'Eddard', 'Character', 'Arya'], - ['Character', 'Eddard', 'Character', 'Sansa'], - ['Character', 'Eddard', 'Character', 'Robb'], - ['Character', 'Eddard', 'Character', 'Bran'], - ['Character', 'Eddard', 'Character', 'Jon Snow'] + datastore.Key('Character', 'Rickard'), + datastore.Key('Character', 'Rickard', 'Character', 'Eddard'), + datastore.Key('Character', 'Catelyn'), + datastore.Key('Character', 'Eddard', 'Character', 'Arya'), + datastore.Key('Character', 'Eddard', 'Character', 'Sansa'), + datastore.Key('Character', 'Eddard', 'Character', 'Robb'), + datastore.Key('Character', 'Eddard', 'Character', 'Bran'), + datastore.Key('Character', 'Eddard', 'Character', 'Jon Snow') ]; var characters = [{ @@ -227,7 +231,8 @@ describe('datastore', function() { }); it('should filter by ancestor', function(done) { - var q = ds.createQuery('Character').hasAncestor(['Character', 'Eddard']); + var q = ds.createQuery('Character') + .hasAncestor(datastore.Key('Character', 'Eddard')); ds.runQuery(q, function(err, entities) { assert.ifError(err); assert.equal(entities.length, 5); @@ -237,7 +242,7 @@ describe('datastore', function() { it('should filter by key', function(done) { var q = ds.createQuery('Character') - .filter('__key__ =', ['Character', 'Rickard']); + .filter('__key__ =', datastore.Key('Character', 'Rickard')); ds.runQuery(q, function(err, entities) { assert.ifError(err); assert.equal(entities.length, 1); @@ -332,7 +337,7 @@ describe('datastore', function() { describe('transactions', function() { it('should run in a transaction', function(done) { - var key = ['Company', 'Google']; + var key = datastore.Key('Company', 'Google'); var obj = { url: 'www.google.com' }; From cb165f3ed5b7c49dbe7c981bbb5309382c804369 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Thu, 7 Aug 2014 15:41:26 -0700 Subject: [PATCH 3/6] Fix lint error. --- regression/datastore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression/datastore.js b/regression/datastore.js index 2293f343ad8..e6372356f70 100644 --- a/regression/datastore.js +++ b/regression/datastore.js @@ -53,7 +53,7 @@ describe('datastore', function() { }); it('should save/get/delete with a numeric key id', function(done) { - var postKey = datastore.Key('Post', 123456789) + var postKey = datastore.Key('Post', 123456789); ds.save({ key: postKey, data: post From 71bfec7d9ece4708f32601ba1fa5de678cc82ac4 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Thu, 7 Aug 2014 15:47:07 -0700 Subject: [PATCH 4/6] Fixing README samples with Key type. --- README.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6aaabb6c49d..0a944eb879b 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,8 @@ If you're running this client on Google Compute Engine, you need to construct a ~~~~ js var gcloud = require('gcloud'), - ds = new gcloud.datastore.Dataset({ projectId: YOUR_PROJECT_ID }); + datastore = gcloud.datastore, + ds = new datastore.Dataset({ projectId: YOUR_PROJECT_ID }); ~~~~ Elsewhere, initiate with project ID and private key downloaded from Developer's Console. @@ -97,12 +98,12 @@ 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, entity) {}); +ds.get(datastore.Key('Company', 123), function(err, entity) {}); // alternatively, you can retrieve multiple entities at once. ds.get([ - ['Company', 123], - ['Product', 'Computer'] + datastore.Key('Company', 123), + datastore.Key('Product', 'Computer') ], function(err, entities) {}); ~~~~ @@ -111,14 +112,16 @@ You can insert arbitrary objects by providing an incomplete key during saving. I To learn more about keys and incomplete keys, skip to the Keys section. ~~~~ js -ds.save({ key: ['Company', null], data: {/*...*/} }, function(err, key) { +ds.save({ + key: datastore.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.save([ - { key: ['Company', 123], data: {/*...*/} }, - { key: ['Product', 'Computer'], data: {/*...*/} } + { key: datastore.Key('Company', 123), data: {/*...*/} }, + { key: datastore.Key('Product', 'Computer'), data: {/*...*/} } ], function(err, keys) { // if the first key was incomplete, keys[0] will return the generated key. }); @@ -132,10 +135,10 @@ ds.delete(['Company', 599900452312], function(err) {}); // alternatively, you can delete multiple entities of different // kinds at once. ds.delete([ - ['Company', 599900452312], - ['Company', 599900452315], - ['Office', 'mtv'], - ['Company', 123, 'Employee', 'jbd'] + datastore.Key('Company', 599900452312), + datastore.Key('Company', 599900452315), + datastore.Key('Office', 'mtv'), + datastore.Key('Company', 123, 'Employee', 'jbd') ], function(err) {}); ~~~~ @@ -174,13 +177,14 @@ stored as properties is not currently supported. ~~~~ js var q = ds.createQuery('Company') - .filter('__key__ =', ['Company', 'Google']) + .filter('__key__ =', datastore.Key('Company', 'Google')) ~~~~ In order to filter by ancestors, use `hasAncestor` helper. ~~~ js -var q = ds.createQuery('Child').hasAncestor(['Parent', 123]); +var q = ds.createQuery('Child') + .hasAncestor(datastore.Key('Parent', 123)); ~~~ ##### Sorting @@ -221,7 +225,7 @@ You can generate IDs without creating entities. The following call will create 100 new IDs from the Company kind which exists under the default namespace. ~~~~ js -ds.allocateIds(['Company', null], 100, function(err, keys) { +ds.allocateIds(datastore.Key('Company', null), 100, function(err, keys) { }); ~~~~ @@ -232,8 +236,8 @@ call below will create 100 new IDs, but from the Company kind that exists under the "ns-test" namespace. ~~~~ js -ds.allocateIds(['ns-test', 'Company', null], 100, function(err, keys) { - +var incompleteKey = datastore.Key('ns-test', 'Company', null); +ds.allocateIds(incompleteKey, 100, function(err, keys) { }); ~~~~ From 158aa9b27f070a6aa1004ce11368c98bb21bc187 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Thu, 7 Aug 2014 16:45:55 -0700 Subject: [PATCH 5/6] Remove unnecessary handling for array type --- lib/datastore/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/datastore/index.js b/lib/datastore/index.js index f985648ea91..e0831ff07f6 100644 --- a/lib/datastore/index.js +++ b/lib/datastore/index.js @@ -20,11 +20,8 @@ var entity = require('./entity'); module.exports = { Dataset: require('./dataset'), - Key: function(path) { + Key: function() { // TODO(jbd): Handle arguments in entity.Key constructor. - if (Array.isArray(path)) { - return new entity.Key(path); - } return new entity.Key([].slice.call(arguments)); }, Int: function(value) { From 53d4f5673774c5ac23bfb7b14be7cfe307f3f224 Mon Sep 17 00:00:00 2001 From: Burcu Dogan Date: Thu, 7 Aug 2014 17:53:21 -0700 Subject: [PATCH 6/6] Lowercase Key initializer. --- README.md | 28 ++++++++++++++-------------- lib/datastore/index.js | 2 +- regression/datastore.js | 38 +++++++++++++++++++------------------- test/datastore/dataset.js | 22 +++++++++++----------- test/datastore/entity.js | 26 +++++++++++++------------- 5 files changed, 58 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 0a944eb879b..dd8e96c3541 100644 --- a/README.md +++ b/README.md @@ -98,12 +98,12 @@ 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(datastore.Key('Company', 123), function(err, entity) {}); +ds.get(datastore.key('Company', 123), function(err, entity) {}); // alternatively, you can retrieve multiple entities at once. ds.get([ - datastore.Key('Company', 123), - datastore.Key('Product', 'Computer') + datastore.key('Company', 123), + datastore.key('Product', 'Computer') ], function(err, entities) {}); ~~~~ @@ -113,15 +113,15 @@ To learn more about keys and incomplete keys, skip to the Keys section. ~~~~ js ds.save({ - key: datastore.Key('Company', null), data: {/*...*/} + key: datastore.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.save([ - { key: datastore.Key('Company', 123), data: {/*...*/} }, - { key: datastore.Key('Product', 'Computer'), data: {/*...*/} } + { key: datastore.key('Company', 123), data: {/*...*/} }, + { key: datastore.key('Product', 'Computer'), data: {/*...*/} } ], function(err, keys) { // if the first key was incomplete, keys[0] will return the generated key. }); @@ -135,10 +135,10 @@ ds.delete(['Company', 599900452312], function(err) {}); // alternatively, you can delete multiple entities of different // kinds at once. ds.delete([ - datastore.Key('Company', 599900452312), - datastore.Key('Company', 599900452315), - datastore.Key('Office', 'mtv'), - datastore.Key('Company', 123, 'Employee', 'jbd') + datastore.key('Company', 599900452312), + datastore.key('Company', 599900452315), + datastore.key('Office', 'mtv'), + datastore.key('Company', 123, 'Employee', 'jbd') ], function(err) {}); ~~~~ @@ -177,14 +177,14 @@ stored as properties is not currently supported. ~~~~ js var q = ds.createQuery('Company') - .filter('__key__ =', datastore.Key('Company', 'Google')) + .filter('__key__ =', datastore.key('Company', 'Google')) ~~~~ In order to filter by ancestors, use `hasAncestor` helper. ~~~ js var q = ds.createQuery('Child') - .hasAncestor(datastore.Key('Parent', 123)); + .hasAncestor(datastore.key('Parent', 123)); ~~~ ##### Sorting @@ -225,7 +225,7 @@ You can generate IDs without creating entities. The following call will create 100 new IDs from the Company kind which exists under the default namespace. ~~~~ js -ds.allocateIds(datastore.Key('Company', null), 100, function(err, keys) { +ds.allocateIds(datastore.key('Company', null), 100, function(err, keys) { }); ~~~~ @@ -236,7 +236,7 @@ call below will create 100 new IDs, but from the Company kind that exists under the "ns-test" namespace. ~~~~ js -var incompleteKey = datastore.Key('ns-test', 'Company', null); +var incompleteKey = datastore.key('ns-test', 'Company', null); ds.allocateIds(incompleteKey, 100, function(err, keys) { }); ~~~~ diff --git a/lib/datastore/index.js b/lib/datastore/index.js index e0831ff07f6..f0bbf029b33 100644 --- a/lib/datastore/index.js +++ b/lib/datastore/index.js @@ -20,7 +20,7 @@ var entity = require('./entity'); module.exports = { Dataset: require('./dataset'), - Key: function() { + key: function() { // TODO(jbd): Handle arguments in entity.Key constructor. return new entity.Key([].slice.call(arguments)); }, diff --git a/regression/datastore.js b/regression/datastore.js index e6372356f70..23608fa931b 100644 --- a/regression/datastore.js +++ b/regression/datastore.js @@ -37,7 +37,7 @@ describe('datastore', function() { }; it('should save/get/delete with a key name', function(done) { - var postKey = datastore.Key('Post', 'post1'); + var postKey = datastore.key('Post', 'post1'); ds.save({ key: postKey, data: post }, function(err, key) { assert.ifError(err); assert.equal(key.path_[1], 'post1'); @@ -53,7 +53,7 @@ describe('datastore', function() { }); it('should save/get/delete with a numeric key id', function(done) { - var postKey = datastore.Key('Post', 123456789); + var postKey = datastore.key('Post', 123456789); ds.save({ key: postKey, data: post @@ -73,16 +73,16 @@ describe('datastore', function() { it('should save/get/delete with a generated key id', function(done) { ds.save({ - key: datastore.Key('Post', null), + key: datastore.key('Post', null), data: post }, function(err, key) { assert.ifError(err); var assignedId = key.path_[1]; assert(assignedId); - ds.get(datastore.Key('Post', assignedId), function(err, entity) { + ds.get(datastore.key('Post', assignedId), function(err, entity) { assert.ifError(err); assert.deepEqual(entity.data, post); - ds.delete(datastore.Key('Post', assignedId), function(err) { + ds.delete(datastore.key('Post', assignedId), function(err) { assert.ifError(err); done(); }); @@ -100,15 +100,15 @@ describe('datastore', function() { wordCount: 450, rating: 4.5, }; - var key = datastore.Key('Post', null); + var key = datastore.key('Post', null); ds.save([ { key: key, data: post }, { key: key, data: post2 } ], function(err, keys) { assert.ifError(err); assert.equal(keys.length,2); - var firstKey = datastore.Key('Post', keys[0].path_[1]); - var secondKey = datastore.Key('Post', keys[1].path_[1]); + var firstKey = datastore.key('Post', keys[0].path_[1]); + var secondKey = datastore.key('Post', keys[1].path_[1]); ds.get([firstKey, secondKey], function(err, entities) { assert.ifError(err); assert.equal(entities.length, 2); @@ -125,14 +125,14 @@ describe('datastore', function() { describe('querying the datastore', function() { var keys = [ - datastore.Key('Character', 'Rickard'), - datastore.Key('Character', 'Rickard', 'Character', 'Eddard'), - datastore.Key('Character', 'Catelyn'), - datastore.Key('Character', 'Eddard', 'Character', 'Arya'), - datastore.Key('Character', 'Eddard', 'Character', 'Sansa'), - datastore.Key('Character', 'Eddard', 'Character', 'Robb'), - datastore.Key('Character', 'Eddard', 'Character', 'Bran'), - datastore.Key('Character', 'Eddard', 'Character', 'Jon Snow') + datastore.key('Character', 'Rickard'), + datastore.key('Character', 'Rickard', 'Character', 'Eddard'), + datastore.key('Character', 'Catelyn'), + datastore.key('Character', 'Eddard', 'Character', 'Arya'), + datastore.key('Character', 'Eddard', 'Character', 'Sansa'), + datastore.key('Character', 'Eddard', 'Character', 'Robb'), + datastore.key('Character', 'Eddard', 'Character', 'Bran'), + datastore.key('Character', 'Eddard', 'Character', 'Jon Snow') ]; var characters = [{ @@ -232,7 +232,7 @@ describe('datastore', function() { it('should filter by ancestor', function(done) { var q = ds.createQuery('Character') - .hasAncestor(datastore.Key('Character', 'Eddard')); + .hasAncestor(datastore.key('Character', 'Eddard')); ds.runQuery(q, function(err, entities) { assert.ifError(err); assert.equal(entities.length, 5); @@ -242,7 +242,7 @@ describe('datastore', function() { it('should filter by key', function(done) { var q = ds.createQuery('Character') - .filter('__key__ =', datastore.Key('Character', 'Rickard')); + .filter('__key__ =', datastore.key('Character', 'Rickard')); ds.runQuery(q, function(err, entities) { assert.ifError(err); assert.equal(entities.length, 1); @@ -337,7 +337,7 @@ describe('datastore', function() { describe('transactions', function() { it('should run in a transaction', function(done) { - var key = datastore.Key('Company', 'Google'); + var key = datastore.key('Company', 'Google'); var obj = { url: 'www.google.com' }; diff --git a/test/datastore/dataset.js b/test/datastore/dataset.js index 7d577a3fb87..5b9681f365d 100644 --- a/test/datastore/dataset.js +++ b/test/datastore/dataset.js @@ -31,7 +31,7 @@ describe('Dataset', function() { assert.equal(proto.keys.length, 1); callback(null, mockRespGet); }; - ds.get(datastore.Key('Kind', 123), function(err, entity) { + ds.get(datastore.key('Kind', 123), function(err, entity) { var properties = entity.data; assert.deepEqual(entity.key.path_, ['Kind', 5732568548769792]); assert.strictEqual(properties.name, 'Burcu'); @@ -50,7 +50,7 @@ describe('Dataset', function() { assert.equal(proto.keys.length, 1); callback(null, mockRespGet); }; - var key = datastore.Key('Kind', 5732568548769792); + var key = datastore.key('Kind', 5732568548769792); ds.get([key], function(err, entities) { var entity = entities[0]; var properties = entity.data; @@ -71,7 +71,7 @@ describe('Dataset', function() { assert.equal(!!proto.mutation.delete, true); callback(); }; - ds.delete(datastore.Key('Kind', 123), done); + ds.delete(datastore.key('Kind', 123), done); }); it('should multi delete by keys', function(done) { @@ -82,8 +82,8 @@ describe('Dataset', function() { callback(); }; ds.delete([ - datastore.Key('Kind', 123), - datastore.Key('Kind', 345) + datastore.key('Kind', 123), + datastore.key('Kind', 345) ], done); }); @@ -94,7 +94,7 @@ describe('Dataset', function() { assert.equal(proto.mutation.insertAutoId.length, 1); callback(); }; - var key = datastore.Key('Kind', 123, null); + var key = datastore.key('Kind', 123, null); ds.save({ key: key, data: {} }, done); }); @@ -107,8 +107,8 @@ describe('Dataset', function() { callback(); }; ds.save([ - { key: datastore.Key('Kind', 123), data: { k: 'v' } }, - { key: datastore.Key('Kind', 456), data: { k: 'v' } } + { key: datastore.key('Kind', 123), data: { k: 'v' } }, + { key: datastore.key('Kind', 456), data: { k: 'v' } } ], done); }); @@ -129,8 +129,8 @@ describe('Dataset', function() { ] }); }; - ds.allocateIds(datastore.Key('Kind', null), 1, function(err, ids) { - assert.deepEqual(ids[0], datastore.Key('Kind', 123)); + ds.allocateIds(datastore.key('Kind', null), 1, function(err, ids) { + assert.deepEqual(ids[0], datastore.key('Kind', 123)); done(); }); }); @@ -138,7 +138,7 @@ describe('Dataset', function() { it('should throw if trying to allocate IDs with complete keys', function() { var ds = new datastore.Dataset({ projectId: 'test' }); assert.throws(function() { - ds.allocateIds(datastore.Key('Kind', 123)); + ds.allocateIds(datastore.key('Kind', 123)); }); }); diff --git a/test/datastore/entity.js b/test/datastore/entity.js index 0eff8413e49..17ddba34ba8 100644 --- a/test/datastore/entity.js +++ b/test/datastore/entity.js @@ -149,26 +149,26 @@ describe('keyFromKeyProto', function() { it('should handle keys hierarchically', function(done) { var key = entity.keyFromKeyProto(protoH); - assert.deepEqual(key, datastore.Key('Test', 'Kind', 111, 'Kind2', 'name')); + assert.deepEqual(key, datastore.key('Test', 'Kind', 111, 'Kind2', 'name')); done(); }); it('should handle incomplete keys hierarchically', function(done) { var key = entity.keyFromKeyProto(protoHIncomplete); - assert.deepEqual(key, datastore.Key('Test', 'Kind', null, 'Kind2', null)); + assert.deepEqual(key, datastore.key('Test', 'Kind', null, 'Kind2', null)); done(); }); it('should not set namespace if default', function(done) { var key = entity.keyFromKeyProto(proto); - assert.deepEqual(key, datastore.Key('Kind', 'Name')); + assert.deepEqual(key, datastore.key('Kind', 'Name')); done(); }); }); describe('keyToKeyProto', function() { it('should handle hierarchical key definitions', function(done) { - var key = datastore.Key('Kind1', 1, 'Kind2', 'name'); + var key = datastore.key('Kind1', 1, 'Kind2', 'name'); var proto = entity.keyToKeyProto(key); assert.strictEqual(proto.partitionId, undefined); assert.strictEqual(proto.path[0].kind, 'Kind1'); @@ -181,7 +181,7 @@ describe('keyToKeyProto', function() { }); it('should detect the namespace of the hierarchical keys', function(done) { - var key = datastore.Key('Namespace', 'Kind1', 1, 'Kind2', 'name'); + var key = datastore.key('Namespace', 'Kind1', 1, 'Kind2', 'name'); var proto = entity.keyToKeyProto(key); assert.strictEqual(proto.partitionId.namespace, 'Namespace'); assert.strictEqual(proto.path[0].kind, 'Kind1'); @@ -194,8 +194,8 @@ describe('keyToKeyProto', function() { }); it('should handle incomplete keys with & without namespaces', function(done) { - var key = datastore.Key('Kind1', null); - var keyWithNS = datastore.Key('Namespace', 'Kind1', null); + var key = datastore.key('Kind1', null); + var keyWithNS = datastore.key('Namespace', 'Kind1', null); var proto = entity.keyToKeyProto(key); var protoWithNS = entity.keyToKeyProto(keyWithNS); @@ -222,10 +222,10 @@ describe('keyToKeyProto', function() { describe('isKeyComplete', function() { it('should ret true if kind and an identifier have !0 vals', function(done) { [ - { key: datastore.Key('Kind1', null), expected: false }, - { key: datastore.Key('Kind1', 3), expected: true }, - { key: datastore.Key('Namespace', 'Kind1', null), expected: false }, - { key: datastore.Key('Namespace', 'Kind1', 'name'), expected: true } + { key: datastore.key('Kind1', null), expected: false }, + { key: datastore.key('Kind1', 3), expected: true }, + { key: datastore.key('Namespace', 'Kind1', null), expected: false }, + { key: datastore.key('Namespace', 'Kind1', 'name'), expected: true } ].forEach(function(test) { assert.strictEqual(entity.isKeyComplete(test.key), test.expected); }); @@ -239,7 +239,7 @@ describe('entityFromEntityProto', function() { var obj = entity.entityFromEntityProto(entityProto); assert.strictEqual( obj.createdAt.getTime(), new Date('2001-01-01').getTime()); - assert.deepEqual(obj.linkedTo, datastore.Key('Kind', 4790047639339008)); + assert.deepEqual(obj.linkedTo, datastore.key('Kind', 4790047639339008)); assert.strictEqual(obj.name, 'Name'); assert.strictEqual(obj.flagged, true); assert.strictEqual(obj.count, 5); @@ -294,7 +294,7 @@ describe('queryToQueryProto', function() { var ds = new datastore.Dataset({ projectId: 'project-id' }); var q = ds.createQuery('Kind1') .filter('name =', 'John') - .hasAncestor(datastore.Key('Kind2', 'somename')); + .hasAncestor(datastore.key('Kind2', 'somename')); var proto = entity.queryToQueryProto(q); assert.deepEqual(proto, queryFilterProto); done();