Fix for #5269 - the sub type was being lost in some scenarios related to the user table being updated - making sure it is consistently kept when dealing with either of the related tables.
This commit is contained in:
parent
d251a80123
commit
194b76985c
5 changed files with 75 additions and 11 deletions
|
@ -10,9 +10,30 @@ const {
|
||||||
const usageQuota = require("../../../utilities/usageQuota")
|
const usageQuota = require("../../../utilities/usageQuota")
|
||||||
const { getAppDB } = require("@budibase/backend-core/context")
|
const { getAppDB } = require("@budibase/backend-core/context")
|
||||||
const env = require("../../../environment")
|
const env = require("../../../environment")
|
||||||
const { cleanupAttachments } = require("../../../utilities/rowProcessor")
|
const {
|
||||||
|
cleanupAttachments,
|
||||||
|
fixAutoColumnSubType,
|
||||||
|
} = require("../../../utilities/rowProcessor")
|
||||||
const { runStaticFormulaChecks } = require("./bulkFormula")
|
const { runStaticFormulaChecks } = require("./bulkFormula")
|
||||||
|
|
||||||
|
function checkAutoColumns(table, oldTable) {
|
||||||
|
if (!table.schema) {
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
for (let [key, schema] of Object.entries(table.schema)) {
|
||||||
|
if (!schema.autocolumn || schema.subtype) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const oldSchema = oldTable.schema[key]
|
||||||
|
if (oldSchema && oldSchema.subtype) {
|
||||||
|
table.schema[key].subtype = oldSchema.subtype
|
||||||
|
} else {
|
||||||
|
table.schema[key] = fixAutoColumnSubType(schema)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return table
|
||||||
|
}
|
||||||
|
|
||||||
exports.save = async function (ctx) {
|
exports.save = async function (ctx) {
|
||||||
const db = getAppDB()
|
const db = getAppDB()
|
||||||
const { dataImport, ...rest } = ctx.request.body
|
const { dataImport, ...rest } = ctx.request.body
|
||||||
|
@ -29,9 +50,12 @@ exports.save = async function (ctx) {
|
||||||
oldTable = await db.get(ctx.request.body._id)
|
oldTable = await db.get(ctx.request.body._id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check all types are correct
|
||||||
if (hasTypeChanged(tableToSave, oldTable)) {
|
if (hasTypeChanged(tableToSave, oldTable)) {
|
||||||
ctx.throw(400, "A column type has changed.")
|
ctx.throw(400, "A column type has changed.")
|
||||||
}
|
}
|
||||||
|
// check that subtypes have been maintained
|
||||||
|
tableToSave = checkAutoColumns(tableToSave, oldTable)
|
||||||
|
|
||||||
// saving a table is a complex operation, involving many different steps, this
|
// saving a table is a complex operation, involving many different steps, this
|
||||||
// has been broken out into a utility to make it more obvious/easier to manipulate
|
// has been broken out into a utility to make it more obvious/easier to manipulate
|
||||||
|
|
|
@ -162,6 +162,14 @@ exports.AutoFieldSubTypes = {
|
||||||
AUTO_ID: "autoID",
|
AUTO_ID: "autoID",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.AutoFieldDefaultNames = {
|
||||||
|
CREATED_BY: "Created By",
|
||||||
|
CREATED_AT: "Created At",
|
||||||
|
UPDATED_BY: "Updated By",
|
||||||
|
UPDATED_AT: "Updated At",
|
||||||
|
AUTO_ID: "Auto ID",
|
||||||
|
}
|
||||||
|
|
||||||
exports.OBJ_STORE_DIRECTORY = "/prod-budi-app-assets"
|
exports.OBJ_STORE_DIRECTORY = "/prod-budi-app-assets"
|
||||||
exports.BaseQueryVerbs = {
|
exports.BaseQueryVerbs = {
|
||||||
CREATE: "create",
|
CREATE: "create",
|
||||||
|
|
|
@ -376,6 +376,7 @@ class LinkController {
|
||||||
|
|
||||||
if (field.autocolumn) {
|
if (field.autocolumn) {
|
||||||
linkedField.autocolumn = field.autocolumn
|
linkedField.autocolumn = field.autocolumn
|
||||||
|
linkedField.subtype = field.subtype
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the linked table to make sure we aren't overwriting an existing column
|
// check the linked table to make sure we aren't overwriting an existing column
|
||||||
|
|
|
@ -2,7 +2,7 @@ const linkRows = require("../../db/linkedRows")
|
||||||
const { cloneDeep } = require("lodash/fp")
|
const { cloneDeep } = require("lodash/fp")
|
||||||
const { FieldTypes, AutoFieldSubTypes } = require("../../constants")
|
const { FieldTypes, AutoFieldSubTypes } = require("../../constants")
|
||||||
const { attachmentsRelativeURL } = require("../index")
|
const { attachmentsRelativeURL } = require("../index")
|
||||||
const { processFormulas } = require("./utils")
|
const { processFormulas, fixAutoColumnSubType } = require("./utils")
|
||||||
const { deleteFiles } = require("../../utilities/fileSystem/utilities")
|
const { deleteFiles } = require("../../utilities/fileSystem/utilities")
|
||||||
const { ObjectStoreBuckets } = require("../../constants")
|
const { ObjectStoreBuckets } = require("../../constants")
|
||||||
const {
|
const {
|
||||||
|
@ -11,6 +11,7 @@ const {
|
||||||
dbExists,
|
dbExists,
|
||||||
} = require("@budibase/backend-core/db")
|
} = require("@budibase/backend-core/db")
|
||||||
const { getAppId } = require("@budibase/backend-core/context")
|
const { getAppId } = require("@budibase/backend-core/context")
|
||||||
|
const { InternalTables } = require("../../db/utils")
|
||||||
|
|
||||||
const BASE_AUTO_ID = 1
|
const BASE_AUTO_ID = 1
|
||||||
|
|
||||||
|
@ -137,21 +138,23 @@ function processAutoColumn(
|
||||||
opts = { reprocessing: false, noAutoRelationships: false }
|
opts = { reprocessing: false, noAutoRelationships: false }
|
||||||
) {
|
) {
|
||||||
let noUser = !user || !user.userId
|
let noUser = !user || !user.userId
|
||||||
|
let isUserTable = table._id === InternalTables.USER_METADATA
|
||||||
let now = new Date().toISOString()
|
let now = new Date().toISOString()
|
||||||
// if a row doesn't have a revision then it doesn't exist yet
|
// if a row doesn't have a revision then it doesn't exist yet
|
||||||
const creating = !row._rev
|
const creating = !row._rev
|
||||||
|
// check its not user table, or whether any of the processing options have been disabled
|
||||||
|
const shouldUpdateUserFields =
|
||||||
|
!isUserTable && !opts.reprocessing && !opts.noAutoRelationships && !noUser
|
||||||
for (let [key, schema] of Object.entries(table.schema)) {
|
for (let [key, schema] of Object.entries(table.schema)) {
|
||||||
if (!schema.autocolumn) {
|
if (!schema.autocolumn) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if (!schema.subtype) {
|
||||||
|
schema = fixAutoColumnSubType(schema)
|
||||||
|
}
|
||||||
switch (schema.subtype) {
|
switch (schema.subtype) {
|
||||||
case AutoFieldSubTypes.CREATED_BY:
|
case AutoFieldSubTypes.CREATED_BY:
|
||||||
if (
|
if (creating && shouldUpdateUserFields) {
|
||||||
creating &&
|
|
||||||
!opts.reprocessing &&
|
|
||||||
!opts.noAutoRelationships &&
|
|
||||||
!noUser
|
|
||||||
) {
|
|
||||||
row[key] = [user.userId]
|
row[key] = [user.userId]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -161,7 +164,7 @@ function processAutoColumn(
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case AutoFieldSubTypes.UPDATED_BY:
|
case AutoFieldSubTypes.UPDATED_BY:
|
||||||
if (!opts.reprocessing && !opts.noAutoRelationships && !noUser) {
|
if (shouldUpdateUserFields) {
|
||||||
row[key] = [user.userId]
|
row[key] = [user.userId]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -179,7 +182,7 @@ function processAutoColumn(
|
||||||
return { table, row }
|
return { table, row }
|
||||||
}
|
}
|
||||||
exports.processAutoColumn = processAutoColumn
|
exports.processAutoColumn = processAutoColumn
|
||||||
|
exports.fixAutoColumnSubType = fixAutoColumnSubType
|
||||||
exports.processFormulas = processFormulas
|
exports.processFormulas = processFormulas
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,34 @@
|
||||||
const { FieldTypes, FormulaTypes } = require("../../constants")
|
const {
|
||||||
|
FieldTypes,
|
||||||
|
FormulaTypes,
|
||||||
|
AutoFieldDefaultNames,
|
||||||
|
AutoFieldSubTypes,
|
||||||
|
} = require("../../constants")
|
||||||
const { processStringSync } = require("@budibase/string-templates")
|
const { processStringSync } = require("@budibase/string-templates")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the subtype has been lost for any reason this works out what
|
||||||
|
* subtype the auto column should be.
|
||||||
|
*/
|
||||||
|
exports.fixAutoColumnSubType = column => {
|
||||||
|
if (!column.autocolumn || !column.name || column.subtype) {
|
||||||
|
return column
|
||||||
|
}
|
||||||
|
// the columns which get auto generated
|
||||||
|
if (column.name.endsWith(AutoFieldDefaultNames.CREATED_BY)) {
|
||||||
|
column.subtype = AutoFieldSubTypes.CREATED_BY
|
||||||
|
} else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_BY)) {
|
||||||
|
column.subtype = AutoFieldSubTypes.UPDATED_BY
|
||||||
|
} else if (column.name.endsWith(AutoFieldDefaultNames.CREATED_AT)) {
|
||||||
|
column.subtype = AutoFieldSubTypes.CREATED_AT
|
||||||
|
} else if (column.name.endsWith(AutoFieldDefaultNames.UPDATED_AT)) {
|
||||||
|
column.subtype = AutoFieldSubTypes.UPDATED_AT
|
||||||
|
} else if (column.name.endsWith(AutoFieldDefaultNames.AUTO_ID)) {
|
||||||
|
column.subtype = AutoFieldSubTypes.AUTO_ID
|
||||||
|
}
|
||||||
|
return column
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks through the rows provided and finds formulas - which it then processes.
|
* Looks through the rows provided and finds formulas - which it then processes.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue