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