1
+ // @flow
1
2
import MongoCollection from './MongoCollection' ;
2
3
import MongoSchemaCollection from './MongoSchemaCollection' ;
4
+ import { StorageAdapter , IndexingStorageAdapter } 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 ) {
@@ -78,20 +87,20 @@ const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPe
78
87
}
79
88
80
89
81
- export class MongoStorageAdapter {
90
+ export class MongoStorageAdapter implements StorageAdapter , IndexingStorageAdapter {
82
91
// Private
83
92
_uri : string ;
84
93
_collectionPrefix : string ;
85
94
_mongoOptions : Object ;
86
95
// Public
87
96
connectionPromise ;
88
- database ;
89
-
97
+ database : any ;
98
+ _maxTimeMS : ? number ;
90
99
constructor ( {
91
100
uri = defaults . DefaultMongoURI ,
92
101
collectionPrefix = '' ,
93
102
mongoOptions = { } ,
94
- } ) {
103
+ } : any ) {
95
104
this . _uri = uri ;
96
105
this . _collectionPrefix = collectionPrefix ;
97
106
this . _mongoOptions = mongoOptions ;
@@ -149,22 +158,22 @@ export class MongoStorageAdapter {
149
158
. then ( collection => new MongoSchemaCollection ( collection ) ) ;
150
159
}
151
160
152
- classExists ( name ) {
161
+ classExists ( name : string ) {
153
162
return this . connect ( ) . then ( ( ) => {
154
163
return this . database . listCollections ( { name : this . _collectionPrefix + name } ) . toArray ( ) ;
155
164
} ) . then ( collections => {
156
165
return collections . length > 0 ;
157
166
} ) ;
158
167
}
159
168
160
- setClassLevelPermissions ( className , CLPs ) {
169
+ setClassLevelPermissions ( className : string , CLPs : any ) {
161
170
return this . _schemaCollection ( )
162
171
. then ( schemaCollection => schemaCollection . updateSchema ( className , {
163
172
$set : { _metadata : { class_permissions : CLPs } }
164
173
} ) ) ;
165
174
}
166
175
167
- createClass ( className , schema ) {
176
+ createClass ( className : string , schema : SchemaType ) {
168
177
schema = convertParseSchemaToMongoSchema ( schema ) ;
169
178
const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP ( schema . fields , className , schema . classLevelPermissions ) ;
170
179
mongoObject . _id = className ;
@@ -180,15 +189,15 @@ export class MongoStorageAdapter {
180
189
} )
181
190
}
182
191
183
- addFieldIfNotExists ( className , fieldName , type ) {
192
+ addFieldIfNotExists ( className : string , fieldName : string , type : any ) {
184
193
return this . _schemaCollection ( )
185
194
. then ( schemaCollection => schemaCollection . addFieldIfNotExists ( className , fieldName , type ) )
186
195
. then ( ( ) => this . createIndexesIfNeeded ( className , fieldName , type ) ) ;
187
196
}
188
197
189
198
// Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.)
190
199
// and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible.
191
- deleteClass ( className ) {
200
+ deleteClass ( className : string ) {
192
201
return this . _adaptiveCollection ( className )
193
202
. then ( collection => collection . drop ( ) )
194
203
. catch ( error => {
@@ -229,7 +238,7 @@ export class MongoStorageAdapter {
229
238
// may do so.
230
239
231
240
// Returns a Promise.
232
- deleteFields ( className , schema , fieldNames ) {
241
+ deleteFields ( className : string , schema : SchemaType , fieldNames : string [ ] ) {
233
242
const mongoFormatNames = fieldNames . map ( fieldName => {
234
243
if ( schema . fields [ fieldName ] . type === 'Pointer' ) {
235
244
return `_p_${ fieldName } `
@@ -263,15 +272,15 @@ export class MongoStorageAdapter {
263
272
// Return a promise for the schema with the given name, in Parse format. If
264
273
// this adapter doesn't know about the schema, return a promise that rejects with
265
274
// undefined as the reason.
266
- getClass ( className ) {
275
+ getClass ( className : string ) {
267
276
return this . _schemaCollection ( )
268
277
. then ( schemasCollection => schemasCollection . _fetchOneSchemaFrom_SCHEMA ( className ) )
269
278
}
270
279
271
280
// TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema,
272
281
// and should infer from the type. Or maybe does need the schema for validations. Or maybe needs
273
282
// the schema only for the legacy mongo format. We'll figure that out later.
274
- createObject ( className , schema , object ) {
283
+ createObject ( className : string , schema : SchemaType , object : any ) {
275
284
schema = convertParseSchemaToMongoSchema ( schema ) ;
276
285
const mongoObject = parseObjectToMongoObjectForCreate ( className , object , schema ) ;
277
286
return this . _adaptiveCollection ( className )
@@ -295,7 +304,7 @@ export class MongoStorageAdapter {
295
304
// Remove all objects that match the given Parse Query.
296
305
// If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined.
297
306
// If there is some other error, reject with INTERNAL_SERVER_ERROR.
298
- deleteObjectsByQuery ( className , schema , query ) {
307
+ deleteObjectsByQuery ( className : string , schema : SchemaType , query : QueryType ) {
299
308
schema = convertParseSchemaToMongoSchema ( schema ) ;
300
309
return this . _adaptiveCollection ( className )
301
310
. then ( collection => {
@@ -313,7 +322,7 @@ export class MongoStorageAdapter {
313
322
}
314
323
315
324
// Apply the update to all objects that match the given Parse Query.
316
- updateObjectsByQuery ( className , schema , query , update ) {
325
+ updateObjectsByQuery ( className : string , schema : SchemaType , query : QueryType , update : any ) {
317
326
schema = convertParseSchemaToMongoSchema ( schema ) ;
318
327
const mongoUpdate = transformUpdate ( className , update , schema ) ;
319
328
const mongoWhere = transformWhere ( className , query , schema ) ;
@@ -323,7 +332,7 @@ export class MongoStorageAdapter {
323
332
324
333
// Atomically finds and updates an object based on query.
325
334
// Return value not currently well specified.
326
- findOneAndUpdate ( className , schema , query , update ) {
335
+ findOneAndUpdate ( className : string , schema : SchemaType , query : QueryType , update : any ) {
327
336
schema = convertParseSchemaToMongoSchema ( schema ) ;
328
337
const mongoUpdate = transformUpdate ( className , update , schema ) ;
329
338
const mongoWhere = transformWhere ( className , query , schema ) ;
@@ -333,7 +342,7 @@ export class MongoStorageAdapter {
333
342
}
334
343
335
344
// Hopefully we can get rid of this. It's only used for config and hooks.
336
- upsertOneObject ( className , schema , query , update ) {
345
+ upsertOneObject ( className : string , schema : SchemaType , query : QueryType , update : any ) {
337
346
schema = convertParseSchemaToMongoSchema ( schema ) ;
338
347
const mongoUpdate = transformUpdate ( className , update , schema ) ;
339
348
const mongoWhere = transformWhere ( className , query , schema ) ;
@@ -342,7 +351,7 @@ export class MongoStorageAdapter {
342
351
}
343
352
344
353
// Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }.
345
- find ( className , schema , query , { skip, limit, sort, keys, readPreference } ) {
354
+ find ( className : string , schema : SchemaType , query : QueryType , { skip, limit, sort, keys, readPreference } : QueryOptionsType ) {
346
355
schema = convertParseSchemaToMongoSchema ( schema ) ;
347
356
const mongoWhere = transformWhere ( className , query , schema ) ;
348
357
const mongoSort = _ . mapKeys ( sort , ( value , fieldName ) => transformKey ( className , fieldName , schema ) ) ;
@@ -370,7 +379,7 @@ export class MongoStorageAdapter {
370
379
// As such, we shouldn't expose this function to users of parse until we have an out-of-band
371
380
// Way of determining if a field is nullable. Undefined doesn't count against uniqueness,
372
381
// which is why we use sparse indexes.
373
- ensureUniqueness ( className , schema , fieldNames ) {
382
+ ensureUniqueness ( className : string , schema : SchemaType , fieldNames : string [ ] ) {
374
383
schema = convertParseSchemaToMongoSchema ( schema ) ;
375
384
const indexCreationRequest = { } ;
376
385
const mongoFieldNames = fieldNames . map ( fieldName => transformKey ( className , fieldName , schema ) ) ;
@@ -388,14 +397,14 @@ export class MongoStorageAdapter {
388
397
}
389
398
390
399
// Used in tests
391
- _rawFind ( className , query ) {
400
+ _rawFind ( className : string , query : QueryType ) {
392
401
return this . _adaptiveCollection ( className ) . then ( collection => collection . find ( query , {
393
402
maxTimeMS : this . _maxTimeMS ,
394
403
} ) ) ;
395
404
}
396
405
397
406
// Executes a count.
398
- count ( className , schema , query , readPreference ) {
407
+ count ( className : string , schema : SchemaType , query : QueryType , readPreference : ? string ) {
399
408
schema = convertParseSchemaToMongoSchema ( schema ) ;
400
409
readPreference = this . _parseReadPreference ( readPreference ) ;
401
410
return this . _adaptiveCollection ( className )
@@ -405,13 +414,13 @@ export class MongoStorageAdapter {
405
414
} ) ) ;
406
415
}
407
416
408
- distinct ( className , schema , query , fieldName ) {
417
+ distinct ( className : string , schema : SchemaType , query : QueryType , fieldName : string ) {
409
418
schema = convertParseSchemaToMongoSchema ( schema ) ;
410
419
return this . _adaptiveCollection ( className )
411
420
. then ( collection => collection . distinct ( fieldName , transformWhere ( className , query , schema ) ) ) ;
412
421
}
413
422
414
- aggregate ( className , pipeline , readPreference ) {
423
+ aggregate ( className : string , pipeline : any , readPreference : ? string ) {
415
424
readPreference = this . _parseReadPreference ( readPreference ) ;
416
425
return this . _adaptiveCollection ( className )
417
426
. then ( collection => collection . aggregate ( pipeline , { readPreference, maxTimeMS : this . _maxTimeMS } ) )
@@ -426,7 +435,7 @@ export class MongoStorageAdapter {
426
435
} ) ;
427
436
}
428
437
429
- _parseReadPreference ( readPreference ) {
438
+ _parseReadPreference ( readPreference : ? string ) : ? string {
430
439
if ( readPreference ) {
431
440
switch ( readPreference ) {
432
441
case 'PRIMARY' :
@@ -451,16 +460,16 @@ export class MongoStorageAdapter {
451
460
return readPreference ;
452
461
}
453
462
454
- performInitialization ( ) {
463
+ performInitialization ( ) : Promise < void > {
455
464
return Promise . resolve ( ) ;
456
465
}
457
466
458
- createIndex ( className , index ) {
467
+ createIndex ( className : string , index : any ) {
459
468
return this . _adaptiveCollection ( className )
460
469
. then ( collection => collection . _mongoCollection . createIndex ( index ) ) ;
461
470
}
462
471
463
- createIndexesIfNeeded ( className , fieldName , type ) {
472
+ createIndexesIfNeeded ( className : string , fieldName : string , type : any ) {
464
473
if ( type && type . type === 'Polygon' ) {
465
474
const index = {
466
475
[ fieldName ] : '2dsphere'
@@ -470,7 +479,7 @@ export class MongoStorageAdapter {
470
479
return Promise . resolve ( ) ;
471
480
}
472
481
473
- createTextIndexesIfNeeded ( className , query ) {
482
+ createTextIndexesIfNeeded ( className : string , query : QueryType ) {
474
483
for ( const fieldName in query ) {
475
484
if ( ! query [ fieldName ] || ! query [ fieldName ] . $text ) {
476
485
continue ;
@@ -491,11 +500,10 @@ export class MongoStorageAdapter {
491
500
return Promise . resolve ( ) ;
492
501
}
493
502
494
- getIndexes ( className ) {
503
+ getIndexes ( className : string ) {
495
504
return this . _adaptiveCollection ( className )
496
505
. then ( collection => collection . _mongoCollection . indexes ( ) ) ;
497
506
}
498
507
}
499
508
500
509
export default MongoStorageAdapter ;
501
- module . exports = MongoStorageAdapter ; // Required for tests
0 commit comments