Merge branch 'feature/relationship-enrichment' of github.com:Budibase/budibase into feature/relationship-enrichment
This commit is contained in:
commit
142dc20277
|
@ -4,11 +4,13 @@ const {
|
||||||
getLinkDocuments,
|
getLinkDocuments,
|
||||||
createLinkView,
|
createLinkView,
|
||||||
getUniqueByProp,
|
getUniqueByProp,
|
||||||
|
getRelatedTableForField,
|
||||||
|
getLinkedTableIDs,
|
||||||
|
getLinkedTable,
|
||||||
} = require("./linkUtils")
|
} = require("./linkUtils")
|
||||||
const { flatten } = require("lodash")
|
const { flatten } = require("lodash")
|
||||||
const CouchDB = require("../../db")
|
const CouchDB = require("../../db")
|
||||||
const { getMultiIDParams } = require("../../db/utils")
|
const { getMultiIDParams } = require("../../db/utils")
|
||||||
const { FieldTypes } = require("../../constants")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This functionality makes sure that when rows with links are created, updated or deleted they are processed
|
* This functionality makes sure that when rows with links are created, updated or deleted they are processed
|
||||||
|
@ -30,26 +32,6 @@ exports.IncludeDocs = IncludeDocs
|
||||||
exports.getLinkDocuments = getLinkDocuments
|
exports.getLinkDocuments = getLinkDocuments
|
||||||
exports.createLinkView = createLinkView
|
exports.createLinkView = createLinkView
|
||||||
|
|
||||||
function getLinkedTableIDs(table) {
|
|
||||||
return Object.values(table.schema)
|
|
||||||
.filter(column => column.type === FieldTypes.LINK)
|
|
||||||
.map(column => column.tableId)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRelatedTableForField(table, fieldName) {
|
|
||||||
// look to see if its on the table, straight in the schema
|
|
||||||
const field = table.schema[fieldName]
|
|
||||||
if (field != null) {
|
|
||||||
return field.tableId
|
|
||||||
}
|
|
||||||
for (let column of Object.values(table.schema)) {
|
|
||||||
if (column.type === FieldTypes.LINK && column.fieldName === fieldName) {
|
|
||||||
return column.tableId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getLinksForRows(appId, rows) {
|
async function getLinksForRows(appId, rows) {
|
||||||
const tableIds = [...new Set(rows.map(el => el.tableId))]
|
const tableIds = [...new Set(rows.map(el => el.tableId))]
|
||||||
// start by getting all the link values for performance reasons
|
// start by getting all the link values for performance reasons
|
||||||
|
@ -172,7 +154,6 @@ exports.attachLinkedPrimaryDisplay = async (appId, table, rows) => {
|
||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
const db = new CouchDB(appId)
|
const db = new CouchDB(appId)
|
||||||
const linkedTables = await Promise.all(linkedTableIds.map(id => db.get(id)))
|
|
||||||
const links = (await getLinksForRows(appId, rows)).filter(link =>
|
const links = (await getLinksForRows(appId, rows)).filter(link =>
|
||||||
rows.some(row => row._id === link.thisId)
|
rows.some(row => row._id === link.thisId)
|
||||||
)
|
)
|
||||||
|
@ -180,27 +161,26 @@ exports.attachLinkedPrimaryDisplay = async (appId, table, rows) => {
|
||||||
const linked = (await db.allDocs(getMultiIDParams(linkedRowIds))).rows.map(
|
const linked = (await db.allDocs(getMultiIDParams(linkedRowIds))).rows.map(
|
||||||
row => row.doc
|
row => row.doc
|
||||||
)
|
)
|
||||||
|
// will populate this as we find them
|
||||||
|
const linkedTables = []
|
||||||
for (let row of rows) {
|
for (let row of rows) {
|
||||||
links
|
for (let link of links.filter(link => link.thisId === row._id)) {
|
||||||
.filter(link => link.thisId === row._id)
|
if (row[link.fieldName] == null) {
|
||||||
.forEach(link => {
|
row[link.fieldName] = []
|
||||||
if (row[link.fieldName] == null) {
|
}
|
||||||
row[link.fieldName] = []
|
const linkedRow = linked.find(row => row._id === link.id)
|
||||||
}
|
const linkedTableId =
|
||||||
const linkedTableId = getRelatedTableForField(table, link.fieldName)
|
linkedRow.tableId || getRelatedTableForField(table, link.fieldName)
|
||||||
const linkedRow = linked.find(row => row._id === link.id)
|
const linkedTable = await getLinkedTable(db, linkedTableId, linkedTables)
|
||||||
const linkedTable = linkedTables.find(
|
if (!linkedRow || !linkedTable) {
|
||||||
table => table._id === linkedTableId
|
continue
|
||||||
)
|
}
|
||||||
if (!linkedRow || !linkedTable) {
|
// need to handle an edge case where relationship just wasn't found
|
||||||
return
|
const value = linkedRow[linkedTable.primaryDisplay] || linkedRow._id
|
||||||
}
|
if (value) {
|
||||||
// need to handle an edge case where relationship just wasn't found
|
row[link.fieldName].push(value)
|
||||||
const value = linkedRow[linkedTable.primaryDisplay] || linkedRow._id
|
}
|
||||||
if (value) {
|
}
|
||||||
row[link.fieldName].push(value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const CouchDB = require("../index")
|
const CouchDB = require("../index")
|
||||||
const Sentry = require("@sentry/node")
|
const Sentry = require("@sentry/node")
|
||||||
const { ViewNames, getQueryIndex } = require("../utils")
|
const { ViewNames, getQueryIndex } = require("../utils")
|
||||||
|
const { FieldTypes } = require("../../constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only needed so that boolean parameters are being used for includeDocs
|
* Only needed so that boolean parameters are being used for includeDocs
|
||||||
|
@ -120,3 +121,35 @@ exports.getUniqueByProp = (array, prop) => {
|
||||||
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos
|
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.getLinkedTableIDs = table => {
|
||||||
|
return Object.values(table.schema)
|
||||||
|
.filter(column => column.type === FieldTypes.LINK)
|
||||||
|
.map(column => column.tableId)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getLinkedTable = async (db, id, tables) => {
|
||||||
|
let linkedTable = tables.find(table => table._id === id)
|
||||||
|
if (linkedTable) {
|
||||||
|
return linkedTable
|
||||||
|
}
|
||||||
|
linkedTable = await db.get(id)
|
||||||
|
if (linkedTable) {
|
||||||
|
tables.push(linkedTable)
|
||||||
|
}
|
||||||
|
return linkedTable
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getRelatedTableForField = (table, fieldName) => {
|
||||||
|
// look to see if its on the table, straight in the schema
|
||||||
|
const field = table.schema[fieldName]
|
||||||
|
if (field != null) {
|
||||||
|
return field.tableId
|
||||||
|
}
|
||||||
|
for (let column of Object.values(table.schema)) {
|
||||||
|
if (column.type === FieldTypes.LINK && column.fieldName === fieldName) {
|
||||||
|
return column.tableId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue