Merge pull request #3102 from Budibase/fix/view-column-renaming

Keep views in sync with table schema changes
This commit is contained in:
Andrew Kingston 2021-10-21 12:32:07 +01:00 committed by GitHub
commit 85f020d61f
2 changed files with 88 additions and 14 deletions

View File

@ -82,34 +82,30 @@
function isMultipleChoice(field) { function isMultipleChoice(field) {
return ( return (
(viewTable.schema[field].constraints && viewTable.schema[field]?.constraints?.inclusion?.length ||
viewTable.schema[field].constraints.inclusion && viewTable.schema[field]?.type === "boolean"
viewTable.schema[field].constraints.inclusion.length) ||
viewTable.schema[field].type === "boolean"
) )
} }
function fieldOptions(field) { function fieldOptions(field) {
return viewTable.schema[field].type === "options" return viewTable.schema[field]?.type === "options"
? viewTable.schema[field].constraints.inclusion ? viewTable.schema[field]?.constraints.inclusion
: [true, false] : [true, false]
} }
function isDate(field) { function isDate(field) {
return viewTable.schema[field].type === "datetime" return viewTable.schema[field]?.type === "datetime"
} }
function isNumber(field) { function isNumber(field) {
return viewTable.schema[field].type === "number" return viewTable.schema[field]?.type === "number"
} }
const fieldChanged = filter => ev => { const fieldChanged = filter => ev => {
// reset if type changed // Reset if type changed
if ( const oldType = viewTable.schema[filter.key]?.type
filter.key && const newType = viewTable.schema[ev.detail]?.type
ev.detail && if (filter.key && ev.detail && oldType !== newType) {
viewTable.schema[filter.key].type !== viewTable.schema[ev.detail].type
) {
filter.value = "" filter.value = ""
} }
} }

View File

@ -13,6 +13,8 @@ const {
isExternalTable, isExternalTable,
breakExternalTableId, breakExternalTableId,
} = require("../../../integrations/utils") } = require("../../../integrations/utils")
const { getViews, saveView } = require("../view/utils")
const viewTemplate = require("../view/viewBuilder")
exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => { exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
let updatedRows = [] let updatedRows = []
@ -25,6 +27,7 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
} }
// check for renaming of columns or deleted columns // check for renaming of columns or deleted columns
if (rename || deletedColumns.length !== 0) { if (rename || deletedColumns.length !== 0) {
// Update all rows
const rows = await db.allDocs( const rows = await db.allDocs(
getRowParams(updatedTable._id, null, { getRowParams(updatedTable._id, null, {
include_docs: true, include_docs: true,
@ -39,6 +42,9 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => {
} }
return doc return doc
}) })
// Update views
await exports.checkForViewUpdates(db, updatedTable, rename, deletedColumns)
delete updatedTable._rename delete updatedTable._rename
} }
return { rows: updatedRows, table: updatedTable } return { rows: updatedRows, table: updatedTable }
@ -237,4 +243,76 @@ exports.getTable = async (appId, tableId) => {
} }
} }
exports.checkForViewUpdates = async (db, table, rename, deletedColumns) => {
const views = await getViews(db)
const tableViews = views.filter(view => view.meta.tableId === table._id)
// Check each table view to see if impacted by this table action
for (let view of tableViews) {
let needsUpdated = false
// First check for renames, otherwise check for deletions
if (rename) {
// Update calculation field if required
if (view.meta.field === rename.old) {
view.meta.field = rename.updated
needsUpdated = true
}
// Update group by field if required
if (view.meta.groupBy === rename.old) {
view.meta.groupBy = rename.updated
needsUpdated = true
}
// Update filters if required
if (view.meta.filters) {
view.meta.filters.forEach(filter => {
if (filter.key === rename.old) {
filter.key = rename.updated
needsUpdated = true
}
})
}
} else if (deletedColumns) {
deletedColumns.forEach(column => {
// Remove calculation statement if required
if (view.meta.field === column) {
delete view.meta.field
delete view.meta.calculation
delete view.meta.groupBy
needsUpdated = true
}
// Remove group by field if required
if (view.meta.groupBy === column) {
delete view.meta.groupBy
needsUpdated = true
}
// Remove filters referencing deleted field if required
if (view.meta.filters && view.meta.filters.length) {
const initialLength = view.meta.filters.length
view.meta.filters = view.meta.filters.filter(filter => {
return filter.key !== column
})
if (initialLength !== view.meta.filters.length) {
needsUpdated = true
}
}
})
}
// Update view if required
if (needsUpdated) {
const newViewTemplate = viewTemplate(view.meta)
await saveView(db, null, view.name, newViewTemplate)
if (!newViewTemplate.meta.schema) {
newViewTemplate.meta.schema = table.schema
}
table.views[view.name] = newViewTemplate.meta
}
}
}
exports.TableSaveFunctions = TableSaveFunctions exports.TableSaveFunctions = TableSaveFunctions