Skip to content

Commit 4febe5f

Browse files
flovilmartRafael Santos
authored andcommitted
Uses one query for installation dedup (parse-community#2281)
1 parent b8a1f34 commit 4febe5f

File tree

1 file changed

+56
-38
lines changed

1 file changed

+56
-38
lines changed

src/RestWrite.js

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -582,65 +582,83 @@ RestWrite.prototype.handleInstallation = function() {
582582
var promise = Promise.resolve();
583583

584584
var idMatch; // Will be a match on either objectId or installationId
585+
var objectIdMatch;
586+
var installationIdMatch;
585587
var deviceTokenMatches = [];
586588

589+
// Instead of issuing 3 reads, let's do it with one OR.
590+
let orQueries = [];
587591
if (this.query && this.query.objectId) {
588-
promise = promise.then(() => {
589-
return this.config.database.find('_Installation', {
592+
orQueries.push({
590593
objectId: this.query.objectId
591-
}, {}).then((results) => {
592-
if (!results.length) {
593-
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
594+
});
595+
}
596+
if (this.data.installationId) {
597+
orQueries.push({
598+
'installationId': this.data.installationId
599+
});
600+
}
601+
if (this.data.deviceToken) {
602+
orQueries.push({'deviceToken': this.data.deviceToken});
603+
}
604+
605+
if (orQueries.length == 0) {
606+
return;
607+
}
608+
609+
promise = promise.then(() => {
610+
return this.config.database.find('_Installation', {
611+
'$or': orQueries
612+
}, {});
613+
}).then((results) => {
614+
results.forEach((result) => {
615+
if (this.query && this.query.objectId && result.objectId == this.query.objectId) {
616+
objectIdMatch = result;
617+
}
618+
if (result.installationId == this.data.installationId) {
619+
installationIdMatch = result;
620+
}
621+
if (result.deviceToken == this.data.deviceToken) {
622+
deviceTokenMatches.push(result);
623+
}
624+
});
625+
626+
// Sanity checks when running a query
627+
if (this.query && this.query.objectId) {
628+
if (!objectIdMatch) {
629+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
594630
'Object not found for update.');
595-
}
596-
idMatch = results[0];
597-
if (this.data.installationId && idMatch.installationId &&
598-
this.data.installationId !== idMatch.installationId) {
631+
}
632+
if (this.data.installationId && objectIdMatch.installationId &&
633+
this.data.installationId !== objectIdMatch.installationId) {
599634
throw new Parse.Error(136,
600635
'installationId may not be changed in this ' +
601636
'operation');
602637
}
603-
if (this.data.deviceToken && idMatch.deviceToken &&
604-
this.data.deviceToken !== idMatch.deviceToken &&
605-
!this.data.installationId && !idMatch.installationId) {
638+
if (this.data.deviceToken && objectIdMatch.deviceToken &&
639+
this.data.deviceToken !== objectIdMatch.deviceToken &&
640+
!this.data.installationId && !objectIdMatch.installationId) {
606641
throw new Parse.Error(136,
607642
'deviceToken may not be changed in this ' +
608643
'operation');
609644
}
610645
if (this.data.deviceType && this.data.deviceType &&
611-
this.data.deviceType !== idMatch.deviceType) {
646+
this.data.deviceType !== objectIdMatch.deviceType) {
612647
throw new Parse.Error(136,
613648
'deviceType may not be changed in this ' +
614649
'operation');
615650
}
616-
return;
617-
});
618-
});
619-
}
620-
621-
// Check if we already have installations for the installationId/deviceToken
622-
promise = promise.then(() => {
623-
if (this.data.installationId) {
624-
return this.config.database.find('_Installation', {
625-
'installationId': this.data.installationId
626-
});
627-
}
628-
return Promise.resolve([]);
629-
}).then((results) => {
630-
if (results && results.length) {
631-
// We only take the first match by installationId
632-
idMatch = results[0];
633651
}
634-
if (this.data.deviceToken) {
635-
return this.config.database.find(
636-
'_Installation',
637-
{'deviceToken': this.data.deviceToken});
652+
653+
if (this.query && this.query.objectId && objectIdMatch) {
654+
idMatch = objectIdMatch;
638655
}
639-
return Promise.resolve([]);
640-
}).then((results) => {
641-
if (results) {
642-
deviceTokenMatches = results;
656+
657+
if (this.data.installationId && installationIdMatch) {
658+
idMatch = installationIdMatch;
643659
}
660+
661+
}).then(() => {
644662
if (!idMatch) {
645663
if (!deviceTokenMatches.length) {
646664
return;

0 commit comments

Comments
 (0)