Uses one query for installation dedup (#2281)
This commit is contained in:
@@ -582,65 +582,83 @@ RestWrite.prototype.handleInstallation = function() {
|
|||||||
var promise = Promise.resolve();
|
var promise = Promise.resolve();
|
||||||
|
|
||||||
var idMatch; // Will be a match on either objectId or installationId
|
var idMatch; // Will be a match on either objectId or installationId
|
||||||
|
var objectIdMatch;
|
||||||
|
var installationIdMatch;
|
||||||
var deviceTokenMatches = [];
|
var deviceTokenMatches = [];
|
||||||
|
|
||||||
|
// Instead of issuing 3 reads, let's do it with one OR.
|
||||||
|
let orQueries = [];
|
||||||
if (this.query && this.query.objectId) {
|
if (this.query && this.query.objectId) {
|
||||||
promise = promise.then(() => {
|
orQueries.push({
|
||||||
return this.config.database.find('_Installation', {
|
|
||||||
objectId: this.query.objectId
|
objectId: this.query.objectId
|
||||||
}, {}).then((results) => {
|
});
|
||||||
if (!results.length) {
|
}
|
||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
|
if (this.data.installationId) {
|
||||||
|
orQueries.push({
|
||||||
|
'installationId': this.data.installationId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.data.deviceToken) {
|
||||||
|
orQueries.push({'deviceToken': this.data.deviceToken});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orQueries.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
promise = promise.then(() => {
|
||||||
|
return this.config.database.find('_Installation', {
|
||||||
|
'$or': orQueries
|
||||||
|
}, {});
|
||||||
|
}).then((results) => {
|
||||||
|
results.forEach((result) => {
|
||||||
|
if (this.query && this.query.objectId && result.objectId == this.query.objectId) {
|
||||||
|
objectIdMatch = result;
|
||||||
|
}
|
||||||
|
if (result.installationId == this.data.installationId) {
|
||||||
|
installationIdMatch = result;
|
||||||
|
}
|
||||||
|
if (result.deviceToken == this.data.deviceToken) {
|
||||||
|
deviceTokenMatches.push(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sanity checks when running a query
|
||||||
|
if (this.query && this.query.objectId) {
|
||||||
|
if (!objectIdMatch) {
|
||||||
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
|
||||||
'Object not found for update.');
|
'Object not found for update.');
|
||||||
}
|
}
|
||||||
idMatch = results[0];
|
if (this.data.installationId && objectIdMatch.installationId &&
|
||||||
if (this.data.installationId && idMatch.installationId &&
|
this.data.installationId !== objectIdMatch.installationId) {
|
||||||
this.data.installationId !== idMatch.installationId) {
|
|
||||||
throw new Parse.Error(136,
|
throw new Parse.Error(136,
|
||||||
'installationId may not be changed in this ' +
|
'installationId may not be changed in this ' +
|
||||||
'operation');
|
'operation');
|
||||||
}
|
}
|
||||||
if (this.data.deviceToken && idMatch.deviceToken &&
|
if (this.data.deviceToken && objectIdMatch.deviceToken &&
|
||||||
this.data.deviceToken !== idMatch.deviceToken &&
|
this.data.deviceToken !== objectIdMatch.deviceToken &&
|
||||||
!this.data.installationId && !idMatch.installationId) {
|
!this.data.installationId && !objectIdMatch.installationId) {
|
||||||
throw new Parse.Error(136,
|
throw new Parse.Error(136,
|
||||||
'deviceToken may not be changed in this ' +
|
'deviceToken may not be changed in this ' +
|
||||||
'operation');
|
'operation');
|
||||||
}
|
}
|
||||||
if (this.data.deviceType && this.data.deviceType &&
|
if (this.data.deviceType && this.data.deviceType &&
|
||||||
this.data.deviceType !== idMatch.deviceType) {
|
this.data.deviceType !== objectIdMatch.deviceType) {
|
||||||
throw new Parse.Error(136,
|
throw new Parse.Error(136,
|
||||||
'deviceType may not be changed in this ' +
|
'deviceType may not be changed in this ' +
|
||||||
'operation');
|
'operation');
|
||||||
}
|
}
|
||||||
return;
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we already have installations for the installationId/deviceToken
|
if (this.query && this.query.objectId && objectIdMatch) {
|
||||||
promise = promise.then(() => {
|
idMatch = objectIdMatch;
|
||||||
if (this.data.installationId) {
|
|
||||||
return this.config.database.find('_Installation', {
|
|
||||||
'installationId': this.data.installationId
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return Promise.resolve([]);
|
|
||||||
}).then((results) => {
|
if (this.data.installationId && installationIdMatch) {
|
||||||
if (results && results.length) {
|
idMatch = installationIdMatch;
|
||||||
// We only take the first match by installationId
|
|
||||||
idMatch = results[0];
|
|
||||||
}
|
|
||||||
if (this.data.deviceToken) {
|
|
||||||
return this.config.database.find(
|
|
||||||
'_Installation',
|
|
||||||
{'deviceToken': this.data.deviceToken});
|
|
||||||
}
|
|
||||||
return Promise.resolve([]);
|
|
||||||
}).then((results) => {
|
|
||||||
if (results) {
|
|
||||||
deviceTokenMatches = results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}).then(() => {
|
||||||
if (!idMatch) {
|
if (!idMatch) {
|
||||||
if (!deviceTokenMatches.length) {
|
if (!deviceTokenMatches.length) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user