Skip to content

Commit 0b990b6

Browse files
committed
Merge pull request #729 from ParsePlatform/nlutsenko.decouple.schema
Decouple and remove direct mongo access from Schema/SchemaRouter.
2 parents 382149b + d1dbc1a commit 0b990b6

File tree

6 files changed

+202
-252
lines changed

6 files changed

+202
-252
lines changed

spec/Schema.spec.js

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict';
2+
13
var Config = require('../src/Config');
24
var Schema = require('../src/Schema');
35
var dd = require('deep-diff');
@@ -483,7 +485,7 @@ describe('Schema', () => {
483485
.then(schema => schema.deleteField('installationId', '_Installation'))
484486
.catch(error => {
485487
expect(error.code).toEqual(136);
486-
expect(error.error).toEqual('field installationId cannot be changed');
488+
expect(error.message).toEqual('field installationId cannot be changed');
487489
done();
488490
});
489491
});
@@ -493,7 +495,7 @@ describe('Schema', () => {
493495
.then(schema => schema.deleteField('field', 'NoClass'))
494496
.catch(error => {
495497
expect(error.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
496-
expect(error.error).toEqual('class NoClass does not exist');
498+
expect(error.message).toEqual('Class NoClass does not exist.');
497499
done();
498500
});
499501
});
@@ -504,32 +506,39 @@ describe('Schema', () => {
504506
.then(schema => schema.deleteField('missingField', 'HasAllPOD'))
505507
.fail(error => {
506508
expect(error.code).toEqual(255);
507-
expect(error.error).toEqual('field missingField does not exist, cannot delete');
509+
expect(error.message).toEqual('Field missingField does not exist, cannot delete.');
508510
done();
509511
});
510512
});
511513

512514
it('drops related collection when deleting relation field', done => {
513515
var obj1 = hasAllPODobject();
514516
obj1.save()
515-
.then(savedObj1 => {
516-
var obj2 = new Parse.Object('HasPointersAndRelations');
517-
obj2.set('aPointer', savedObj1);
518-
var relation = obj2.relation('aRelation');
519-
relation.add(obj1);
520-
return obj2.save();
521-
})
522-
.then(() => {
523-
config.database.adapter.database.collection('test__Join:aRelation:HasPointersAndRelations', { strict: true }, (err, coll) => {
524-
expect(err).toEqual(null);
525-
config.database.loadSchema()
526-
.then(schema => schema.deleteField('aRelation', 'HasPointersAndRelations', config.database.adapter.database, 'test_'))
527-
.then(() => config.database.adapter.database.collection('test__Join:aRelation:HasPointersAndRelations', { strict: true }, (err, coll) => {
528-
expect(err).not.toEqual(null);
529-
done();
530-
}))
517+
.then(savedObj1 => {
518+
var obj2 = new Parse.Object('HasPointersAndRelations');
519+
obj2.set('aPointer', savedObj1);
520+
var relation = obj2.relation('aRelation');
521+
relation.add(obj1);
522+
return obj2.save();
523+
})
524+
.then(() => config.database.collectionExists('_Join:aRelation:HasPointersAndRelations'))
525+
.then(exists => {
526+
if (!exists) {
527+
fail('Relation collection should exist after save.');
528+
}
529+
})
530+
.then(() => config.database.loadSchema())
531+
.then(schema => schema.deleteField('aRelation', 'HasPointersAndRelations', config.database))
532+
.then(() => config.database.collectionExists('_Join:aRelation:HasPointersAndRelations'))
533+
.then(exists => {
534+
if (exists) {
535+
fail('Relation collection should not exist after deleting relation field.');
536+
}
537+
done();
538+
}, error => {
539+
fail(error);
540+
done();
531541
});
532-
})
533542
});
534543

535544
it('can delete string fields and resave as number field', done => {
@@ -538,7 +547,7 @@ describe('Schema', () => {
538547
var obj2 = hasAllPODobject();
539548
var p = Parse.Object.saveAll([obj1, obj2])
540549
.then(() => config.database.loadSchema())
541-
.then(schema => schema.deleteField('aString', 'HasAllPOD', config.database.adapter.database, 'test_'))
550+
.then(schema => schema.deleteField('aString', 'HasAllPOD', config.database))
542551
.then(() => new Parse.Query('HasAllPOD').get(obj1.id))
543552
.then(obj1Reloaded => {
544553
expect(obj1Reloaded.get('aString')).toEqual(undefined);
@@ -568,7 +577,7 @@ describe('Schema', () => {
568577
expect(obj1.get('aPointer').id).toEqual(obj1.id);
569578
})
570579
.then(() => config.database.loadSchema())
571-
.then(schema => schema.deleteField('aPointer', 'NewClass', config.database.adapter.database, 'test_'))
580+
.then(schema => schema.deleteField('aPointer', 'NewClass', config.database))
572581
.then(() => new Parse.Query('NewClass').get(obj1.id))
573582
.then(obj1 => {
574583
expect(obj1.get('aPointer')).toEqual(undefined);

spec/schemas.spec.js

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict';
2+
13
var Parse = require('parse/node').Parse;
24
var request = require('request');
35
var dd = require('deep-diff');
@@ -369,7 +371,7 @@ describe('schemas', () => {
369371
}, (error, response, body) => {
370372
expect(response.statusCode).toEqual(400);
371373
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
372-
expect(body.error).toEqual('class NoClass does not exist');
374+
expect(body.error).toEqual('Class NoClass does not exist.');
373375
done();
374376
});
375377
});
@@ -390,13 +392,13 @@ describe('schemas', () => {
390392
}, (error, response, body) => {
391393
expect(response.statusCode).toEqual(400);
392394
expect(body.code).toEqual(255);
393-
expect(body.error).toEqual('field aString exists, cannot update');
395+
expect(body.error).toEqual('Field aString exists, cannot update.');
394396
done();
395397
});
396398
})
397399
});
398400

399-
it('refuses to delete non-existant fields', done => {
401+
it('refuses to delete non-existent fields', done => {
400402
var obj = hasAllPODobject();
401403
obj.save()
402404
.then(() => {
@@ -406,13 +408,13 @@ describe('schemas', () => {
406408
json: true,
407409
body: {
408410
fields: {
409-
nonExistantKey: {__op: "Delete"},
411+
nonExistentKey: {__op: "Delete"},
410412
}
411413
}
412414
}, (error, response, body) => {
413415
expect(response.statusCode).toEqual(400);
414416
expect(body.code).toEqual(255);
415-
expect(body.error).toEqual('field nonExistantKey does not exist, cannot delete');
417+
expect(body.error).toEqual('Field nonExistentKey does not exist, cannot delete.');
416418
done();
417419
});
418420
});
@@ -660,7 +662,8 @@ describe('schemas', () => {
660662
}, (error, response, body) => {
661663
expect(response.statusCode).toEqual(400);
662664
expect(body.code).toEqual(255);
663-
expect(body.error).toEqual('class HasAllPOD not empty, contains 1 objects, cannot drop schema');
665+
expect(body.error).toMatch(/HasAllPOD/);
666+
expect(body.error).toMatch(/contains 1/);
664667
done();
665668
});
666669
});
@@ -710,28 +713,35 @@ describe('schemas', () => {
710713
}, (error, response, body) => {
711714
expect(response.statusCode).toEqual(200);
712715
expect(response.body).toEqual({});
713-
config.database.adapter.database.collection('test__Join:aRelation:MyOtherClass', { strict: true }, (err, coll) => {
714-
//Expect Join table to be gone
715-
expect(err).not.toEqual(null);
716-
config.database.adapter.database.collection('test_MyOtherClass', { strict: true }, (err, coll) => {
717-
// Expect data table to be gone
718-
expect(err).not.toEqual(null);
719-
request.get({
720-
url: 'http://localhost:8378/1/schemas/MyOtherClass',
721-
headers: masterKeyHeaders,
722-
json: true,
723-
}, (error, response, body) => {
724-
//Expect _SCHEMA entry to be gone.
725-
expect(response.statusCode).toEqual(400);
726-
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
727-
expect(body.error).toEqual('class MyOtherClass does not exist');
728-
done();
729-
});
716+
config.database.collectionExists('_Join:aRelation:MyOtherClass').then(exists => {
717+
if (exists) {
718+
fail('Relation collection should be deleted.');
719+
done();
720+
}
721+
return config.database.collectionExists('MyOtherClass');
722+
}).then(exists => {
723+
if (exists) {
724+
fail('Class collection should be deleted.');
725+
done();
726+
}
727+
}).then(() => {
728+
request.get({
729+
url: 'http://localhost:8378/1/schemas/MyOtherClass',
730+
headers: masterKeyHeaders,
731+
json: true,
732+
}, (error, response, body) => {
733+
//Expect _SCHEMA entry to be gone.
734+
expect(response.statusCode).toEqual(400);
735+
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
736+
expect(body.error).toEqual('class MyOtherClass does not exist');
737+
done();
730738
});
731739
});
732740
});
741+
}).then(() => {
733742
}, error => {
734743
fail(error);
744+
done();
735745
});
736746
});
737747
});

src/Adapters/Storage/Mongo/MongoStorageAdapter.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ export class MongoStorageAdapter {
3030
});
3131
}
3232

33+
collectionExists(name: string) {
34+
return this.connect().then(() => {
35+
return this.database.listCollections({ name: name }).toArray();
36+
}).then(collections => {
37+
return collections.length > 0;
38+
});
39+
}
40+
41+
dropCollection(name: string) {
42+
return this.collection(name).then(collection => collection.drop());
43+
}
3344
// Used for testing only right now.
3445
collectionsContaining(match: string) {
3546
return this.connect().then(() => {

src/Controllers/DatabaseController.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,18 @@ DatabaseController.prototype.collection = function(className) {
3838
return this.rawCollection(className);
3939
};
4040

41+
DatabaseController.prototype.collectionExists = function(className) {
42+
return this.adapter.collectionExists(this.collectionPrefix + className);
43+
};
44+
4145
DatabaseController.prototype.rawCollection = function(className) {
4246
return this.adapter.collection(this.collectionPrefix + className);
4347
};
4448

49+
DatabaseController.prototype.dropCollection = function(className) {
50+
return this.adapter.dropCollection(this.collectionPrefix + className);
51+
};
52+
4553
function returnsTrue() {
4654
return true;
4755
}

0 commit comments

Comments
 (0)