Skip to content

Commit e78c07e

Browse files
authored
Fix read preference for aggregate (#6585)
* added failing test cases * fixed test cases for aggregate query * added read preference option to aggregate router
1 parent 288e746 commit e78c07e

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

spec/ReadPreferenceOption.spec.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,86 @@ describe_only_db('mongo')('Read preference option', () => {
796796
});
797797
});
798798

799+
it('should change read preference for `aggregate` using `beforeFind`', async() => {
800+
// Save objects
801+
const obj0 = new Parse.Object('MyObject');
802+
obj0.set('boolKey', false);
803+
const obj1 = new Parse.Object('MyObject');
804+
obj1.set('boolKey', true);
805+
await Parse.Object.saveAll([obj0, obj1]);
806+
// Add trigger
807+
Parse.Cloud.beforeFind('MyObject', req => {
808+
req.readPreference = 'SECONDARY';
809+
});
810+
// Spy on DB adapter
811+
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
812+
spyOn(databaseAdapter.database.serverConfig, 'startSession').and.callThrough();
813+
// Query
814+
const query = new Parse.Query('MyObject');
815+
const results = await query.aggregate([{match:{boolKey: false}}]);
816+
// Validate
817+
expect(results.length).toBe(1);
818+
let readPreference = null;
819+
databaseAdapter.database.serverConfig.startSession.calls.all().forEach(call => {
820+
if (call.args[0].owner.ns.indexOf('MyObject') > -1) {
821+
readPreference = call.args[0].owner.operation.readPreference.mode;
822+
}
823+
});
824+
expect(readPreference).toEqual(ReadPreference.SECONDARY);
825+
});
826+
827+
it('should change read preference for `find` using query option', async() => {
828+
// Save objects
829+
const obj0 = new Parse.Object('MyObject');
830+
obj0.set('boolKey', false);
831+
const obj1 = new Parse.Object('MyObject');
832+
obj1.set('boolKey', true);
833+
await Parse.Object.saveAll([obj0, obj1]);
834+
// Spy on DB adapter
835+
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
836+
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
837+
// Query
838+
const query = new Parse.Query('MyObject');
839+
query.equalTo('boolKey', false);
840+
query.readPreference('SECONDARY');
841+
const results = await query.find();
842+
// Validate
843+
expect(results.length).toBe(1);
844+
let myObjectReadPreference = null;
845+
databaseAdapter.database.serverConfig.cursor.calls.all().forEach(call => {
846+
if (call.args[0].ns.collection.indexOf('MyObject') >= 0) {
847+
myObjectReadPreference =
848+
call.args[0].options.readPreference.mode;
849+
}
850+
});
851+
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
852+
});
853+
854+
it('should change read preference for `aggregate` using query option', async() => {
855+
// Save objects
856+
const obj0 = new Parse.Object('MyObject');
857+
obj0.set('boolKey', false);
858+
const obj1 = new Parse.Object('MyObject');
859+
obj1.set('boolKey', true);
860+
await Parse.Object.saveAll([obj0, obj1]);
861+
// Spy on DB adapter
862+
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
863+
spyOn(databaseAdapter.database.serverConfig, 'startSession').and.callThrough();
864+
// Query
865+
const query = new Parse.Query('MyObject');
866+
query.readPreference('SECONDARY');
867+
const results = await query.aggregate([{match:{boolKey: false}}]);
868+
// Validate
869+
expect(results.length).toBe(1);
870+
let readPreference = null;
871+
databaseAdapter.database.serverConfig.startSession.calls.all().forEach(call => {
872+
if (call.args[0].owner.ns.indexOf('MyObject') > -1) {
873+
readPreference = call.args[0].owner.operation.readPreference.mode;
874+
}
875+
});
876+
expect(readPreference).toEqual(ReadPreference.SECONDARY);
877+
});
878+
799879
it('should find includes in same replica of readPreference by default', done => {
800880
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
801881

src/Routers/AggregateRouter.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ export class AggregateRouter extends ClassesRouter {
5454
options.explain = body.explain;
5555
delete body.explain;
5656
}
57+
if (body.readPreference) {
58+
options.readPreference = body.readPreference;
59+
delete body.readPreference;
60+
}
5761
options.pipeline = AggregateRouter.getPipeline(body);
5862
if (typeof body.where === 'string') {
5963
body.where = JSON.parse(body.where);

0 commit comments

Comments
 (0)