From 58ff985a351e4f1c8658242c75382037103ebf13 Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Thu, 1 Oct 2020 11:33:37 +0100 Subject: [PATCH 1/2] Resolving issues with deleting a linked column, should now be possible. --- .../src/db/linkedRecords/LinkController.js | 17 +++++++------- packages/server/src/db/linkedRecords/index.js | 22 +++++++++---------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/server/src/db/linkedRecords/LinkController.js b/packages/server/src/db/linkedRecords/LinkController.js index c43b116571..f5967daad5 100644 --- a/packages/server/src/db/linkedRecords/LinkController.js +++ b/packages/server/src/db/linkedRecords/LinkController.js @@ -38,12 +38,13 @@ function LinkDocument( } class LinkController { - constructor({ instanceId, modelId, record, model }) { + constructor({ instanceId, modelId, record, model, oldModel }) { this._instanceId = instanceId this._db = new CouchDB(instanceId) this._modelId = modelId this._record = record this._model = model + this._oldModel = oldModel } /** @@ -192,12 +193,12 @@ class LinkController { * @returns {Promise} The model has now been updated. */ async removeFieldFromModel(fieldName) { - let model = await this.model() - let field = model.schema[fieldName] + let oldModel = this._oldModel + let field = oldModel.schema[fieldName] const linkDocs = await this.getModelLinkDocs(IncludeDocs.INCLUDE) let toDelete = linkDocs.filter(linkDoc => { let correctFieldName = - linkDoc.doc1.modelId === model._id + linkDoc.doc1.modelId === oldModel._id ? linkDoc.doc1.fieldName : linkDoc.doc2.fieldName return correctFieldName === fieldName @@ -211,8 +212,8 @@ class LinkController { }) ) // remove schema from other model - let linkedModel = this._db.get(field.modelId) - delete linkedModel[field.fieldName] + let linkedModel = await this._db.get(field.modelId) + delete linkedModel.schema[field.fieldName] this._db.put(linkedModel) } @@ -246,10 +247,10 @@ class LinkController { /** * Update a model, this means if a field is removed need to handle removing from other table and removing * any link docs that pertained to it. - * @param {object} oldModel The model before it was updated which can be used for differencing. * @returns {Promise} The model which has been saved, same response as with the modelSaved function. */ - async modelUpdated(oldModel) { + async modelUpdated() { + const oldModel = this._oldModel // first start by checking if any link columns have been deleted const newModel = await this.model() for (let fieldName of Object.keys(oldModel.schema)) { diff --git a/packages/server/src/db/linkedRecords/index.js b/packages/server/src/db/linkedRecords/index.js index be501e3653..115553696c 100644 --- a/packages/server/src/db/linkedRecords/index.js +++ b/packages/server/src/db/linkedRecords/index.js @@ -33,24 +33,22 @@ exports.createLinkView = createLinkView * @returns {Promise} When the update is complete this will respond successfully. Returns the record for * record operations and the model for model operations. */ -exports.updateLinks = async ({ +exports.updateLinks = async function({ eventType, instanceId, record, modelId, model, oldModel, -}) => { - // make sure model ID is set - if (model != null) { - modelId = model._id +}) { + if (instanceId == null) { + throw "Cannot operate without an instance ID." } - let linkController = new LinkController({ - instanceId, - modelId, - model, - record, - }) + // make sure model ID is set + if (modelId == null && model != null) { + arguments[0].modelId = model._id + } + let linkController = new LinkController(arguments[0]) if ( !(await linkController.doesModelHaveLinkedFields()) && (oldModel == null || @@ -67,7 +65,7 @@ exports.updateLinks = async ({ case EventType.MODEL_SAVE: return await linkController.modelSaved() case EventType.MODEL_UPDATED: - return await linkController.modelUpdated(oldModel) + return await linkController.modelUpdated() case EventType.MODEL_DELETE: return await linkController.modelDeleted() default: From d1fa921c27b09970c3363d177be4d76664f47b35 Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Thu, 1 Oct 2020 11:49:49 +0100 Subject: [PATCH 2/2] Adding validation so that a linked column and a primary display column cannot be renamed. --- packages/server/src/api/controllers/model.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/server/src/api/controllers/model.js b/packages/server/src/api/controllers/model.js index b046a2f3a8..df6c794109 100644 --- a/packages/server/src/api/controllers/model.js +++ b/packages/server/src/api/controllers/model.js @@ -34,7 +34,11 @@ exports.save = async function(ctx) { // rename record fields when table column is renamed const { _rename } = modelToSave - if (_rename) { + if (_rename && modelToSave.schema[_rename.updated].type === "link") { + throw "Cannot rename a linked field." + } else if (_rename && modelToSave.primaryDisplay === _rename.old) { + throw "Cannot rename the primary display field." + } else if (_rename) { const records = await db.query(`database/all_${modelToSave._id}`, { include_docs: true, })