@@ -235,17 +235,18 @@ DatabaseController.prototype.update = function(className, query, update, {
235
235
many,
236
236
upsert,
237
237
} = { } , skipSanitization = false ) {
238
+ const originalQuery = query ;
238
239
const originalUpdate = update ;
239
240
// Make a copy of the object, so we don't mutate the incoming data.
240
241
update = deepcopy ( update ) ;
241
-
242
+ var relationUpdates = [ ] ;
242
243
var isMaster = acl === undefined ;
243
244
var aclGroup = acl || [ ] ;
244
245
return this . loadSchema ( )
245
246
. then ( schemaController => {
246
247
return ( isMaster ? Promise . resolve ( ) : schemaController . validatePermission ( className , aclGroup , 'update' ) )
247
- . then ( ( ) => this . handleRelationUpdates ( className , query . objectId , update ) )
248
248
. then ( ( ) => {
249
+ relationUpdates = this . collectRelationUpdates ( className , originalQuery . objectId , update ) ;
249
250
if ( ! isMaster ) {
250
251
query = this . addPointerPermissions ( schemaController , className , 'update' , query , aclGroup ) ;
251
252
}
@@ -295,6 +296,10 @@ DatabaseController.prototype.update = function(className, query, update, {
295
296
if ( ! result ) {
296
297
return Promise . reject ( new Parse . Error ( Parse . Error . OBJECT_NOT_FOUND , 'Object not found.' ) ) ;
297
298
}
299
+ return this . handleRelationUpdates ( className , originalQuery . objectId , update , relationUpdates ) . then ( ( ) => {
300
+ return result ;
301
+ } ) ;
302
+ } ) . then ( ( result ) => {
298
303
if ( skipSanitization ) {
299
304
return Promise . resolve ( result ) ;
300
305
}
@@ -320,12 +325,11 @@ function sanitizeDatabaseResult(originalObject, result) {
320
325
return Promise . resolve ( response ) ;
321
326
}
322
327
323
- // Processes relation-updating operations from a REST-format update.
324
- // Returns a promise that resolves successfully when these are
325
- // processed.
328
+ // Collect all relation-updating operations from a REST-format update.
329
+ // Returns a list of all relation updates to perform
326
330
// This mutates update.
327
- DatabaseController . prototype . handleRelationUpdates = function ( className , objectId , update ) {
328
- var pending = [ ] ;
331
+ DatabaseController . prototype . collectRelationUpdates = function ( className , objectId , update ) {
332
+ var ops = [ ] ;
329
333
var deleteMe = [ ] ;
330
334
objectId = update . objectId || objectId ;
331
335
@@ -334,20 +338,12 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
334
338
return ;
335
339
}
336
340
if ( op . __op == 'AddRelation' ) {
337
- for ( const object of op . objects ) {
338
- pending . push ( this . addRelation ( key , className ,
339
- objectId ,
340
- object . objectId ) ) ;
341
- }
341
+ ops . push ( { key, op} ) ;
342
342
deleteMe . push ( key ) ;
343
343
}
344
344
345
345
if ( op . __op == 'RemoveRelation' ) {
346
- for ( const object of op . objects ) {
347
- pending . push ( this . removeRelation ( key , className ,
348
- objectId ,
349
- object . objectId ) ) ;
350
- }
346
+ ops . push ( { key, op} ) ;
351
347
deleteMe . push ( key ) ;
352
348
}
353
349
@@ -364,6 +360,35 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
364
360
for ( const key of deleteMe ) {
365
361
delete update [ key ] ;
366
362
}
363
+ return ops ;
364
+ }
365
+
366
+ // Processes relation-updating operations from a REST-format update.
367
+ // Returns a promise that resolves when all updates have been performed
368
+ DatabaseController . prototype . handleRelationUpdates = function ( className , objectId , update , ops ) {
369
+ var pending = [ ] ;
370
+ objectId = update . objectId || objectId ;
371
+ ops . forEach ( ( { key, op} ) => {
372
+ if ( ! op ) {
373
+ return ;
374
+ }
375
+ if ( op . __op == 'AddRelation' ) {
376
+ for ( const object of op . objects ) {
377
+ pending . push ( this . addRelation ( key , className ,
378
+ objectId ,
379
+ object . objectId ) ) ;
380
+ }
381
+ }
382
+
383
+ if ( op . __op == 'RemoveRelation' ) {
384
+ for ( const object of op . objects ) {
385
+ pending . push ( this . removeRelation ( key , className ,
386
+ objectId ,
387
+ object . objectId ) ) ;
388
+ }
389
+ }
390
+ } ) ;
391
+
367
392
return Promise . all ( pending ) ;
368
393
} ;
369
394
@@ -511,12 +536,11 @@ DatabaseController.prototype.create = function(className, object, { acl } = {})
511
536
512
537
var isMaster = acl === undefined ;
513
538
var aclGroup = acl || [ ] ;
514
-
539
+ const relationUpdates = this . collectRelationUpdates ( className , null , object ) ;
515
540
return this . validateClassName ( className )
516
541
. then ( ( ) => this . loadSchema ( ) )
517
542
. then ( schemaController => {
518
543
return ( isMaster ? Promise . resolve ( ) : schemaController . validatePermission ( className , aclGroup , 'create' ) )
519
- . then ( ( ) => this . handleRelationUpdates ( className , null , object ) )
520
544
. then ( ( ) => schemaController . enforceClassExists ( className ) )
521
545
. then ( ( ) => schemaController . reloadData ( ) )
522
546
. then ( ( ) => schemaController . getOneSchema ( className , true ) )
@@ -525,7 +549,11 @@ DatabaseController.prototype.create = function(className, object, { acl } = {})
525
549
flattenUpdateOperatorsForCreate ( object ) ;
526
550
return this . adapter . createObject ( className , SchemaController . convertSchemaToAdapterSchema ( schema ) , object ) ;
527
551
} )
528
- . then ( result => sanitizeDatabaseResult ( originalObject , result . ops [ 0 ] ) ) ;
552
+ . then ( result => {
553
+ return this . handleRelationUpdates ( className , null , object , relationUpdates ) . then ( ( ) => {
554
+ return sanitizeDatabaseResult ( originalObject , result . ops [ 0 ] )
555
+ } ) ;
556
+ } ) ;
529
557
} )
530
558
} ;
531
559
0 commit comments