Remove dependency on raw mongo from SchemaRouter.delete.

This commit is contained in:
Nikita Lutsenko
2016-02-29 17:04:38 -08:00
parent d7b1184b5e
commit 028ef2a7b2
4 changed files with 50 additions and 66 deletions

View File

@@ -396,7 +396,7 @@ describe('schemas', () => {
}) })
}); });
it('refuses to delete non-existant fields', done => { it('refuses to delete non-existent fields', done => {
var obj = hasAllPODobject(); var obj = hasAllPODobject();
obj.save() obj.save()
.then(() => { .then(() => {
@@ -406,13 +406,13 @@ describe('schemas', () => {
json: true, json: true,
body: { body: {
fields: { fields: {
nonExistantKey: {__op: "Delete"}, nonExistentKey: {__op: "Delete"},
} }
} }
}, (error, response, body) => { }, (error, response, body) => {
expect(response.statusCode).toEqual(400); expect(response.statusCode).toEqual(400);
expect(body.code).toEqual(255); expect(body.code).toEqual(255);
expect(body.error).toEqual('field nonExistantKey does not exist, cannot delete'); expect(body.error).toEqual('field nonExistentKey does not exist, cannot delete');
done(); done();
}); });
}); });
@@ -660,7 +660,8 @@ describe('schemas', () => {
}, (error, response, body) => { }, (error, response, body) => {
expect(response.statusCode).toEqual(400); expect(response.statusCode).toEqual(400);
expect(body.code).toEqual(255); expect(body.code).toEqual(255);
expect(body.error).toEqual('class HasAllPOD not empty, contains 1 objects, cannot drop schema'); expect(body.error).toMatch(/HasAllPOD/);
expect(body.error).toMatch(/contains 1/);
done(); done();
}); });
}); });

View File

@@ -30,6 +30,13 @@ export class MongoStorageAdapter {
}); });
} }
dropCollection(name: string) {
return this.connect.then(() => this.collection(name).then(collection => collection.drop()));
}
dropCollection(name: string) {
return this.collection(name).then(collection => collection.drop());
}
// Used for testing only right now. // Used for testing only right now.
collectionsContaining(match: string) { collectionsContaining(match: string) {
return this.connect().then(() => { return this.connect().then(() => {

View File

@@ -42,6 +42,10 @@ DatabaseController.prototype.rawCollection = function(className) {
return this.adapter.collection(this.collectionPrefix + className); return this.adapter.collection(this.collectionPrefix + className);
}; };
DatabaseController.prototype.dropCollection = function(className) {
return this.adapter.dropCollection(this.collectionPrefix + className);
};
function returnsTrue() { function returnsTrue() {
return true; return true;
} }

View File

@@ -184,20 +184,12 @@ function modifySchema(req) {
} }
// A helper function that removes all join tables for a schema. Returns a promise. // A helper function that removes all join tables for a schema. Returns a promise.
var removeJoinTables = (database, prefix, mongoSchema) => { var removeJoinTables = (database, mongoSchema) => {
return Promise.all(Object.keys(mongoSchema) return Promise.all(Object.keys(mongoSchema)
.filter(field => mongoSchema[field].startsWith('relation<')) .filter(field => mongoSchema[field].startsWith('relation<'))
.map(field => { .map(field => {
var joinCollectionName = prefix + '_Join:' + field + ':' + mongoSchema._id; let collectionName = `_Join:${field}:${mongoSchema._id}`;
return new Promise((resolve, reject) => { return database.dropCollection(collectionName);
database.dropCollection(joinCollectionName, (err, results) => {
if (err) {
reject(err);
} else {
resolve();
}
})
});
}) })
); );
}; };
@@ -208,63 +200,43 @@ function deleteSchema(req) {
} }
if (!Schema.classNameIsValid(req.params.className)) { if (!Schema.classNameIsValid(req.params.className)) {
return Promise.resolve({ throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, Schema.invalidClassNameMessage(req.params.className));
status: 400,
response: {
code: Parse.Error.INVALID_CLASS_NAME,
error: Schema.invalidClassNameMessage(req.params.className),
}
});
} }
return req.config.database.collection(req.params.className) return req.config.database.collection(req.params.className)
.then(coll => new Promise((resolve, reject) => { .then(collection => {
coll.count((err, count) => { return collection.count()
if (err) { .then(count => {
reject(err); if (count > 0) {
} else if (count > 0) { throw new Parse.Error(255, `Class ${req.params.className} is not empty, contains ${count} objects, cannot drop schema.`);
resolve({
status: 400,
response: {
code: 255,
error: 'class ' + req.params.className + ' not empty, contains ' + count + ' objects, cannot drop schema',
} }
}); return collection.drop();
} else { })
coll.drop((err, reply) => { .then(() => {
if (err) { // We've dropped the collection now, so delete the item from _SCHEMA
reject(err); // and clear the _Join collections
} else { return req.config.database.collection('_SCHEMA')
// We've dropped the collection now, so delete the item from _SCHEMA .then(coll => coll.findAndRemove({_id: req.params.className}, []))
// and clear the _Join collections .then(doc => {
req.config.database.collection('_SCHEMA') if (doc.value === null) {
.then(coll => new Promise((resolve, reject) => { //tried to delete non-existent class
coll.findAndRemove({ _id: req.params.className }, [], (err, doc) => { return Promise.resolve();
if (err) { }
reject(err); return removeJoinTables(req.config.database, doc.value);
} else if (doc.value === null) { });
//tried to delete non-existant class })
resolve({ response: {}}); })
} else { .then(() => {
removeJoinTables(req.config.database.adapter.database, req.config.database.collectionPrefix, doc.value) // Success
.then(resolve, reject); return { response: {} };
} }, error => {
}); if (error.message == 'ns not found') {
})) // If they try to delete a non-existent class, that's fine, just let them.
.then(resolve.bind(undefined, {response: {}}), reject); return { response: {} };
}
});
} }
return Promise.reject(error);
}); });
}))
.catch( (error) => {
if (error.message == 'ns not found') {
// If they try to delete a non-existant class, thats fine, just let them.
return Promise.resolve({ response: {} });
}
return Promise.reject(error);
});
} }
export class SchemasRouter extends PromiseRouter { export class SchemasRouter extends PromiseRouter {