diff --git a/lib/datastore/request.js b/lib/datastore/request.js index 7580ef958f3..82b907ffadc 100644 --- a/lib/datastore/request.js +++ b/lib/datastore/request.js @@ -308,15 +308,15 @@ DatastoreRequest.prototype.delete = function(keys, callback) { * //- * * // Retrieve 5 companies. - * transaction.runQuery(queryObject, function(err, entities, nextQuery) { - * // `nextQuery` is not null if there are more results. - * if (nextQuery) { - * transaction.runQuery(nextQuery, function(err, entities, nextQuery) {}); - * } + * transaction.runQuery(queryObject, function(err, entities, endCursor) { + * // Use `endCursor` as the starting cursor for your next query. + * var nextQuery = queryObject.start(endCursor); + * transaction.runQuery(nextQuery, function(err, entities, endCursor) {}); * }); */ DatastoreRequest.prototype.runQuery = function(q, callback) { callback = callback || util.noop; + var req = { read_options: {}, query: entity.queryToQueryProto(q) @@ -333,14 +333,13 @@ DatastoreRequest.prototype.runQuery = function(q, callback) { callback(err); return; } - var nextQuery = null; + + var cursor = ''; if (resp.batch.end_cursor) { - var cursor = resp.batch.end_cursor.toBase64(); - if (cursor !== q.startVal) { - nextQuery = q.start(cursor).offset(0); - } + cursor = resp.batch.end_cursor.toBase64(); } - callback(null, entity.formatArray(resp.batch.entity_result), nextQuery); + + callback(null, entity.formatArray(resp.batch.entity_result), cursor); }); }; diff --git a/regression/datastore.js b/regression/datastore.js index 9c7920c9798..056c3c89420 100644 --- a/regression/datastore.js +++ b/regression/datastore.js @@ -231,19 +231,17 @@ describe('datastore', function() { it('should limit queries', function(done) { var q = ds.createQuery('Character').hasAncestor(ancestor) .limit(5); - ds.runQuery(q, function(err, firstEntities, secondQuery) { + ds.runQuery(q, function(err, firstEntities, firstEndCursor) { assert.ifError(err); assert.equal(firstEntities.length, 5); - assert(secondQuery); - ds.runQuery(secondQuery, function(err, secondEntities, thirdQuery) { + var secondQ = q.start(firstEndCursor); + ds.runQuery(secondQ, function(err, secondEntities, secondEndCursor) { assert.ifError(err); assert.equal(secondEntities.length, 3); - // TODO(silvano): it currently requires an additional request that - // brings an empty page and a null query - //assert.equal(thirdQuery, null) - ds.runQuery(thirdQuery, function(err, thirdEntities, fourthQuery) { + var thirdQ = q.start(secondEndCursor); + ds.runQuery(thirdQ, function(err, thirdEntities) { assert.ifError(err); - assert.equal(fourthQuery, null); + assert.equal(thirdEntities.length, 0); done(); }); }); @@ -324,11 +322,12 @@ describe('datastore', function() { .offset(2) .limit(3) .order('appearances'); - ds.runQuery(q, function(err, entities, secondQuery) { + ds.runQuery(q, function(err, entities, endCursor) { assert.ifError(err); assert.equal(entities.length, 3); assert.equal(entities[0].data.name, 'Robb'); assert.equal(entities[2].data.name, 'Catelyn'); + var secondQuery = q.start(endCursor).offset(0); ds.runQuery(secondQuery, function(err, secondEntities) { assert.equal(secondEntities.length, 3); assert.equal(secondEntities[0].data.name, 'Sansa'); @@ -343,13 +342,12 @@ describe('datastore', function() { .offset(2) .limit(2) .order('appearances'); - ds.runQuery(q, function(err, entities, nextQuery) { + ds.runQuery(q, function(err, entities, endCursor) { assert.ifError(err); - var startCursor = nextQuery.startVal; var cursorQuery = ds.createQuery('Character').hasAncestor(ancestor) .order('appearances') - .start(startCursor); + .start(endCursor); ds.runQuery(cursorQuery, function(err, secondEntities) { assert.ifError(err); assert.equal(secondEntities.length, 4); diff --git a/test/datastore/request.js b/test/datastore/request.js index 9841b60b76b..66ee13ff460 100644 --- a/test/datastore/request.js +++ b/test/datastore/request.js @@ -329,15 +329,29 @@ describe('Request', function() { }); }); - it('should return a new query if results remain', function() { + it('should return an empty string if no end cursor exists', function(done) { request.makeReq_ = function(method, req, callback) { - assert.equal(method, 'runQuery'); - callback(null, mockResponse.withResultsAndEndCursor); + callback(null, mockResponse.withResults); + }; + + request.runQuery(query, function(err, entities, endCursor) { + assert.ifError(err); + assert.strictEqual(endCursor, ''); + done(); + }); + }); + + it('should return the end cursor from the last query', function(done) { + var response = mockResponse.withResultsAndEndCursor; + + request.makeReq_ = function(method, req, callback) { + callback(null, response); }; - request.runQuery(query, function(err, entities, nextQuery) { + request.runQuery(query, function(err, entities, endCursor) { assert.ifError(err); - assert.equal(nextQuery.constructor.name, 'Query'); + assert.equal(endCursor, response.batch.end_cursor.toBase64()); + done(); }); }); });