Fixes issue affecting deleting multiple fields of a Schema (#3735)
This commit is contained in:
committed by
Florent Vilmart
parent
2a5c20376a
commit
5e14147676
@@ -13,7 +13,6 @@
|
||||
// DatabaseController. This will let us replace the schema logic for
|
||||
// different databases.
|
||||
// TODO: hide all schema logic inside the database adapter.
|
||||
|
||||
const Parse = require('parse/node').Parse;
|
||||
|
||||
const defaultColumns = Object.freeze({
|
||||
@@ -465,18 +464,22 @@ export default class SchemaController {
|
||||
|
||||
// Finally we have checked to make sure the request is valid and we can start deleting fields.
|
||||
// Do all deletions first, then a single save to _SCHEMA collection to handle all additions.
|
||||
const deletePromises = [];
|
||||
const deletedFields = [];
|
||||
const insertedFields = [];
|
||||
Object.keys(submittedFields).forEach(fieldName => {
|
||||
if (submittedFields[fieldName].__op === 'Delete') {
|
||||
const promise = this.deleteField(fieldName, className, database);
|
||||
deletePromises.push(promise);
|
||||
deletedFields.push(fieldName);
|
||||
} else {
|
||||
insertedFields.push(fieldName);
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(deletePromises) // Delete Everything
|
||||
let deletePromise = Promise.resolve();
|
||||
if (deletedFields.length > 0) {
|
||||
deletePromise = this.deleteFields(deletedFields, className, database);
|
||||
}
|
||||
|
||||
return deletePromise // Delete Everything
|
||||
.then(() => this.reloadData({ clearCache: true })) // Reload our Schema, so we have all the new values
|
||||
.then(() => {
|
||||
const promises = insertedFields.map(fieldName => {
|
||||
@@ -647,24 +650,32 @@ export default class SchemaController {
|
||||
});
|
||||
}
|
||||
|
||||
// Delete a field, and remove that data from all objects. This is intended
|
||||
// maintain compatibility
|
||||
deleteField(fieldName, className, database) {
|
||||
return this.deleteFields([fieldName], className, database);
|
||||
}
|
||||
|
||||
// Delete fields, and remove that data from all objects. This is intended
|
||||
// to remove unused fields, if other writers are writing objects that include
|
||||
// this field, the field may reappear. Returns a Promise that resolves with
|
||||
// no object on success, or rejects with { code, error } on failure.
|
||||
// Passing the database and prefix is necessary in order to drop relation collections
|
||||
// and remove fields from objects. Ideally the database would belong to
|
||||
// a database adapter and this function would close over it or access it via member.
|
||||
deleteField(fieldName, className, database) {
|
||||
deleteFields(fieldNames, className, database) {
|
||||
if (!classNameIsValid(className)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className));
|
||||
}
|
||||
if (!fieldNameIsValid(fieldName)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`);
|
||||
}
|
||||
//Don't allow deleting the default fields.
|
||||
if (!fieldNameIsValidForClass(fieldName, className)) {
|
||||
throw new Parse.Error(136, `field ${fieldName} cannot be changed`);
|
||||
}
|
||||
|
||||
fieldNames.forEach(fieldName => {
|
||||
if (!fieldNameIsValid(fieldName)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`);
|
||||
}
|
||||
//Don't allow deleting the default fields.
|
||||
if (!fieldNameIsValidForClass(fieldName, className)) {
|
||||
throw new Parse.Error(136, `field ${fieldName} cannot be changed`);
|
||||
}
|
||||
});
|
||||
|
||||
return this.getOneSchema(className, false, {clearCache: true})
|
||||
.catch(error => {
|
||||
@@ -675,15 +686,24 @@ export default class SchemaController {
|
||||
}
|
||||
})
|
||||
.then(schema => {
|
||||
if (!schema.fields[fieldName]) {
|
||||
throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`);
|
||||
}
|
||||
if (schema.fields[fieldName].type == 'Relation') {
|
||||
//For relations, drop the _Join table
|
||||
return database.adapter.deleteFields(className, schema, [fieldName])
|
||||
.then(() => database.adapter.deleteClass(`_Join:${fieldName}:${className}`));
|
||||
}
|
||||
return database.adapter.deleteFields(className, schema, [fieldName]);
|
||||
fieldNames.forEach(fieldName => {
|
||||
if (!schema.fields[fieldName]) {
|
||||
throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`);
|
||||
}
|
||||
});
|
||||
|
||||
const schemaFields = { ...schema.fields };
|
||||
return database.adapter.deleteFields(className, schema, fieldNames)
|
||||
.then(() => {
|
||||
return Promise.all(fieldNames.map(fieldName => {
|
||||
const field = schemaFields[fieldName];
|
||||
if (field && field.type === 'Relation') {
|
||||
//For relations, drop the _Join table
|
||||
return database.adapter.deleteClass(`_Join:${fieldName}:${className}`);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}));
|
||||
});
|
||||
}).then(() => {
|
||||
this._cache.clear();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user