1
+ // @flow
1
2
import MongoCollection from './MongoCollection' ;
2
3
import MongoSchemaCollection from './MongoSchemaCollection' ;
4
+ import { StorageAdapter } from '../StorageAdapter' ;
5
+ import type { SchemaType ,
6
+ QueryType ,
7
+ QueryOptionsType } from '../StorageAdapter' ;
3
8
import {
4
9
parse as parseUrl ,
5
10
format as formatUrl ,
@@ -11,10 +16,13 @@ import {
11
16
transformWhere ,
12
17
transformUpdate ,
13
18
} from './MongoTransform' ;
19
+ // $FlowFixMe
14
20
import Parse from 'parse/node' ;
21
+ // $FlowFixMe
15
22
import _ from 'lodash' ;
16
23
import defaults from '../../../defaults' ;
17
24
25
+ // $FlowFixMe
18
26
const mongodb = require ( 'mongodb' ) ;
19
27
const MongoClient = mongodb . MongoClient ;
20
28
const ReadPreference = mongodb . ReadPreference ;
@@ -58,7 +66,8 @@ const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPe
58
66
_id : className ,
59
67
objectId : 'string' ,
60
68
updatedAt : 'string' ,
61
- createdAt : 'string'
69
+ createdAt : 'string' ,
70
+ _metadata : undefined ,
62
71
} ;
63
72
64
73
for ( const fieldName in fields ) {
@@ -83,20 +92,22 @@ const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPe
83
92
}
84
93
85
94
86
- export class MongoStorageAdapter {
95
+ export class MongoStorageAdapter implements StorageAdapter {
87
96
// Private
88
97
_uri : string ;
89
98
_collectionPrefix : string ;
90
99
_mongoOptions : Object ;
91
100
// Public
92
101
connectionPromise ;
93
- database ;
94
- canSortOnJoinTables ;
102
+ database : any ;
103
+ _maxTimeMS : ?number ;
104
+ canSortOnJoinTables : boolean ;
105
+
95
106
constructor ( {
96
107
uri = defaults . DefaultMongoURI ,
97
108
collectionPrefix = '' ,
98
109
mongoOptions = { } ,
99
- } ) {
110
+ } : any ) {
100
111
this . _uri = uri ;
101
112
this . _collectionPrefix = collectionPrefix ;
102
113
this . _mongoOptions = mongoOptions ;
@@ -155,22 +166,22 @@ export class MongoStorageAdapter {
155
166
. then ( collection => new MongoSchemaCollection ( collection ) ) ;
156
167
}
157
168
158
- classExists ( name ) {
169
+ classExists ( name : string ) {
159
170
return this . connect ( ) . then ( ( ) => {
160
171
return this . database . listCollections ( { name : this . _collectionPrefix + name } ) . toArray ( ) ;
161
172
} ) . then ( collections => {
162
173
return collections . length > 0 ;
163
174
} ) ;
164
175
}
165
176
166
- setClassLevelPermissions ( className , CLPs ) {
177
+ setClassLevelPermissions ( className : string , CLPs : any ) {
167
178
return this . _schemaCollection ( )
168
179
. then ( schemaCollection => schemaCollection . updateSchema ( className , {
169
180
$set : { _metadata : { class_permissions : CLPs } }
170
181
} ) ) ;
171
182
}
172
183
173
- setIndexesWithSchemaFormat ( className , submittedIndexes , existingIndexes = { } , fields ) {
184
+ setIndexesWithSchemaFormat ( className : string , submittedIndexes : any , existingIndexes : any = { } , fields : any ) : Promise < void > {
174
185
if ( submittedIndexes === undefined ) {
175
186
return Promise . resolve ( ) ;
176
187
}
@@ -216,7 +227,7 @@ export class MongoStorageAdapter {
216
227
} ) ) ;
217
228
}
218
229
219
- setIndexesFromMongo ( className ) {
230
+ setIndexesFromMongo ( className : string ) {
220
231
return this . getIndexes ( className ) . then ( ( indexes ) => {
221
232
indexes = indexes . reduce ( ( obj , index ) => {
222
233
if ( index . key . _fts ) {
@@ -239,7 +250,7 @@ export class MongoStorageAdapter {
239
250
} ) ;
240
251
}
241
252
242
- createClass ( className , schema ) {
253
+ createClass ( className : string , schema : SchemaType ) {
243
254
schema = convertParseSchemaToMongoSchema ( schema ) ;
244
255
const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP ( schema . fields , className , schema . classLevelPermissions , schema . indexes ) ;
245
256
mongoObject . _id = className ;
@@ -256,15 +267,15 @@ export class MongoStorageAdapter {
256
267
} )
257
268
}
258
269
259
- addFieldIfNotExists ( className , fieldName , type ) {
270
+ addFieldIfNotExists ( className : string , fieldName : string , type : any ) {
260
271
return this . _schemaCollection ( )
261
272
. then ( schemaCollection => schemaCollection . addFieldIfNotExists ( className , fieldName , type ) )
262
273
. then ( ( ) => this . createIndexesIfNeeded ( className , fieldName , type ) ) ;
263
274
}
264
275
265
276
// Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.)
266
277
// and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible.
267
- deleteClass ( className ) {
278
+ deleteClass ( className : string ) {
268
279
return this . _adaptiveCollection ( className )
269
280
. then ( collection => collection . drop ( ) )
270
281
. catch ( error => {
@@ -305,7 +316,7 @@ export class MongoStorageAdapter {
305
316
// may do so.
306
317
307
318
// Returns a Promise.
308
- deleteFields ( className , schema , fieldNames ) {
319
+ deleteFields ( className : string , schema : SchemaType , fieldNames : string [ ] ) {
309
320
const mongoFormatNames = fieldNames . map ( fieldName => {
310
321
if ( schema . fields [ fieldName ] . type === 'Pointer' ) {
311
322
return `_p_${ fieldName } `
@@ -339,15 +350,15 @@ export class MongoStorageAdapter {
339
350
// Return a promise for the schema with the given name, in Parse format. If
340
351
// this adapter doesn't know about the schema, return a promise that rejects with
341
352
// undefined as the reason.
342
- getClass ( className ) {
353
+ getClass ( className : string ) {
343
354
return this . _schemaCollection ( )
344
355
. then ( schemasCollection => schemasCollection . _fetchOneSchemaFrom_SCHEMA ( className ) )
345
356
}
346
357
347
358
// TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema,
348
359
// and should infer from the type. Or maybe does need the schema for validations. Or maybe needs
349
360
// the schema only for the legacy mongo format. We'll figure that out later.
350
- createObject ( className , schema , object ) {
361
+ createObject ( className : string , schema : SchemaType , object : any ) {
351
362
schema = convertParseSchemaToMongoSchema ( schema ) ;
352
363
const mongoObject = parseObjectToMongoObjectForCreate ( className , object , schema ) ;
353
364
return this . _adaptiveCollection ( className )
@@ -371,7 +382,7 @@ export class MongoStorageAdapter {
371
382
// Remove all objects that match the given Parse Query.
372
383
// If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined.
373
384
// If there is some other error, reject with INTERNAL_SERVER_ERROR.
374
- deleteObjectsByQuery ( className , schema , query ) {
385
+ deleteObjectsByQuery ( className : string , schema : SchemaType , query : QueryType ) {
375
386
schema = convertParseSchemaToMongoSchema ( schema ) ;
376
387
return this . _adaptiveCollection ( className )
377
388
. then ( collection => {
@@ -389,7 +400,7 @@ export class MongoStorageAdapter {
389
400
}
390
401
391
402
// Apply the update to all objects that match the given Parse Query.
392
- updateObjectsByQuery ( className , schema , query , update ) {
403
+ updateObjectsByQuery ( className : string , schema : SchemaType , query : QueryType , update : any ) {
393
404
schema = convertParseSchemaToMongoSchema ( schema ) ;
394
405
const mongoUpdate = transformUpdate ( className , update , schema ) ;
395
406
const mongoWhere = transformWhere ( className , query , schema ) ;
@@ -399,7 +410,7 @@ export class MongoStorageAdapter {
399
410
400
411
// Atomically finds and updates an object based on query.
401
412
// Return value not currently well specified.
402
- findOneAndUpdate ( className , schema , query , update ) {
413
+ findOneAndUpdate ( className : string , schema : SchemaType , query : QueryType , update : any ) {
403
414
schema = convertParseSchemaToMongoSchema ( schema ) ;
404
415
const mongoUpdate = transformUpdate ( className , update , schema ) ;
405
416
const mongoWhere = transformWhere ( className , query , schema ) ;
@@ -409,7 +420,7 @@ export class MongoStorageAdapter {
409
420
}
410
421
411
422
// Hopefully we can get rid of this. It's only used for config and hooks.
412
- upsertOneObject ( className , schema , query , update ) {
423
+ upsertOneObject ( className : string , schema : SchemaType , query : QueryType , update : any ) {
413
424
schema = convertParseSchemaToMongoSchema ( schema ) ;
414
425
const mongoUpdate = transformUpdate ( className , update , schema ) ;
415
426
const mongoWhere = transformWhere ( className , query , schema ) ;
@@ -418,7 +429,7 @@ export class MongoStorageAdapter {
418
429
}
419
430
420
431
// Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }.
421
- find ( className , schema , query , { skip, limit, sort, keys, readPreference } ) {
432
+ find ( className : string , schema : SchemaType , query : QueryType , { skip, limit, sort, keys, readPreference } : QueryOptionsType ) : Promise < any > {
422
433
schema = convertParseSchemaToMongoSchema ( schema ) ;
423
434
const mongoWhere = transformWhere ( className , query , schema ) ;
424
435
const mongoSort = _ . mapKeys ( sort , ( value , fieldName ) => transformKey ( className , fieldName , schema ) ) ;
@@ -446,7 +457,7 @@ export class MongoStorageAdapter {
446
457
// As such, we shouldn't expose this function to users of parse until we have an out-of-band
447
458
// Way of determining if a field is nullable. Undefined doesn't count against uniqueness,
448
459
// which is why we use sparse indexes.
449
- ensureUniqueness ( className , schema , fieldNames ) {
460
+ ensureUniqueness ( className : string , schema : SchemaType , fieldNames : string [ ] ) {
450
461
schema = convertParseSchemaToMongoSchema ( schema ) ;
451
462
const indexCreationRequest = { } ;
452
463
const mongoFieldNames = fieldNames . map ( fieldName => transformKey ( className , fieldName , schema ) ) ;
@@ -464,14 +475,14 @@ export class MongoStorageAdapter {
464
475
}
465
476
466
477
// Used in tests
467
- _rawFind ( className , query ) {
478
+ _rawFind ( className : string , query : QueryType ) {
468
479
return this . _adaptiveCollection ( className ) . then ( collection => collection . find ( query , {
469
480
maxTimeMS : this . _maxTimeMS ,
470
481
} ) ) ;
471
482
}
472
483
473
484
// Executes a count.
474
- count ( className , schema , query , readPreference ) {
485
+ count ( className : string , schema : SchemaType , query : QueryType , readPreference : ? string ) {
475
486
schema = convertParseSchemaToMongoSchema ( schema ) ;
476
487
readPreference = this . _parseReadPreference ( readPreference ) ;
477
488
return this . _adaptiveCollection ( className )
@@ -481,14 +492,14 @@ export class MongoStorageAdapter {
481
492
} ) ) ;
482
493
}
483
494
484
- distinct ( className , schema , query , fieldName ) {
495
+ distinct ( className : string , schema : SchemaType , query : QueryType , fieldName : string ) {
485
496
schema = convertParseSchemaToMongoSchema ( schema ) ;
486
497
return this . _adaptiveCollection ( className )
487
498
. then ( collection => collection . distinct ( fieldName , transformWhere ( className , query , schema ) ) )
488
499
. then ( objects => objects . map ( object => mongoObjectToParseObject ( className , object , schema ) ) ) ;
489
500
}
490
501
491
- aggregate ( className , schema , pipeline , readPreference ) {
502
+ aggregate ( className : string , schema : any , pipeline : any , readPreference : ? string ) {
492
503
readPreference = this . _parseReadPreference ( readPreference ) ;
493
504
return this . _adaptiveCollection ( className )
494
505
. then ( collection => collection . aggregate ( pipeline , { readPreference, maxTimeMS : this . _maxTimeMS } ) )
@@ -504,7 +515,7 @@ export class MongoStorageAdapter {
504
515
. then ( objects => objects . map ( object => mongoObjectToParseObject ( className , object , schema ) ) ) ;
505
516
}
506
517
507
- _parseReadPreference ( readPreference ) {
518
+ _parseReadPreference ( readPreference : ? string ) : ? string {
508
519
if ( readPreference ) {
509
520
switch ( readPreference ) {
510
521
case 'PRIMARY' :
@@ -529,21 +540,21 @@ export class MongoStorageAdapter {
529
540
return readPreference ;
530
541
}
531
542
532
- performInitialization ( ) {
543
+ performInitialization ( ) : Promise < void > {
533
544
return Promise . resolve ( ) ;
534
545
}
535
546
536
- createIndex ( className , index ) {
547
+ createIndex ( className : string , index : any ) {
537
548
return this . _adaptiveCollection ( className )
538
549
. then ( collection => collection . _mongoCollection . createIndex ( index ) ) ;
539
550
}
540
551
541
- createIndexes ( className , indexes ) {
552
+ createIndexes ( className : string , indexes : any ) {
542
553
return this . _adaptiveCollection ( className )
543
554
. then ( collection => collection . _mongoCollection . createIndexes ( indexes ) ) ;
544
555
}
545
556
546
- createIndexesIfNeeded ( className , fieldName , type ) {
557
+ createIndexesIfNeeded ( className : string , fieldName : string , type : any ) {
547
558
if ( type && type . type === 'Polygon' ) {
548
559
const index = {
549
560
[ fieldName ] : '2dsphere'
@@ -553,7 +564,7 @@ export class MongoStorageAdapter {
553
564
return Promise . resolve ( ) ;
554
565
}
555
566
556
- createTextIndexesIfNeeded ( className , query , schema ) {
567
+ createTextIndexesIfNeeded ( className : string , query : QueryType , schema : any ) : Promise < void > {
557
568
for ( const fieldName in query ) {
558
569
if ( ! query [ fieldName ] || ! query [ fieldName ] . $text ) {
559
570
continue ;
@@ -580,17 +591,17 @@ export class MongoStorageAdapter {
580
591
return Promise . resolve ( ) ;
581
592
}
582
593
583
- getIndexes ( className ) {
594
+ getIndexes ( className : string ) {
584
595
return this . _adaptiveCollection ( className )
585
596
. then ( collection => collection . _mongoCollection . indexes ( ) ) ;
586
597
}
587
598
588
- dropIndex ( className , index ) {
599
+ dropIndex ( className : string , index : any ) {
589
600
return this . _adaptiveCollection ( className )
590
601
. then ( collection => collection . _mongoCollection . dropIndex ( index ) ) ;
591
602
}
592
603
593
- dropAllIndexes ( className ) {
604
+ dropAllIndexes ( className : string ) {
594
605
return this . _adaptiveCollection ( className )
595
606
. then ( collection => collection . _mongoCollection . dropIndexes ( ) ) ;
596
607
}
@@ -607,4 +618,3 @@ export class MongoStorageAdapter {
607
618
}
608
619
609
620
export default MongoStorageAdapter ;
610
- module . exports = MongoStorageAdapter ; // Required for tests
0 commit comments