From 789e970836d4a49785ed2223443adb03feb45a47 Mon Sep 17 00:00:00 2001 From: Stephen Sawchuk Date: Mon, 10 Oct 2016 15:22:07 -0400 Subject: [PATCH] datastore: use a Symbol to get the key from an entity --- packages/datastore/src/entity.js | 14 ++++-- packages/datastore/src/index.js | 7 +++ packages/datastore/src/query.js | 7 +-- packages/datastore/src/request.js | 7 +-- packages/datastore/system-test/datastore.js | 47 +++++++++++---------- packages/datastore/test/entity.js | 18 +++++--- packages/datastore/test/index.js | 11 +++++ 7 files changed, 71 insertions(+), 40 deletions(-) diff --git a/packages/datastore/src/entity.js b/packages/datastore/src/entity.js index 2e38cb6675e..ee9ae89f150 100644 --- a/packages/datastore/src/entity.js +++ b/packages/datastore/src/entity.js @@ -37,6 +37,13 @@ var InvalidKeyError = createErrorClass('InvalidKey', function(opts) { this.message = errorMessages[opts.code]; }); +/** + * A symbol to access the Key object from an entity object. + * + * @type {symbol} + */ +entity.KEY_SYMBOL = Symbol('KEY'); + /** * Build a Datastore Double object. * @@ -405,10 +412,9 @@ entity.entityToEntityProto = entityToEntityProto; */ function formatArray(results) { return results.map(function(result) { - return { - key: entity.keyFromKeyProto(result.entity.key), - data: entity.entityFromEntityProto(result.entity) - }; + var ent = entity.entityFromEntityProto(result.entity); + ent[entity.KEY_SYMBOL] = entity.keyFromKeyProto(result.entity.key); + return ent; }); } diff --git a/packages/datastore/src/index.js b/packages/datastore/src/index.js index 4e1a66b428d..039a705e80e 100644 --- a/packages/datastore/src/index.js +++ b/packages/datastore/src/index.js @@ -378,6 +378,13 @@ Datastore.prototype.int = Datastore.int = function(value) { return new entity.Int(value); }; +/** + * Access the Key from an Entity object. + * + * @type {symbol} + */ +Datastore.prototype.KEY = Datastore.KEY = entity.KEY_SYMBOL; + /** * This is one of three values which may be returned from * {module:datastore#runQuery}, {module:transaction#runQuery}, and diff --git a/packages/datastore/src/query.js b/packages/datastore/src/query.js index 7b3f89529e5..617b29fdb31 100644 --- a/packages/datastore/src/query.js +++ b/packages/datastore/src/query.js @@ -312,7 +312,7 @@ Query.prototype.offset = function(n) { * // unnecessary processing and API requests. * //- * query.run() - * .on('data', function (entity) { + * .on('data', function(entity) { * this.end(); * }); * @@ -323,8 +323,9 @@ Query.prototype.offset = function(n) { * query.select('__key__'); * * query.run(function(err, entities) { - * // entities[].key = Key object - * // entities[].data = Empty object + * var keys = entities.map(function(entity) { + * return entity[datastore.KEY]; + * }); * }); */ Query.prototype.run = function() { diff --git a/packages/datastore/src/request.js b/packages/datastore/src/request.js index 2b56a0f708b..e1be17484fc 100644 --- a/packages/datastore/src/request.js +++ b/packages/datastore/src/request.js @@ -299,7 +299,7 @@ DatastoreRequest.prototype.delete = function(keys, callback) { * // Error handling omitted. * } * - * entity.data.newValue = true; + * entity.newValue = true; * datastore.save(entity, function(err) {}); * }); */ @@ -489,8 +489,9 @@ DatastoreRequest.prototype.insert = function(entities, callback) { * var keysOnlyQuery = datastore.createQuery('Lion').select('__key__'); * * datastore.runQuery(keysOnlyQuery, function(err, entities) { - * // entities[].key = Key object - * // entities[].data = Empty object + * var keys = entities.map(function(entity) { + * return entity[datastore.KEY]; + * }); * }); */ DatastoreRequest.prototype.runQuery = function(query, options, callback) { diff --git a/packages/datastore/system-test/datastore.js b/packages/datastore/system-test/datastore.js index cf10a910dcd..9e56a329679 100644 --- a/packages/datastore/system-test/datastore.js +++ b/packages/datastore/system-test/datastore.js @@ -48,7 +48,7 @@ describe('Datastore', function() { } var keys = entities.map(function(entity) { - return entity.key; + return entity[datastore.KEY]; }); datastore.delete(keys, callback); @@ -91,7 +91,8 @@ describe('Datastore', function() { datastore.get(postKey, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data, post); + assert.deepEqual(entity, post); + assert.deepEqual(entity[datastore.KEY], postKey); datastore.delete(postKey, done); }); @@ -107,7 +108,7 @@ describe('Datastore', function() { datastore.get(postKey, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data, post); + assert.deepEqual(entity, post); datastore.delete(postKey, done); }); @@ -129,7 +130,7 @@ describe('Datastore', function() { datastore.get(postKey, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data, data); + assert.deepEqual(entity, data); datastore.delete(datastore.key(['Post', assignedId]), done); }); @@ -148,7 +149,7 @@ describe('Datastore', function() { datastore.get(postKey, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data, post); + assert.deepEqual(entity, post); datastore.delete(postKey, done); }); @@ -174,7 +175,7 @@ describe('Datastore', function() { datastore.get(postKey, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data, post); + assert.deepEqual(entity, post); datastore.delete(postKey, done); }); @@ -268,8 +269,8 @@ describe('Datastore', function() { datastore.runQuery(query, function(err, results) { assert.ifError(err); - assert.strictEqual(results[0].data.fullName, 'Full name'); - assert.deepEqual(results[0].data.linkedTo, personKey); + assert.strictEqual(results[0].fullName, 'Full name'); + assert.deepEqual(results[0].linkedTo, personKey); datastore.delete(personKey, done); }); @@ -293,7 +294,7 @@ describe('Datastore', function() { datastore.get(key, function(err, entity) { assert.ifError(err); - assert.strictEqual(entity.data.year, integerValue); + assert.strictEqual(entity.year, integerValue); done(); }); }); @@ -315,7 +316,7 @@ describe('Datastore', function() { datastore.get(key, function(err, entity) { assert.ifError(err); - assert.strictEqual(entity.data.nines, doubleValue); + assert.strictEqual(entity.nines, doubleValue); done(); }); }); @@ -340,7 +341,7 @@ describe('Datastore', function() { datastore.get(key, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data.location, geoPointValue); + assert.deepEqual(entity.location, geoPointValue); done(); }); }); @@ -553,8 +554,8 @@ describe('Datastore', function() { datastore.runQuery(q, function(err, entities) { assert.ifError(err); - assert.strictEqual(entities[0].data.name, characters[0].name); - assert.strictEqual(entities[7].data.name, characters[3].name); + assert.strictEqual(entities[0].name, characters[0].name); + assert.strictEqual(entities[7].name, characters[3].name); done(); }); @@ -568,12 +569,12 @@ describe('Datastore', function() { datastore.runQuery(q, function(err, entities) { assert.ifError(err); - assert.deepEqual(entities[0].data, { + assert.deepEqual(entities[0], { name: 'Arya', family: 'Stark' }); - assert.deepEqual(entities[8].data, { + assert.deepEqual(entities[8], { name: 'Sansa', family: 'Stark' }); @@ -593,8 +594,8 @@ describe('Datastore', function() { assert.ifError(err); assert.strictEqual(entities.length, 3); - assert.strictEqual(entities[0].data.name, 'Robb'); - assert.strictEqual(entities[2].data.name, 'Catelyn'); + assert.strictEqual(entities[0].name, 'Robb'); + assert.strictEqual(entities[2].name, 'Catelyn'); var secondQ = datastore.createQuery('Character') .hasAncestor(ancestor) @@ -605,8 +606,8 @@ describe('Datastore', function() { assert.ifError(err); assert.strictEqual(secondEntities.length, 3); - assert.strictEqual(secondEntities[0].data.name, 'Sansa'); - assert.strictEqual(secondEntities[2].data.name, 'Arya'); + assert.strictEqual(secondEntities[0].name, 'Sansa'); + assert.strictEqual(secondEntities[2].name, 'Arya'); done(); }); @@ -632,8 +633,8 @@ describe('Datastore', function() { assert.ifError(err); assert.strictEqual(secondEntities.length, 4); - assert.strictEqual(secondEntities[0].data.name, 'Catelyn'); - assert.strictEqual(secondEntities[3].data.name, 'Arya'); + assert.strictEqual(secondEntities[0].name, 'Catelyn'); + assert.strictEqual(secondEntities[3].name, 'Arya'); done(); }); @@ -681,7 +682,7 @@ describe('Datastore', function() { datastore.get(key, function(err, entity) { assert.ifError(err); - assert.deepEqual(entity.data, obj); + assert.deepEqual(entity, obj); done(); }); }); @@ -738,7 +739,7 @@ describe('Datastore', function() { function(callback) { datastore.get(key, function(err, entity) { assert.ifError(err); - assert.strictEqual(entity.data.rating, 10); + assert.strictEqual(entity.rating, 10); callback(); }); } diff --git a/packages/datastore/test/entity.js b/packages/datastore/test/entity.js index c357ba37240..a97ace5433f 100644 --- a/packages/datastore/test/entity.js +++ b/packages/datastore/test/entity.js @@ -33,6 +33,12 @@ describe('entity', function() { entity = require('../src/entity.js'); }); + describe('KEY_SYMBOL', function() { + it('should export the symbol', function() { + assert.strictEqual(entity.KEY_SYMBOL.toString(), 'Symbol(KEY)'); + }); + }); + describe('Double', function() { it('should store the value', function() { var value = 8.3; @@ -532,12 +538,7 @@ describe('entity', function() { } ]; - var expectedResults = [ - { - key: key, - data: entityProto - } - ]; + var expectedResults = entityProto; entity.keyFromKeyProto = function(key_) { assert.strictEqual(key_, key); @@ -549,7 +550,10 @@ describe('entity', function() { return entityProto; }; - assert.deepEqual(entity.formatArray(results), expectedResults); + var ent = entity.formatArray(results)[0]; + + assert.deepEqual(ent, expectedResults); + assert.strictEqual(ent[entity.KEY_SYMBOL], key); }); }); diff --git a/packages/datastore/test/index.js b/packages/datastore/test/index.js index ad7161ecf32..81f74849cb2 100644 --- a/packages/datastore/test/index.js +++ b/packages/datastore/test/index.js @@ -22,6 +22,7 @@ var proxyquire = require('proxyquire'); var util = require('@google-cloud/common').util; var fakeEntity = { + KEY_SYMBOL: Symbol('fake key symbol'), Int: function(value) { this.value = value; }, @@ -198,6 +199,16 @@ describe('Datastore', function() { }); }); + describe('KEY', function() { + it('should expose the KEY symbol', function() { + assert.strictEqual(Datastore.KEY, fakeEntity.KEY_SYMBOL); + }); + + it('should also be on the prototype', function() { + assert.strictEqual(datastore.KEY, Datastore.KEY); + }); + }); + describe('MORE_RESULTS_AFTER_CURSOR', function() { it('should expose a MORE_RESULTS_AFTER_CURSOR helper', function() { assert.strictEqual(