1
1
// A database adapter that works with data exported from the hosted
2
2
// Parse database.
3
3
4
+ import intersect from 'intersect' ;
5
+
4
6
var mongodb = require ( 'mongodb' ) ;
5
7
var Parse = require ( 'parse/node' ) . Parse ;
6
8
@@ -487,18 +489,26 @@ DatabaseController.prototype.reduceRelationKeys = function(className, query) {
487
489
}
488
490
} ;
489
491
490
- DatabaseController . prototype . addInObjectIdsIds = function ( ids , query ) {
491
- if ( typeof query . objectId == 'string' ) {
492
- // Add equality op as we are sure
493
- // we had a constraint on that one
494
- query . objectId = { '$eq' : query . objectId } ;
492
+ DatabaseController . prototype . addInObjectIdsIds = function ( ids = null , query ) {
493
+ let idsFromString = typeof query . objectId === 'string' ? [ query . objectId ] : null ;
494
+ let idsFromEq = query . objectId && query . objectId [ '$eq' ] ? [ query . objectId [ '$eq' ] ] : null ;
495
+ let idsFromIn = query . objectId && query . objectId [ '$in' ] ? query . objectId [ '$in' ] : null ;
496
+
497
+ let allIds = [ idsFromString , idsFromEq , idsFromIn , ids ] . filter ( list => list !== null ) ;
498
+ let totalLength = allIds . reduce ( ( memo , list ) => memo + list . length , 0 ) ;
499
+
500
+ let idsIntersection = [ ] ;
501
+ if ( totalLength > 125 ) {
502
+ idsIntersection = intersect . big ( allIds ) ;
503
+ } else {
504
+ idsIntersection = intersect ( allIds ) ;
495
505
}
496
- query . objectId = query . objectId || { } ;
497
- let queryIn = [ ] . concat ( query . objectId [ '$in' ] || [ ] , ids || [ ] ) ;
498
- // make a set and spread to remove duplicates
499
- // replace the $in operator as other constraints
500
- // may be set
501
- query . objectId [ '$in' ] = [ ... new Set ( queryIn ) ] ;
506
+
507
+ // Need to make sure we don't clobber existing $lt or other constraints on objectId
508
+ if ( ! ( 'objectId' in query ) || typeof query . objectId === 'string' ) {
509
+ query . objectId = { } ;
510
+ }
511
+ query . objectId [ '$in' ] = idsIntersection ;
502
512
503
513
return query ;
504
514
}
@@ -518,53 +528,47 @@ DatabaseController.prototype.addInObjectIdsIds = function(ids, query) {
518
528
// anything about users, ideally. Then, improve the format of the ACL
519
529
// arg to work like the others.
520
530
DatabaseController . prototype . find = function ( className , query , options = { } ) {
521
- var mongoOptions = { } ;
531
+ let mongoOptions = { } ;
522
532
if ( options . skip ) {
523
533
mongoOptions . skip = options . skip ;
524
534
}
525
535
if ( options . limit ) {
526
536
mongoOptions . limit = options . limit ;
527
537
}
528
538
529
- var isMaster = ! ( 'acl' in options ) ;
530
- var aclGroup = options . acl || [ ] ;
531
- var acceptor = function ( schema ) {
532
- return schema . hasKeys ( className , keysForQuery ( query ) ) ;
533
- } ;
534
- var schema ;
535
- return this . loadSchema ( acceptor ) . then ( ( s ) => {
539
+ let isMaster = ! ( 'acl' in options ) ;
540
+ let aclGroup = options . acl || [ ] ;
541
+ let acceptor = schema => schema . hasKeys ( className , keysForQuery ( query ) )
542
+ let schema = null ;
543
+ return this . loadSchema ( acceptor ) . then ( s => {
536
544
schema = s ;
537
545
if ( options . sort ) {
538
546
mongoOptions . sort = { } ;
539
- for ( var key in options . sort ) {
540
- var mongoKey = transform . transformKey ( schema , className , key ) ;
547
+ for ( let key in options . sort ) {
548
+ let mongoKey = transform . transformKey ( schema , className , key ) ;
541
549
mongoOptions . sort [ mongoKey ] = options . sort [ key ] ;
542
550
}
543
551
}
544
552
545
553
if ( ! isMaster ) {
546
- var op = 'find' ;
547
- var k = Object . keys ( query ) ;
548
- if ( k . length == 1 && typeof query . objectId == 'string' ) {
549
- op = 'get' ;
550
- }
554
+ let op = typeof query . objectId == 'string' && Object . keys ( query ) . length === 1 ?
555
+ 'get' :
556
+ 'find' ;
551
557
return schema . validatePermission ( className , aclGroup , op ) ;
552
558
}
553
559
return Promise . resolve ( ) ;
554
- } ) . then ( ( ) => {
555
- return this . reduceRelationKeys ( className , query ) ;
556
- } ) . then ( ( ) => {
557
- return this . reduceInRelation ( className , query , schema ) ;
558
- } ) . then ( ( ) => {
559
- return this . adaptiveCollection ( className ) ;
560
- } ) . then ( collection => {
561
- var mongoWhere = transform . transformWhere ( schema , className , query ) ;
560
+ } )
561
+ . then ( ( ) => this . reduceRelationKeys ( className , query ) )
562
+ . then ( ( ) => this . reduceInRelation ( className , query , schema ) )
563
+ . then ( ( ) => this . adaptiveCollection ( className ) )
564
+ . then ( collection => {
565
+ let mongoWhere = transform . transformWhere ( schema , className , query ) ;
562
566
if ( ! isMaster ) {
563
- var orParts = [
567
+ let orParts = [
564
568
{ "_rperm" : { "$exists" : false } } ,
565
569
{ "_rperm" : { "$in" : [ "*" ] } }
566
570
] ;
567
- for ( var acl of aclGroup ) {
571
+ for ( let acl of aclGroup ) {
568
572
orParts . push ( { "_rperm" : { "$in" : [ acl ] } } ) ;
569
573
}
570
574
mongoWhere = { '$and' : [ mongoWhere , { '$or' : orParts } ] } ;
0 commit comments