diff --git a/lib/model/query/entities.js b/lib/model/query/entities.js index 36e638ac7..272cbee6a 100644 --- a/lib/model/query/entities.js +++ b/lib/model/query/entities.js @@ -206,6 +206,29 @@ const _checkHeldSubmission = (maybeOne, branchId, branchBaseVersion) => maybeOne WHERE "branchId"=${branchId} AND "branchBaseVersion" = ${branchBaseVersion} RETURNING *`); +// Used by _updateVerison below to figure out the intended base version in Central +// based on the branchId, trunkVersion, and baseVersion in the submission +const _computeBaseVersion = async (maybeOne, run, dataset, clientEntity, submissionDef) => { + if (!clientEntity.def.trunkVersion || clientEntity.def.baseVersion === clientEntity.def.trunkVersion) { + // trunk and client baseVersion are the same, indicating the start of a batch + return clientEntity.def.baseVersion; + } else { + const condition = { datasetId: dataset.id, uuid: clientEntity.uuid, + branchId: clientEntity.def.branchId, + branchBaseVersion: clientEntity.def.baseVersion - 1 }; + + // eslint-disable-next-line no-use-before-define + const previousInBranch = (await _getDef(maybeOne, new QueryOptions({ condition }))); + if (!previousInBranch.isDefined()) { + // not ready to process this submission. eventually hold it for later. + await _holdSubmission(run, submissionDef.submissionId, submissionDef.id, clientEntity.def.branchId, clientEntity.def.baseVersion); + return null; + } else { + return previousInBranch.get().version; + } + } +}; + const _createEntity = (dataset, entityData, submissionId, submissionDef, submissionDefId, event, parentEvent) => async ({ Audits, Entities }) => { // If dataset requires approval on submission to create an entity and this event is not // an approval event, then don't create an entity @@ -257,26 +280,14 @@ const _updateEntity = (dataset, entityData, submissionId, submissionDef, submiss let { conflict } = serverEntity; let conflictingProperties; // Maybe we don't need to persist this??? just compute at the read time - // TODO: comments about what is happening here - let baseVersion; - if (!clientEntity.def.trunkVersion || clientEntity.def.baseVersion === clientEntity.def.trunkVersion) { - // trunk and client baseVersion are the same, indicating the start of a batch - baseVersion = clientEntity.def.baseVersion; - } else { - const condition = { datasetId: dataset.id, uuid: clientEntity.uuid, - branchId: clientEntity.def.branchId, - branchBaseVersion: clientEntity.def.baseVersion - 1 }; + // Figure out the intended baseVersion + // If this is an offline update with a branchId, the baseVersion value is local to that + // offline context and we need to translate it to the correct base version within Central. + const baseVersion = await _computeBaseVersion(maybeOne, run, dataset, clientEntity, submissionDef); - // eslint-disable-next-line no-use-before-define - const previousInBranch = (await _getDef(maybeOne, new QueryOptions({ condition }))); - if (!previousInBranch.isDefined()) { - // not ready to process this submission. eventually hold it for later. - await _holdSubmission(run, submissionDef.submissionId, submissionDef.id, clientEntity.def.branchId, clientEntity.def.baseVersion); - return null; - } else { - baseVersion = previousInBranch.get().version; - } - } + // If baseVersion is null, we held a submission and will stop processing now. + if (baseVersion == null) + return; if (baseVersion !== serverEntity.aux.currentVersion.version) {