Skip to content

Commit a163327

Browse files
committed
Remove usages of non-adaptive collection inside DatabaseController.
1 parent 8d10447 commit a163327

File tree

3 files changed

+74
-68
lines changed

3 files changed

+74
-68
lines changed

src/Adapters/Storage/Mongo/MongoCollection.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export default class MongoCollection {
5757
})
5858
}
5959

60+
insertOne(object) {
61+
return this._mongoCollection.insertOne(object);
62+
}
63+
6064
// Atomically updates data in the database for a single (first) object that matched the query
6165
// If there is nothing that matches the query - does insert
6266
// Postgres Note: `INSERT ... ON CONFLICT UPDATE` that is available since 9.5.
@@ -83,8 +87,8 @@ export default class MongoCollection {
8387
return this._mongoCollection.deleteOne(query);
8488
}
8589

86-
remove(query) {
87-
return this._mongoCollection.remove(query);
90+
deleteMany(query) {
91+
return this._mongoCollection.deleteMany(query);
8892
}
8993

9094
drop() {

src/Controllers/DatabaseController.js

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ function returnsTrue() {
5454
return true;
5555
}
5656

57+
DatabaseController.prototype.validateClassName = function(className) {
58+
if (!Schema.classNameIsValid(className)) {
59+
const error = new Parse.Error(Parse.Error.INVALID_CLASS_NAME, 'invalid className: ' + className);
60+
return Promise.reject(error);
61+
}
62+
return Promise.resolve();
63+
};
64+
5765
// Returns a promise for a schema object.
5866
// If we are provided a acceptor, then we run it on the schema.
5967
// If the schema isn't accepted, we reload it at most once.
@@ -230,30 +238,28 @@ DatabaseController.prototype.handleRelationUpdates = function(className,
230238

231239
// Adds a relation.
232240
// Returns a promise that resolves successfully iff the add was successful.
233-
DatabaseController.prototype.addRelation = function(key, fromClassName,
234-
fromId, toId) {
235-
var doc = {
241+
DatabaseController.prototype.addRelation = function(key, fromClassName, fromId, toId) {
242+
let doc = {
236243
relatedId: toId,
237-
owningId: fromId
244+
owningId : fromId
238245
};
239-
var className = '_Join:' + key + ':' + fromClassName;
240-
return this.collection(className).then((coll) => {
241-
return coll.update(doc, doc, {upsert: true});
246+
let className = `_Join:${key}:${fromClassName}`;
247+
return this.adaptiveCollection(className).then((coll) => {
248+
return coll.upsertOne(doc, doc);
242249
});
243250
};
244251

245252
// Removes a relation.
246253
// Returns a promise that resolves successfully iff the remove was
247254
// successful.
248-
DatabaseController.prototype.removeRelation = function(key, fromClassName,
249-
fromId, toId) {
255+
DatabaseController.prototype.removeRelation = function(key, fromClassName, fromId, toId) {
250256
var doc = {
251257
relatedId: toId,
252258
owningId: fromId
253259
};
254-
var className = '_Join:' + key + ':' + fromClassName;
255-
return this.collection(className).then((coll) => {
256-
return coll.remove(doc);
260+
let className = `_Join:${key}:${fromClassName}`;
261+
return this.adaptiveCollection(className).then(coll => {
262+
return coll.deleteOne(doc);
257263
});
258264
};
259265

@@ -269,40 +275,36 @@ DatabaseController.prototype.destroy = function(className, query, options = {})
269275
var aclGroup = options.acl || [];
270276

271277
var schema;
272-
return this.loadSchema().then((s) => {
273-
schema = s;
274-
if (!isMaster) {
275-
return schema.validatePermission(className, aclGroup, 'delete');
276-
}
277-
return Promise.resolve();
278-
}).then(() => {
279-
280-
return this.collection(className);
281-
}).then((coll) => {
282-
var mongoWhere = transform.transformWhere(schema, className, query);
283-
284-
if (options.acl) {
285-
var writePerms = [
286-
{_wperm: {'$exists': false}}
287-
];
288-
for (var entry of options.acl) {
289-
writePerms.push({_wperm: {'$in': [entry]}});
278+
return this.loadSchema()
279+
.then(s => {
280+
schema = s;
281+
if (!isMaster) {
282+
return schema.validatePermission(className, aclGroup, 'delete');
290283
}
291-
mongoWhere = {'$and': [mongoWhere, {'$or': writePerms}]};
292-
}
293-
294-
return coll.remove(mongoWhere);
295-
}).then((resp) => {
296-
//Check _Session to avoid changing password failed without any session.
297-
if (resp.result.n === 0 && className !== "_Session") {
298-
return Promise.reject(
299-
new Parse.Error(Parse.Error.OBJECT_NOT_FOUND,
300-
'Object not found.'));
284+
return Promise.resolve();
285+
})
286+
.then(() => this.adaptiveCollection(className))
287+
.then(collection => {
288+
let mongoWhere = transform.transformWhere(schema, className, query);
301289

302-
}
303-
}, (error) => {
304-
throw error;
305-
});
290+
if (options.acl) {
291+
var writePerms = [
292+
{ _wperm: { '$exists': false } }
293+
];
294+
for (var entry of options.acl) {
295+
writePerms.push({ _wperm: { '$in': [entry] } });
296+
}
297+
mongoWhere = { '$and': [mongoWhere, { '$or': writePerms }] };
298+
}
299+
return collection.deleteMany(mongoWhere);
300+
})
301+
.then(resp => {
302+
//Check _Session to avoid changing password failed without any session.
303+
// TODO: @nlutsenko Stop relying on `result.n`
304+
if (resp.result.n === 0 && className !== "_Session") {
305+
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.');
306+
}
307+
});
306308
};
307309

308310
// Inserts an object into the database.
@@ -312,21 +314,21 @@ DatabaseController.prototype.create = function(className, object, options) {
312314
var isMaster = !('acl' in options);
313315
var aclGroup = options.acl || [];
314316

315-
return this.loadSchema().then((s) => {
316-
schema = s;
317-
if (!isMaster) {
318-
return schema.validatePermission(className, aclGroup, 'create');
319-
}
320-
return Promise.resolve();
321-
}).then(() => {
322-
323-
return this.handleRelationUpdates(className, null, object);
324-
}).then(() => {
325-
return this.collection(className);
326-
}).then((coll) => {
327-
var mongoObject = transform.transformCreate(schema, className, object);
328-
return coll.insert([mongoObject]);
329-
});
317+
return this.validateClassName(className)
318+
.then(() => this.loadSchema())
319+
.then(s => {
320+
schema = s;
321+
if (!isMaster) {
322+
return schema.validatePermission(className, aclGroup, 'create');
323+
}
324+
return Promise.resolve();
325+
})
326+
.then(() => this.handleRelationUpdates(className, null, object))
327+
.then(() => this.adaptiveCollection(className))
328+
.then(coll => {
329+
var mongoObject = transform.transformCreate(schema, className, object);
330+
return coll.insertOne(mongoObject);
331+
});
330332
};
331333

332334
// Runs a mongo query on the database.
@@ -386,14 +388,14 @@ DatabaseController.prototype.owningIds = function(className, key, relatedIds) {
386388
// equal-to-pointer constraints on relation fields.
387389
// Returns a promise that resolves when query is mutated
388390
DatabaseController.prototype.reduceInRelation = function(className, query, schema) {
389-
391+
390392
// Search for an in-relation or equal-to-relation
391393
// Make it sequential for now, not sure of paralleization side effects
392394
if (query['$or']) {
393395
let ors = query['$or'];
394396
return Promise.all(ors.map((aQuery, index) => {
395397
return this.reduceInRelation(className, aQuery, schema).then((aQuery) => {
396-
query['$or'][index] = aQuery;
398+
query['$or'][index] = aQuery;
397399
})
398400
}));
399401
}
@@ -413,14 +415,14 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
413415
relatedIds = [query[key].objectId];
414416
}
415417
return this.owningIds(className, key, relatedIds).then((ids) => {
416-
delete query[key];
418+
delete query[key];
417419
this.addInObjectIdsIds(ids, query);
418420
return Promise.resolve(query);
419421
});
420422
}
421423
return Promise.resolve(query);
422424
})
423-
425+
424426
return Promise.all(promises).then(() => {
425427
return Promise.resolve(query);
426428
})
@@ -429,13 +431,13 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
429431
// Modifies query so that it no longer has $relatedTo
430432
// Returns a promise that resolves when query is mutated
431433
DatabaseController.prototype.reduceRelationKeys = function(className, query) {
432-
434+
433435
if (query['$or']) {
434436
return Promise.all(query['$or'].map((aQuery) => {
435437
return this.reduceRelationKeys(className, aQuery);
436438
}));
437439
}
438-
440+
439441
var relatedTo = query['$relatedTo'];
440442
if (relatedTo) {
441443
return this.relatedIds(

src/Controllers/HooksController.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class HooksController {
7171

7272
_removeHooks(query) {
7373
return this.getCollection().then(collection => {
74-
return collection.remove(query);
74+
return collection.deleteMany(query);
7575
}).then(() => {
7676
return {};
7777
});

0 commit comments

Comments
 (0)