Futzing with read preference (#3963)
* allow setting readpreference when using rest api. * take out partially complete unit test. * oops. nit * Include read preference option for find directly from api and adding few more tests * Adding catch for all tests * Keep same check for get and find * Turn read preference case insensitive * Includes and subqueries read preferences through API * Fixing bugs regarding changes that were done in master branch during the last year * Changing behavior to make includeReadPreference and subqueryReadPreference to follow readPreference by default
This commit is contained in:
committed by
GitHub
parent
893f1d376e
commit
afa74d655d
@@ -41,16 +41,12 @@ describe('GridFSBucket and GridStore interop', () => {
|
|||||||
expect(gfsResult.toString('utf8')).toBe(twoMegabytesFile);
|
expect(gfsResult.toString('utf8')).toBe(twoMegabytesFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('properly deletes a file from GridFS', async () => {
|
||||||
'properly deletes a file from GridFS',
|
|
||||||
async () => {
|
|
||||||
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
|
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
|
||||||
await gfsAdapter.createFile('myFileName', 'a simple file');
|
await gfsAdapter.createFile('myFileName', 'a simple file');
|
||||||
await gfsAdapter.deleteFile('myFileName');
|
await gfsAdapter.deleteFile('myFileName');
|
||||||
await expectMissingFile(gfsAdapter, 'myFileName');
|
await expectMissingFile(gfsAdapter, 'myFileName');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it('properly overrides files', async () => {
|
it('properly overrides files', async () => {
|
||||||
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
|
const gfsAdapter = new GridFSBucketAdapter(databaseURI);
|
||||||
|
|||||||
@@ -108,7 +108,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -124,8 +126,50 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should check read preference as case insensitive', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
Parse.Cloud.beforeFind('MyObject', req => {
|
||||||
|
req.readPreference = 'sEcOnDarY';
|
||||||
|
});
|
||||||
|
|
||||||
|
const query = new Parse.Query('MyObject');
|
||||||
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
|
expect(results.length).toBe(1);
|
||||||
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
|
let myObjectReadPreference = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject') >= 0) {
|
||||||
|
myObjectReadPreference = call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change read preference in the beforeFind trigger even changing query', done => {
|
it('should change read preference in the beforeFind trigger even changing query', done => {
|
||||||
@@ -147,7 +191,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(true);
|
expect(results[0].get('boolKey')).toBe(true);
|
||||||
|
|
||||||
@@ -163,7 +209,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -189,7 +236,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(true);
|
expect(results[0].get('boolKey')).toBe(true);
|
||||||
|
|
||||||
@@ -205,7 +254,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -231,7 +281,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(true);
|
expect(results[0].get('boolKey')).toBe(true);
|
||||||
|
|
||||||
@@ -247,7 +299,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -269,7 +322,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -287,7 +342,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -309,7 +365,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -327,7 +385,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -349,7 +408,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -365,7 +426,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.NEAREST);
|
expect(myObjectReadPreference).toEqual(ReadPreference.NEAREST);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -386,7 +448,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
|
|
||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
|
|
||||||
query.get(obj0.id).then(result => {
|
query
|
||||||
|
.get(obj0.id)
|
||||||
|
.then(result => {
|
||||||
expect(result.get('boolKey')).toBe(false);
|
expect(result.get('boolKey')).toBe(false);
|
||||||
|
|
||||||
let myObjectReadPreference = null;
|
let myObjectReadPreference = null;
|
||||||
@@ -401,7 +465,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -428,7 +493,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
'X-Parse-REST-API-Key': 'rest',
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
},
|
},
|
||||||
json: true,
|
json: true,
|
||||||
}).then(response => {
|
})
|
||||||
|
.then(response => {
|
||||||
const body = response.data;
|
const body = response.data;
|
||||||
expect(body.boolKey).toBe(false);
|
expect(body.boolKey).toBe(false);
|
||||||
|
|
||||||
@@ -444,8 +510,233 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should change read preference for GET directly from API', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject/' +
|
||||||
|
obj0.id +
|
||||||
|
'?readPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.boolKey).toBe(false);
|
||||||
|
|
||||||
|
let myObjectReadPreference = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject') >= 0) {
|
||||||
|
myObjectReadPreference = call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change read preference for GET using API through the beforeFind overriding API option', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
Parse.Cloud.beforeFind('MyObject', req => {
|
||||||
|
req.readPreference = 'SECONDARY_PREFERRED';
|
||||||
|
});
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject/' +
|
||||||
|
obj0.id +
|
||||||
|
'?readPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.boolKey).toBe(false);
|
||||||
|
|
||||||
|
let myObjectReadPreference = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject') >= 0) {
|
||||||
|
myObjectReadPreference = call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference).toEqual(
|
||||||
|
ReadPreference.SECONDARY_PREFERRED
|
||||||
|
);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change read preference for FIND using API through beforeFind trigger', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
Parse.Cloud.beforeFind('MyObject', req => {
|
||||||
|
req.readPreference = 'SECONDARY';
|
||||||
|
});
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url: 'http://localhost:8378/1/classes/MyObject/',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.results.length).toEqual(2);
|
||||||
|
|
||||||
|
let myObjectReadPreference = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject') >= 0) {
|
||||||
|
myObjectReadPreference = call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change read preference for FIND directly from API', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject?readPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.results.length).toEqual(2);
|
||||||
|
|
||||||
|
let myObjectReadPreference = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject') >= 0) {
|
||||||
|
myObjectReadPreference = call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change read preference for FIND using API through the beforeFind overriding API option', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
Parse.Cloud.beforeFind('MyObject', req => {
|
||||||
|
req.readPreference = 'SECONDARY_PREFERRED';
|
||||||
|
});
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject/?readPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.results.length).toEqual(2);
|
||||||
|
|
||||||
|
let myObjectReadPreference = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject') >= 0) {
|
||||||
|
myObjectReadPreference = call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference).toEqual(
|
||||||
|
ReadPreference.SECONDARY_PREFERRED
|
||||||
|
);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change read preference for count', done => {
|
it('should change read preference for count', done => {
|
||||||
@@ -466,7 +757,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query = new Parse.Query('MyObject');
|
const query = new Parse.Query('MyObject');
|
||||||
query.equalTo('boolKey', false);
|
query.equalTo('boolKey', false);
|
||||||
|
|
||||||
query.count().then(result => {
|
query
|
||||||
|
.count()
|
||||||
|
.then(result => {
|
||||||
expect(result).toBe(1);
|
expect(result).toBe(1);
|
||||||
|
|
||||||
let myObjectReadPreference = null;
|
let myObjectReadPreference = null;
|
||||||
@@ -481,11 +774,12 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find includes in primary by default', done => {
|
it('should find includes in same replica of readPreference by default', done => {
|
||||||
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
const obj0 = new Parse.Object('MyObject0');
|
const obj0 = new Parse.Object('MyObject0');
|
||||||
@@ -509,7 +803,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
query.include('myObject1');
|
query.include('myObject1');
|
||||||
query.include('myObject1.myObject0');
|
query.include('myObject1.myObject0');
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
const firstResult = results[0];
|
const firstResult = results[0];
|
||||||
expect(firstResult.get('boolKey')).toBe(false);
|
expect(firstResult.get('boolKey')).toBe(false);
|
||||||
@@ -528,24 +824,26 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
.all()
|
.all()
|
||||||
.forEach(call => {
|
.forEach(call => {
|
||||||
if (call.args[0].indexOf('MyObject0') >= 0) {
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
myObjectReadPreference0 = true;
|
myObjectReadPreference0 =
|
||||||
expect(call.args[2].readPreference).toBe(null);
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject1') >= 0) {
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
myObjectReadPreference1 = true;
|
myObjectReadPreference1 =
|
||||||
expect(call.args[2].readPreference).toBe(null);
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject2') >= 0) {
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
myObjectReadPreference2 = call.args[2].readPreference.preference;
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(myObjectReadPreference0).toBe(true);
|
expect(myObjectReadPreference0).toEqual(ReadPreference.SECONDARY);
|
||||||
expect(myObjectReadPreference1).toBe(true);
|
expect(myObjectReadPreference1).toEqual(ReadPreference.SECONDARY);
|
||||||
expect(myObjectReadPreference2).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference2).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -574,7 +872,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
query.include('myObject1');
|
query.include('myObject1');
|
||||||
query.include('myObject1.myObject0');
|
query.include('myObject1.myObject0');
|
||||||
|
|
||||||
query.find().then(results => {
|
query
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
const firstResult = results[0];
|
const firstResult = results[0];
|
||||||
expect(firstResult.get('boolKey')).toBe(false);
|
expect(firstResult.get('boolKey')).toBe(false);
|
||||||
@@ -593,13 +893,16 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
.all()
|
.all()
|
||||||
.forEach(call => {
|
.forEach(call => {
|
||||||
if (call.args[0].indexOf('MyObject0') >= 0) {
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
myObjectReadPreference0 = call.args[2].readPreference.preference;
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject1') >= 0) {
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
myObjectReadPreference1 = call.args[2].readPreference.preference;
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject2') >= 0) {
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
myObjectReadPreference2 = call.args[2].readPreference.preference;
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -610,11 +913,147 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find subqueries in primary by default', done => {
|
it('should change includes read preference when finding through API', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject0');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject1');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
obj1.set('myObject0', obj0);
|
||||||
|
const obj2 = new Parse.Object('MyObject2');
|
||||||
|
obj2.set('boolKey', false);
|
||||||
|
obj2.set('myObject1', obj1);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1, obj2]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject2/' +
|
||||||
|
obj2.id +
|
||||||
|
'?include=' +
|
||||||
|
JSON.stringify(['myObject1', 'myObject1.myObject0']) +
|
||||||
|
'&readPreference=SECONDARY_PREFERRED&includeReadPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
const firstResult = response.data;
|
||||||
|
expect(firstResult.boolKey).toBe(false);
|
||||||
|
expect(firstResult.myObject1.boolKey).toBe(true);
|
||||||
|
expect(firstResult.myObject1.myObject0.boolKey).toBe(false);
|
||||||
|
|
||||||
|
let myObjectReadPreference0 = null;
|
||||||
|
let myObjectReadPreference1 = null;
|
||||||
|
let myObjectReadPreference2 = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference0).toEqual(ReadPreference.SECONDARY);
|
||||||
|
expect(myObjectReadPreference1).toEqual(ReadPreference.SECONDARY);
|
||||||
|
expect(myObjectReadPreference2).toEqual(
|
||||||
|
ReadPreference.SECONDARY_PREFERRED
|
||||||
|
);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change includes read preference when getting through API', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject0');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject1');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
obj1.set('myObject0', obj0);
|
||||||
|
const obj2 = new Parse.Object('MyObject2');
|
||||||
|
obj2.set('boolKey', false);
|
||||||
|
obj2.set('myObject1', obj1);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1, obj2]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject2?where=' +
|
||||||
|
JSON.stringify({ boolKey: false }) +
|
||||||
|
'&include=' +
|
||||||
|
JSON.stringify(['myObject1', 'myObject1.myObject0']) +
|
||||||
|
'&readPreference=SECONDARY_PREFERRED&includeReadPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.results.length).toBe(1);
|
||||||
|
const firstResult = response.data.results[0];
|
||||||
|
expect(firstResult.boolKey).toBe(false);
|
||||||
|
expect(firstResult.myObject1.boolKey).toBe(true);
|
||||||
|
expect(firstResult.myObject1.myObject0.boolKey).toBe(false);
|
||||||
|
|
||||||
|
let myObjectReadPreference0 = null;
|
||||||
|
let myObjectReadPreference1 = null;
|
||||||
|
let myObjectReadPreference2 = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference0).toEqual(ReadPreference.SECONDARY);
|
||||||
|
expect(myObjectReadPreference1).toEqual(ReadPreference.SECONDARY);
|
||||||
|
expect(myObjectReadPreference2).toEqual(
|
||||||
|
ReadPreference.SECONDARY_PREFERRED
|
||||||
|
);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find subqueries in same replica of readPreference by default', done => {
|
||||||
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
const obj0 = new Parse.Object('MyObject0');
|
const obj0 = new Parse.Object('MyObject0');
|
||||||
@@ -642,7 +1081,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query2 = new Parse.Query('MyObject2');
|
const query2 = new Parse.Query('MyObject2');
|
||||||
query2.matchesQuery('myObject1', query1);
|
query2.matchesQuery('myObject1', query1);
|
||||||
|
|
||||||
query2.find().then(results => {
|
query2
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -653,24 +1094,26 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
.all()
|
.all()
|
||||||
.forEach(call => {
|
.forEach(call => {
|
||||||
if (call.args[0].indexOf('MyObject0') >= 0) {
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
myObjectReadPreference0 = true;
|
myObjectReadPreference0 =
|
||||||
expect(call.args[2].readPreference).toBe(null);
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject1') >= 0) {
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
myObjectReadPreference1 = true;
|
myObjectReadPreference1 =
|
||||||
expect(call.args[2].readPreference).toBe(null);
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject2') >= 0) {
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
myObjectReadPreference2 = call.args[2].readPreference.preference;
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(myObjectReadPreference0).toBe(true);
|
expect(myObjectReadPreference0).toEqual(ReadPreference.SECONDARY);
|
||||||
expect(myObjectReadPreference1).toBe(true);
|
expect(myObjectReadPreference1).toEqual(ReadPreference.SECONDARY);
|
||||||
expect(myObjectReadPreference2).toEqual(ReadPreference.SECONDARY);
|
expect(myObjectReadPreference2).toEqual(ReadPreference.SECONDARY);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -703,7 +1146,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query2 = new Parse.Query('MyObject2');
|
const query2 = new Parse.Query('MyObject2');
|
||||||
query2.matchesQuery('myObject1', query1);
|
query2.matchesQuery('myObject1', query1);
|
||||||
|
|
||||||
query2.find().then(results => {
|
query2
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -714,13 +1159,16 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
.all()
|
.all()
|
||||||
.forEach(call => {
|
.forEach(call => {
|
||||||
if (call.args[0].indexOf('MyObject0') >= 0) {
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
myObjectReadPreference0 = call.args[2].readPreference.preference;
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject1') >= 0) {
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
myObjectReadPreference1 = call.args[2].readPreference.preference;
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject2') >= 0) {
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
myObjectReadPreference2 = call.args[2].readPreference.preference;
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -731,7 +1179,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -764,7 +1213,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
const query2 = new Parse.Query('MyObject2');
|
const query2 = new Parse.Query('MyObject2');
|
||||||
query2.doesNotMatchQuery('myObject1', query1);
|
query2.doesNotMatchQuery('myObject1', query1);
|
||||||
|
|
||||||
query2.find().then(results => {
|
query2
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -775,13 +1226,16 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
.all()
|
.all()
|
||||||
.forEach(call => {
|
.forEach(call => {
|
||||||
if (call.args[0].indexOf('MyObject0') >= 0) {
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
myObjectReadPreference0 = call.args[2].readPreference.preference;
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject1') >= 0) {
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
myObjectReadPreference1 = call.args[2].readPreference.preference;
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject2') >= 0) {
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
myObjectReadPreference2 = call.args[2].readPreference.preference;
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -792,7 +1246,8 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -826,7 +1281,9 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
query2.matchesKeyInQuery('boolKey', 'boolKey', query0);
|
query2.matchesKeyInQuery('boolKey', 'boolKey', query0);
|
||||||
query2.doesNotMatchKeyInQuery('boolKey', 'boolKey', query1);
|
query2.doesNotMatchKeyInQuery('boolKey', 'boolKey', query1);
|
||||||
|
|
||||||
query2.find().then(results => {
|
query2
|
||||||
|
.find()
|
||||||
|
.then(results => {
|
||||||
expect(results.length).toBe(1);
|
expect(results.length).toBe(1);
|
||||||
expect(results[0].get('boolKey')).toBe(false);
|
expect(results[0].get('boolKey')).toBe(false);
|
||||||
|
|
||||||
@@ -837,13 +1294,16 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
.all()
|
.all()
|
||||||
.forEach(call => {
|
.forEach(call => {
|
||||||
if (call.args[0].indexOf('MyObject0') >= 0) {
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
myObjectReadPreference0 = call.args[2].readPreference.preference;
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject1') >= 0) {
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
myObjectReadPreference1 = call.args[2].readPreference.preference;
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
if (call.args[0].indexOf('MyObject2') >= 0) {
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
myObjectReadPreference2 = call.args[2].readPreference.preference;
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -854,7 +1314,90 @@ describe_only_db('mongo')('Read preference option', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should change subqueries read preference when using matchesKeyInQuery and doesNotMatchKeyInQuery to find through API', done => {
|
||||||
|
const databaseAdapter = Config.get(Parse.applicationId).database.adapter;
|
||||||
|
|
||||||
|
const obj0 = new Parse.Object('MyObject0');
|
||||||
|
obj0.set('boolKey', false);
|
||||||
|
const obj1 = new Parse.Object('MyObject1');
|
||||||
|
obj1.set('boolKey', true);
|
||||||
|
obj1.set('myObject0', obj0);
|
||||||
|
const obj2 = new Parse.Object('MyObject2');
|
||||||
|
obj2.set('boolKey', false);
|
||||||
|
obj2.set('myObject1', obj1);
|
||||||
|
|
||||||
|
Parse.Object.saveAll([obj0, obj1, obj2]).then(() => {
|
||||||
|
spyOn(databaseAdapter.database.serverConfig, 'cursor').and.callThrough();
|
||||||
|
|
||||||
|
const whereString = JSON.stringify({
|
||||||
|
boolKey: {
|
||||||
|
$select: {
|
||||||
|
query: {
|
||||||
|
className: 'MyObject0',
|
||||||
|
where: { boolKey: false },
|
||||||
|
},
|
||||||
|
key: 'boolKey',
|
||||||
|
},
|
||||||
|
$dontSelect: {
|
||||||
|
query: {
|
||||||
|
className: 'MyObject1',
|
||||||
|
where: { boolKey: true },
|
||||||
|
},
|
||||||
|
key: 'boolKey',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'GET',
|
||||||
|
url:
|
||||||
|
'http://localhost:8378/1/classes/MyObject2/?where=' +
|
||||||
|
whereString +
|
||||||
|
'&readPreference=SECONDARY_PREFERRED&subqueryReadPreference=SECONDARY',
|
||||||
|
headers: {
|
||||||
|
'X-Parse-Application-Id': 'test',
|
||||||
|
'X-Parse-REST-API-Key': 'rest',
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
expect(response.data.results.length).toBe(1);
|
||||||
|
expect(response.data.results[0].boolKey).toBe(false);
|
||||||
|
|
||||||
|
let myObjectReadPreference0 = null;
|
||||||
|
let myObjectReadPreference1 = null;
|
||||||
|
let myObjectReadPreference2 = null;
|
||||||
|
databaseAdapter.database.serverConfig.cursor.calls
|
||||||
|
.all()
|
||||||
|
.forEach(call => {
|
||||||
|
if (call.args[0].indexOf('MyObject0') >= 0) {
|
||||||
|
myObjectReadPreference0 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
if (call.args[0].indexOf('MyObject1') >= 0) {
|
||||||
|
myObjectReadPreference1 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
if (call.args[0].indexOf('MyObject2') >= 0) {
|
||||||
|
myObjectReadPreference2 =
|
||||||
|
call.args[2].readPreference.preference;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(myObjectReadPreference0).toEqual(ReadPreference.SECONDARY);
|
||||||
|
expect(myObjectReadPreference1).toEqual(ReadPreference.SECONDARY);
|
||||||
|
expect(myObjectReadPreference2).toEqual(
|
||||||
|
ReadPreference.SECONDARY_PREFERRED
|
||||||
|
);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -926,6 +926,9 @@ export class MongoStorageAdapter implements StorageAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_parseReadPreference(readPreference: ?string): ?string {
|
_parseReadPreference(readPreference: ?string): ?string {
|
||||||
|
if (readPreference) {
|
||||||
|
readPreference = readPreference.toUpperCase();
|
||||||
|
}
|
||||||
switch (readPreference) {
|
switch (readPreference) {
|
||||||
case 'PRIMARY':
|
case 'PRIMARY':
|
||||||
readPreference = ReadPreference.PRIMARY;
|
readPreference = ReadPreference.PRIMARY;
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL'];
|
|||||||
// include
|
// include
|
||||||
// keys
|
// keys
|
||||||
// redirectClassNameForKey
|
// redirectClassNameForKey
|
||||||
|
// readPreference
|
||||||
|
// includeReadPreference
|
||||||
|
// subqueryReadPreference
|
||||||
function RestQuery(
|
function RestQuery(
|
||||||
config,
|
config,
|
||||||
auth,
|
auth,
|
||||||
@@ -362,6 +365,8 @@ RestQuery.prototype.replaceInQuery = function() {
|
|||||||
if (this.restOptions.subqueryReadPreference) {
|
if (this.restOptions.subqueryReadPreference) {
|
||||||
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
||||||
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
||||||
|
} else if (this.restOptions.readPreference) {
|
||||||
|
additionalOptions.readPreference = this.restOptions.readPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
var subquery = new RestQuery(
|
var subquery = new RestQuery(
|
||||||
@@ -421,6 +426,8 @@ RestQuery.prototype.replaceNotInQuery = function() {
|
|||||||
if (this.restOptions.subqueryReadPreference) {
|
if (this.restOptions.subqueryReadPreference) {
|
||||||
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
||||||
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
||||||
|
} else if (this.restOptions.readPreference) {
|
||||||
|
additionalOptions.readPreference = this.restOptions.readPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
var subquery = new RestQuery(
|
var subquery = new RestQuery(
|
||||||
@@ -484,6 +491,8 @@ RestQuery.prototype.replaceSelect = function() {
|
|||||||
if (this.restOptions.subqueryReadPreference) {
|
if (this.restOptions.subqueryReadPreference) {
|
||||||
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
||||||
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
||||||
|
} else if (this.restOptions.readPreference) {
|
||||||
|
additionalOptions.readPreference = this.restOptions.readPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
var subquery = new RestQuery(
|
var subquery = new RestQuery(
|
||||||
@@ -545,6 +554,8 @@ RestQuery.prototype.replaceDontSelect = function() {
|
|||||||
if (this.restOptions.subqueryReadPreference) {
|
if (this.restOptions.subqueryReadPreference) {
|
||||||
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.readPreference = this.restOptions.subqueryReadPreference;
|
||||||
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference;
|
||||||
|
} else if (this.restOptions.readPreference) {
|
||||||
|
additionalOptions.readPreference = this.restOptions.readPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
var subquery = new RestQuery(
|
var subquery = new RestQuery(
|
||||||
@@ -809,6 +820,8 @@ function includePath(config, auth, response, path, restOptions = {}) {
|
|||||||
includeRestOptions.readPreference = restOptions.includeReadPreference;
|
includeRestOptions.readPreference = restOptions.includeReadPreference;
|
||||||
includeRestOptions.includeReadPreference =
|
includeRestOptions.includeReadPreference =
|
||||||
restOptions.includeReadPreference;
|
restOptions.includeReadPreference;
|
||||||
|
} else if (restOptions.readPreference) {
|
||||||
|
includeRestOptions.readPreference = restOptions.readPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
const queryPromises = Object.keys(pointersHash).map(className => {
|
const queryPromises = Object.keys(pointersHash).map(className => {
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ import rest from '../rest';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Parse from 'parse/node';
|
import Parse from 'parse/node';
|
||||||
|
|
||||||
const ALLOWED_GET_QUERY_KEYS = ['keys', 'include'];
|
const ALLOWED_GET_QUERY_KEYS = [
|
||||||
|
'keys',
|
||||||
|
'include',
|
||||||
|
'readPreference',
|
||||||
|
'includeReadPreference',
|
||||||
|
'subqueryReadPreference',
|
||||||
|
];
|
||||||
|
|
||||||
export class ClassesRouter extends PromiseRouter {
|
export class ClassesRouter extends PromiseRouter {
|
||||||
className(req) {
|
className(req) {
|
||||||
@@ -57,12 +63,21 @@ export class ClassesRouter extends PromiseRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof body.keys == 'string') {
|
if (typeof body.keys === 'string') {
|
||||||
options.keys = body.keys;
|
options.keys = body.keys;
|
||||||
}
|
}
|
||||||
if (body.include) {
|
if (body.include) {
|
||||||
options.include = String(body.include);
|
options.include = String(body.include);
|
||||||
}
|
}
|
||||||
|
if (typeof body.readPreference === 'string') {
|
||||||
|
options.readPreference = body.readPreference;
|
||||||
|
}
|
||||||
|
if (typeof body.includeReadPreference === 'string') {
|
||||||
|
options.includeReadPreference = body.includeReadPreference;
|
||||||
|
}
|
||||||
|
if (typeof body.subqueryReadPreference === 'string') {
|
||||||
|
options.subqueryReadPreference = body.subqueryReadPreference;
|
||||||
|
}
|
||||||
|
|
||||||
return rest
|
return rest
|
||||||
.get(
|
.get(
|
||||||
@@ -154,6 +169,9 @@ export class ClassesRouter extends PromiseRouter {
|
|||||||
'includeAll',
|
'includeAll',
|
||||||
'redirectClassNameForKey',
|
'redirectClassNameForKey',
|
||||||
'where',
|
'where',
|
||||||
|
'readPreference',
|
||||||
|
'includeReadPreference',
|
||||||
|
'subqueryReadPreference',
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const key of Object.keys(body)) {
|
for (const key of Object.keys(body)) {
|
||||||
@@ -188,6 +206,15 @@ export class ClassesRouter extends PromiseRouter {
|
|||||||
if (body.includeAll) {
|
if (body.includeAll) {
|
||||||
options.includeAll = true;
|
options.includeAll = true;
|
||||||
}
|
}
|
||||||
|
if (typeof body.readPreference === 'string') {
|
||||||
|
options.readPreference = body.readPreference;
|
||||||
|
}
|
||||||
|
if (typeof body.includeReadPreference === 'string') {
|
||||||
|
options.includeReadPreference = body.includeReadPreference;
|
||||||
|
}
|
||||||
|
if (typeof body.subqueryReadPreference === 'string') {
|
||||||
|
options.subqueryReadPreference = body.subqueryReadPreference;
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
src/vendor/mongodbUrl.js
vendored
16
src/vendor/mongodbUrl.js
vendored
@@ -101,7 +101,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
|
|||||||
code === 10 /*\n*/ ||
|
code === 10 /*\n*/ ||
|
||||||
code === 12 /*\f*/ ||
|
code === 12 /*\f*/ ||
|
||||||
code === 160 /*\u00A0*/ ||
|
code === 160 /*\u00A0*/ ||
|
||||||
code === 65279 /*\uFEFF*/;
|
code === 65279; /*\uFEFF*/
|
||||||
if (start === -1) {
|
if (start === -1) {
|
||||||
if (isWs) continue;
|
if (isWs) continue;
|
||||||
lastPos = start = i;
|
lastPos = start = i;
|
||||||
@@ -193,7 +193,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
|
|||||||
// how the browser resolves relative URLs.
|
// how the browser resolves relative URLs.
|
||||||
if (slashesDenoteHost || proto || /^\/\/[^@\/]+@[^@\/]+/.test(rest)) {
|
if (slashesDenoteHost || proto || /^\/\/[^@\/]+@[^@\/]+/.test(rest)) {
|
||||||
var slashes =
|
var slashes =
|
||||||
rest.charCodeAt(0) === 47 /*/*/ && rest.charCodeAt(1) === 47 /*/*/;
|
rest.charCodeAt(0) === 47 /*/*/ && rest.charCodeAt(1) === 47; /*/*/
|
||||||
if (slashes && !(proto && hostlessProtocol[proto])) {
|
if (slashes && !(proto && hostlessProtocol[proto])) {
|
||||||
rest = rest.slice(2);
|
rest = rest.slice(2);
|
||||||
this.slashes = true;
|
this.slashes = true;
|
||||||
@@ -285,7 +285,7 @@ Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
|
|||||||
// assume that it's an IPv6 address.
|
// assume that it's an IPv6 address.
|
||||||
var ipv6Hostname =
|
var ipv6Hostname =
|
||||||
hostname.charCodeAt(0) === 91 /*[*/ &&
|
hostname.charCodeAt(0) === 91 /*[*/ &&
|
||||||
hostname.charCodeAt(hostname.length - 1) === 93 /*]*/;
|
hostname.charCodeAt(hostname.length - 1) === 93; /*]*/
|
||||||
|
|
||||||
// validate a little.
|
// validate a little.
|
||||||
if (!ipv6Hostname) {
|
if (!ipv6Hostname) {
|
||||||
@@ -868,11 +868,11 @@ Url.prototype.resolveObject = function(relative) {
|
|||||||
|
|
||||||
// put the host back
|
// put the host back
|
||||||
if (psychotic) {
|
if (psychotic) {
|
||||||
result.hostname = result.host = isAbsolute
|
if (isAbsolute) {
|
||||||
? ''
|
result.hostname = result.host = '';
|
||||||
: srcPath.length
|
} else {
|
||||||
? srcPath.shift()
|
result.hostname = result.host = srcPath.length ? srcPath.shift() : '';
|
||||||
: '';
|
}
|
||||||
//occasionally the auth can get stuck only in host
|
//occasionally the auth can get stuck only in host
|
||||||
//this especially happens in cases like
|
//this especially happens in cases like
|
||||||
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
|
//url.resolveObject('mailto:local1@domain1', 'local2@domain2')
|
||||||
|
|||||||
Reference in New Issue
Block a user