Addresses #5850 - when importing/migrating views and building new views it checks if calculations are used and if they are then it does an empty check to decide whether or not the fields should be included in the calculation, required for real CouchDB nodes.

This commit is contained in:
mike12345567 2022-05-13 18:09:39 +01:00
parent 0da2592077
commit 459e3c5edd
2 changed files with 28 additions and 11 deletions

View File

@ -7,6 +7,7 @@ const {
} = require("../../../db/utils")
const env = require("../../../environment")
const { getAppDB } = require("@budibase/backend-core/context")
const viewBuilder = require("./viewBuilder")
exports.getView = async viewName => {
const db = getAppDB()
@ -114,7 +115,8 @@ exports.deleteView = async viewName => {
exports.migrateToInMemoryView = async (db, viewName) => {
// delete the view initially
const designDoc = await db.get("_design/database")
const view = designDoc.views[viewName]
// run the view back through the view builder to update it
const view = viewBuilder(designDoc.views[viewName].meta)
delete designDoc.views[viewName]
await db.put(designDoc)
await exports.saveView(db, null, viewName, view)
@ -123,7 +125,7 @@ exports.migrateToInMemoryView = async (db, viewName) => {
exports.migrateToDesignView = async (db, viewName) => {
let view = await db.get(generateMemoryViewID(viewName))
const designDoc = await db.get("_design/database")
designDoc.views[viewName] = view.view
designDoc.views[viewName] = viewBuilder(view.view.meta)
await db.put(designDoc)
await db.remove(view._id, view._rev)
}

View File

@ -10,6 +10,12 @@ const TOKEN_MAP = {
OR: "||",
}
const CONDITIONS = {
EMPTY: "EMPTY",
NOT_EMPTY: "NOT_EMPTY",
CONTAINS: "CONTAINS",
}
const isEmptyExpression = key => {
return `(
doc["${key}"] === undefined ||
@ -77,13 +83,13 @@ function parseFilterExpression(filters) {
expression.push(TOKEN_MAP[filter.conjunction])
}
if (filter.condition === "CONTAINS") {
if (filter.condition === CONDITIONS.CONTAINS) {
expression.push(
`doc["${filter.key}"].${TOKEN_MAP[filter.condition]}("${filter.value}")`
)
} else if (filter.condition === "EMPTY") {
} else if (filter.condition === CONDITIONS.EMPTY) {
expression.push(isEmptyExpression(filter.key))
} else if (filter.condition === "NOT_EMPTY") {
} else if (filter.condition === CONDITIONS.NOT_EMPTY) {
expression.push(`!${isEmptyExpression(filter.key)}`)
} else {
const value =
@ -125,12 +131,6 @@ function viewTemplate({ field, tableId, groupBy, filters = [], calculation }) {
if (filters && filters.length > 0 && filters[0].conjunction) {
delete filters[0].conjunction
}
const parsedFilters = parseFilterExpression(filters)
const filterExpression = parsedFilters ? `&& (${parsedFilters})` : ""
const emitExpression = parseEmitExpression(field, groupBy)
const reduction = field && calculation ? { reduce: `_${calculation}` } : {}
let schema = null
@ -139,8 +139,23 @@ function viewTemplate({ field, tableId, groupBy, filters = [], calculation }) {
...(groupBy ? GROUP_PROPERTY : FIELD_PROPERTY),
...SCHEMA_MAP[calculation],
}
if (
!filters.find(
filter =>
filter.key === field && filter.condition === CONDITIONS.NOT_EMPTY
)
) {
filters.push({ key: field, condition: CONDITIONS.NOT_EMPTY })
}
}
const parsedFilters = parseFilterExpression(filters)
const filterExpression = parsedFilters ? `&& (${parsedFilters})` : ""
const emitExpression = parseEmitExpression(field, groupBy)
const reduction = field && calculation ? { reduce: `_${calculation}` } : {}
return {
meta: {
field,