Skip to content

Commit 9d63eea

Browse files
committed
Merge pull request #1202 from stephenplusplus/master
datastore: fix runQuery end logic
2 parents d0b530b + 053a0f2 commit 9d63eea

2 files changed

Lines changed: 61 additions & 9 deletions

File tree

lib/datastore/request.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,17 +442,19 @@ DatastoreRequest.prototype.runQuery = function(query, callback) {
442442
};
443443
}
444444

445+
var originalLimitVal = query.limitVal;
446+
var entities = [];
447+
445448
function onResponse(err, resp) {
446449
if (err) {
447450
callback(err, null, null, resp);
448451
return;
449452
}
450453

451-
var entities = [];
452454
var nextQuery = null;
453455

454456
if (resp.batch.entityResults) {
455-
entities = entity.formatArray(resp.batch.entityResults);
457+
entities = entities.concat(entity.formatArray(resp.batch.entityResults));
456458
}
457459

458460
var notFinished = resp.batch.moreResults === 'NOT_FINISHED';
@@ -469,11 +471,22 @@ DatastoreRequest.prototype.runQuery = function(query, callback) {
469471
if (notFinished) {
470472
// Run the query again to make sure all of the requested entities are
471473
// returned.
474+
var limit = reqOpts.query.limit.value;
475+
if (limit > -1) {
476+
// Update the limit on the nextQuery to return only the amount of
477+
// results originally asked for.
478+
nextQuery.limit(limit - resp.batch.entityResults.length);
479+
}
472480
reqOpts.query = entity.queryToQueryProto(nextQuery);
473481
self.request_(protoOpts, reqOpts, onResponse);
474482
return;
475483
}
476484

485+
if (nextQuery && originalLimitVal > -1) {
486+
// Restore the original limit value for the query.
487+
nextQuery.limit(originalLimitVal);
488+
}
489+
477490
callback(null, entities, nextQuery, resp);
478491
}
479492

test/datastore/request.js

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -565,44 +565,62 @@ describe('Request', function() {
565565

566566
request.runQuery({}, function(err, entities) {
567567
assert.ifError(err);
568-
assert.strictEqual(entities, entityResults);
568+
assert.deepEqual(entities, entityResults);
569569
done();
570570
});
571571
});
572572

573573
it('should re-run query if not finished', function(done) {
574-
entityOverrides.formatArray = util.noop;
575-
574+
var entityResults = {
575+
1: ['a'],
576+
2: ['b', 'c']
577+
};
576578
var nextQuery;
577-
var queryProto = {};
578579
var query = {
580+
limitVal: 1,
579581
offsetVal: 8
580582
};
583+
var queryProto = {
584+
limit: {
585+
value: query.limitVal
586+
}
587+
};
581588

582589
var timesRequestCalled = 0;
583590
var startCalled = false;
584591
var offsetCalled = false;
585592

593+
entityOverrides.formatArray = function(array) {
594+
assert.strictEqual(array, entityResults[timesRequestCalled]);
595+
return entityResults[timesRequestCalled];
596+
};
597+
586598
request.request_ = function(protoOpts, reqOpts, callback) {
587599
timesRequestCalled++;
588600

601+
var resp = extend(true, {}, apiResponse);
602+
resp.batch.entityResults = entityResults[timesRequestCalled];
603+
589604
if (timesRequestCalled === 1) {
590605
assert.strictEqual(protoOpts.service, 'Datastore');
591606
assert.strictEqual(protoOpts.method, 'runQuery');
592607

593-
var resp = extend(true, {}, apiResponse);
594608
resp.batch.moreResults = 'NOT_FINISHED';
595609

596610
callback(null, resp);
597611
} else {
598612
assert.strictEqual(startCalled, true);
599613
assert.strictEqual(offsetCalled, true);
600614
assert.strictEqual(reqOpts.query, queryProto);
601-
done();
615+
616+
resp.batch.moreResults = 'MORE_RESULTS_AFTER_LIMIT';
617+
618+
callback(null, resp);
602619
}
603620
};
604621

605622
FakeQuery.prototype.start = function(endCursor_) {
623+
nextQuery = this;
606624
assert.strictEqual(endCursor_, endCursor);
607625
startCalled = true;
608626
return this;
@@ -615,14 +633,35 @@ describe('Request', function() {
615633
return this;
616634
};
617635

636+
FakeQuery.prototype.limit = function(limit_) {
637+
if (timesRequestCalled === 1) {
638+
assert.strictEqual(
639+
limit_,
640+
entityResults[1].length - query.limitVal
641+
);
642+
} else {
643+
// Should restore the original limit.
644+
assert.strictEqual(limit_, query.limitVal);
645+
}
646+
return this;
647+
};
648+
618649
entityOverrides.queryToQueryProto = function(query_) {
619650
if (timesRequestCalled > 1) {
620651
assert.strictEqual(query_, nextQuery);
621652
}
622653
return queryProto;
623654
};
624655

625-
request.runQuery(query, assert.ifError);
656+
request.runQuery(query, function(err, entities, nextQuery_) {
657+
assert.ifError(err);
658+
assert.deepEqual(
659+
entities,
660+
[].slice.call(entityResults[1]).concat(entityResults[2])
661+
);
662+
assert.strictEqual(nextQuery_, nextQuery);
663+
done();
664+
});
626665
});
627666

628667
it('should return nextQuery', function(done) {

0 commit comments

Comments
 (0)