@@ -201,15 +201,27 @@ const fieldTypeIsInvalid = ({ type, targetClass }) => {
201
201
return undefined ;
202
202
}
203
203
204
+ const injectDefaultSchema = schema => ( {
205
+ className : schema . className ,
206
+ fields : {
207
+ ...defaultColumns . _Default ,
208
+ ...( defaultColumns [ schema . className ] || { } ) ,
209
+ ...schema . fields ,
210
+ } ,
211
+ classLevelPermissions : schema . classLevelPermissions ,
212
+ } )
213
+
204
214
// Stores the entire schema of the app in a weird hybrid format somewhere between
205
215
// the mongo format and the Parse format. Soon, this will all be Parse format.
206
- class Schema {
216
+ class SchemaController {
207
217
_collection ;
218
+ _dbAdapter ;
208
219
data ;
209
220
perms ;
210
221
211
- constructor ( collection ) {
222
+ constructor ( collection , databaseAdapter ) {
212
223
this . _collection = collection ;
224
+ this . _dbAdapter = databaseAdapter ;
213
225
214
226
// this.data[className][fieldName] tells you the type of that field, in mongo format
215
227
this . data = { } ;
@@ -220,19 +232,25 @@ class Schema {
220
232
reloadData ( ) {
221
233
this . data = { } ;
222
234
this . perms = { } ;
223
- return this . _collection . getAllSchemas ( ) . then ( allSchemas => {
235
+ return this . getAllSchemas ( )
236
+ . then ( allSchemas => {
224
237
allSchemas . forEach ( schema => {
225
- const parseFormatSchema = {
226
- ...defaultColumns . _Default ,
227
- ...( defaultColumns [ schema . className ] || { } ) ,
228
- ...schema . fields ,
229
- }
230
- this . data [ schema . className ] = parseFormatSchema ;
238
+ this . data [ schema . className ] = schema . fields ;
231
239
this . perms [ schema . className ] = schema . classLevelPermissions ;
232
240
} ) ;
233
241
} ) ;
234
242
}
235
243
244
+ getAllSchemas ( ) {
245
+ return this . _dbAdapter . getAllSchemas ( )
246
+ . then ( allSchemas => allSchemas . map ( injectDefaultSchema ) ) ;
247
+ }
248
+
249
+ getOneSchema ( className ) {
250
+ return this . _dbAdapter . getOneSchema ( className )
251
+ . then ( injectDefaultSchema ) ;
252
+ }
253
+
236
254
// Create a new class that includes the three default fields.
237
255
// ACL is an implicit column that does not get an entry in the
238
256
// _SCHEMAS database. Returns a promise that resolves with the
@@ -247,9 +265,6 @@ class Schema {
247
265
}
248
266
249
267
return this . _collection . addSchema ( className , fields , classLevelPermissions )
250
- . then ( res => {
251
- return Promise . resolve ( res ) ;
252
- } )
253
268
. catch ( error => {
254
269
if ( error === undefined ) {
255
270
throw new Parse . Error ( Parse . Error . INVALID_CLASS_NAME , `Class ${ className } already exists.` ) ;
@@ -260,40 +275,42 @@ class Schema {
260
275
}
261
276
262
277
updateClass ( className , submittedFields , classLevelPermissions , database ) {
263
- if ( ! this . data [ className ] ) {
264
- throw new Parse . Error ( Parse . Error . INVALID_CLASS_NAME , `Class ${ className } does not exist.` ) ;
265
- }
266
- let existingFields = Object . assign ( this . data [ className ] , { _id : className } ) ;
267
- Object . keys ( submittedFields ) . forEach ( name => {
268
- let field = submittedFields [ name ] ;
269
- if ( existingFields [ name ] && field . __op !== 'Delete' ) {
270
- throw new Parse . Error ( 255 , `Field ${ name } exists, cannot update.` ) ;
271
- }
272
- if ( ! existingFields [ name ] && field . __op === 'Delete' ) {
273
- throw new Parse . Error ( 255 , `Field ${ name } does not exist, cannot delete.` ) ;
278
+ return this . hasClass ( className )
279
+ . then ( hasClass => {
280
+ if ( ! hasClass ) {
281
+ throw new Parse . Error ( Parse . Error . INVALID_CLASS_NAME , `Class ${ className } does not exist.` ) ;
274
282
}
275
- } ) ;
276
-
277
- let newSchema = buildMergedSchemaObject ( existingFields , submittedFields ) ;
278
- let validationError = this . validateSchemaData ( className , newSchema , classLevelPermissions ) ;
279
- if ( validationError ) {
280
- throw new Parse . Error ( validationError . code , validationError . error ) ;
281
- }
283
+ let existingFields = Object . assign ( this . data [ className ] , { _id : className } ) ;
284
+ Object . keys ( submittedFields ) . forEach ( name => {
285
+ let field = submittedFields [ name ] ;
286
+ if ( existingFields [ name ] && field . __op !== 'Delete' ) {
287
+ throw new Parse . Error ( 255 , `Field ${ name } exists, cannot update.` ) ;
288
+ }
289
+ if ( ! existingFields [ name ] && field . __op === 'Delete' ) {
290
+ throw new Parse . Error ( 255 , `Field ${ name } does not exist, cannot delete.` ) ;
291
+ }
292
+ } ) ;
282
293
283
- // Finally we have checked to make sure the request is valid and we can start deleting fields.
284
- // Do all deletions first, then a single save to _SCHEMA collection to handle all additions.
285
- let deletePromises = [ ] ;
286
- let insertedFields = [ ] ;
287
- Object . keys ( submittedFields ) . forEach ( fieldName => {
288
- if ( submittedFields [ fieldName ] . __op === 'Delete' ) {
289
- const promise = this . deleteField ( fieldName , className , database ) ;
290
- deletePromises . push ( promise ) ;
291
- } else {
292
- insertedFields . push ( fieldName ) ;
294
+ let newSchema = buildMergedSchemaObject ( existingFields , submittedFields ) ;
295
+ let validationError = this . validateSchemaData ( className , newSchema , classLevelPermissions ) ;
296
+ if ( validationError ) {
297
+ throw new Parse . Error ( validationError . code , validationError . error ) ;
293
298
}
294
- } ) ;
295
299
296
- return Promise . all ( deletePromises ) // Delete Everything
300
+ // Finally we have checked to make sure the request is valid and we can start deleting fields.
301
+ // Do all deletions first, then a single save to _SCHEMA collection to handle all additions.
302
+ let deletePromises = [ ] ;
303
+ let insertedFields = [ ] ;
304
+ Object . keys ( submittedFields ) . forEach ( fieldName => {
305
+ if ( submittedFields [ fieldName ] . __op === 'Delete' ) {
306
+ const promise = this . deleteField ( fieldName , className , database ) ;
307
+ deletePromises . push ( promise ) ;
308
+ } else {
309
+ insertedFields . push ( fieldName ) ;
310
+ }
311
+ } ) ;
312
+
313
+ return Promise . all ( deletePromises ) // Delete Everything
297
314
. then ( ( ) => this . reloadData ( ) ) // Reload our Schema, so we have all the new values
298
315
. then ( ( ) => {
299
316
let promises = insertedFields . map ( fieldName => {
@@ -302,15 +319,14 @@ class Schema {
302
319
} ) ;
303
320
return Promise . all ( promises ) ;
304
321
} )
305
- . then ( ( ) => {
306
- return this . setPermissions ( className , classLevelPermissions )
307
- } )
322
+ . then ( ( ) => this . setPermissions ( className , classLevelPermissions ) )
308
323
//TODO: Move this logic into the database adapter
309
- . then ( ( ) => {
310
- return { className : className ,
311
- fields : this . data [ className ] ,
312
- classLevelPermissions : this . perms [ className ] }
313
- } ) ;
324
+ . then ( ( ) => ( {
325
+ className : className ,
326
+ fields : this . data [ className ] ,
327
+ classLevelPermissions : this . perms [ className ]
328
+ } ) ) ;
329
+ } )
314
330
}
315
331
316
332
@@ -637,9 +653,7 @@ class Schema {
637
653
return undefined ;
638
654
} ;
639
655
640
- // Checks if a given class is in the schema. Needs to load the
641
- // schema first, which is kinda janky. Hopefully we can refactor
642
- // and make this be a regular value.
656
+ // Checks if a given class is in the schema.
643
657
hasClass ( className ) {
644
658
return this . reloadData ( ) . then ( ( ) => ! ! ( this . data [ className ] ) ) ;
645
659
}
@@ -672,8 +686,8 @@ class Schema {
672
686
}
673
687
674
688
// Returns a promise for a new Schema.
675
- function load ( collection ) {
676
- let schema = new Schema ( collection ) ;
689
+ function load ( collection , dbAdapter ) {
690
+ let schema = new SchemaController ( collection , dbAdapter ) ;
677
691
return schema . reloadData ( ) . then ( ( ) => schema ) ;
678
692
}
679
693
0 commit comments