Browse Source

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.

master
mike12345567 4 years ago
parent
commit
22c57cdc0c
  1. 6
      packages/server/src/api/controllers/view/utils.js
  2. 33
      packages/server/src/api/controllers/view/viewBuilder.js

6
packages/server/src/api/controllers/view/utils.js

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

33
packages/server/src/api/controllers/view/viewBuilder.js

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

Loading…
Cancel
Save