Fixing automation integration and various components around forms.

This commit is contained in:
mike12345567 2021-06-16 18:38:00 +01:00
parent efafe5d243
commit 295c3ef1a3
4 changed files with 60 additions and 15 deletions

View File

@ -1,7 +1,11 @@
const { makeExternalQuery } = require("./utils")
const { DataSourceOperation, SortDirection } = require("../../../constants")
const { getExternalTable } = require("../table/utils")
const { breakExternalTableId } = require("../../../integrations/utils")
const {
breakExternalTableId,
generateRowIdField,
breakRowIdField
} = require("../../../integrations/utils")
function inputProcessing(row, table) {
if (!row) {
@ -29,20 +33,35 @@ function outputProcessing(rows, table) {
for (let field of primary) {
idParts.push(row[field])
}
row._id = idParts
row._id = generateRowIdField(idParts)
row.tableId = table._id
}
return rows
}
function buildIDFilter(id, table) {
function buildFilters(id, filters, table) {
const primary = table.primary
if (filters) {
// need to map over the filters and make sure the _id field isn't present
for (let filter of Object.values(filters)) {
if (filter._id) {
const parts = breakRowIdField(filter._id)
for (let field of primary) {
filter[field] = parts.shift()
}
}
// make sure this field doesn't exist on any filter
delete filter._id
}
}
// there is no id, just use the user provided filters
if (!id || !table) {
return null
return filters
}
// if used as URL parameter it will have been joined
if (typeof id === "string") {
id = id.split(",")
id = breakRowIdField(id)
}
const primary = table.primary
const equal = {}
for (let field of primary) {
// work through the ID and get the parts
@ -65,10 +84,9 @@ async function handleRequest(
throw `Unable to process query, table "${tableName}" not defined.`
}
// clean up row on ingress using schema
filters = buildFilters(id, filters, table)
row = inputProcessing(row, table)
// try and build an id filter if required
let idFilters = buildIDFilter(id, table)
if (operation === DataSourceOperation.DELETE && Object.keys(idFilters).length === 0) {
if (operation === DataSourceOperation.DELETE && Object.keys(filters).length === 0) {
throw "Deletion must be filtered in someway"
}
let json = {
@ -81,7 +99,7 @@ async function handleRequest(
// not specifying any fields means "*"
fields: [],
},
filters: idFilters != null ? idFilters : filters,
filters,
sort,
paginate,
body: row,
@ -103,7 +121,7 @@ exports.patch = async ctx => {
const appId = ctx.appId
const inputs = ctx.request.body
const tableId = ctx.params.tableId
const id = inputs._id
const id = breakRowIdField(inputs._id)
// don't save the ID to db
delete inputs._id
return handleRequest(appId, DataSourceOperation.UPDATE, tableId, {
@ -150,7 +168,7 @@ exports.destroy = async ctx => {
const appId = ctx.appId
const tableId = ctx.params.tableId
return handleRequest(appId, DataSourceOperation.DELETE, tableId, {
id: ctx.request.body._id,
id: breakRowIdField(ctx.request.body._id),
})
}
@ -163,7 +181,7 @@ exports.bulkDestroy = async ctx => {
for (let row of rows) {
promises.push(
handleRequest(appId, DataSourceOperation.DELETE, tableId, {
id: row._id,
id: breakRowIdField(row._id),
})
)
}
@ -182,6 +200,10 @@ exports.search = async ctx => {
// todo: need to handle bookmarks
page: params.bookmark,
}
} else if (params && params.limit) {
paginateObj = {
limit: params.limit,
}
}
let sort
if (params.sort) {

View File

@ -1,4 +1,6 @@
const CouchDB = require("../db")
const { isExternalTable, breakExternalTableId } = require("../integrations/utils")
const { getExternalTable } = require("../api/controllers/table/utils")
/**
* When values are input to the system generally they will be of type string as this is required for template strings.
@ -60,7 +62,13 @@ module.exports.cleanInputValues = (inputs, schema) => {
*/
module.exports.cleanUpRow = async (appId, tableId, row) => {
const db = new CouchDB(appId)
const table = await db.get(tableId)
let table
if (isExternalTable(tableId)) {
const { datasourceId, tableName } = breakExternalTableId(tableId)
table = await getExternalTable(appId, datasourceId, tableName)
} else {
table = await db.get(tableId)
}
return module.exports.cleanInputValues(row, { properties: table.schema })
}

View File

@ -2,7 +2,6 @@ const { Pool } = require("pg")
const { FIELD_TYPES } = require("./Integration")
const Sql = require("./base/sql")
const { FieldTypes } = require("../constants")
const { SEPARATOR } = require("@budibase/auth/db")
const { buildExternalTableId } = require("./utils")
const SCHEMA = {

View File

@ -16,3 +16,19 @@ exports.breakExternalTableId = tableId => {
let datasourceId = parts.join(DOUBLE_SEPARATOR)
return { datasourceId, tableName }
}
exports.generateRowIdField = (keyProps = []) => {
if (!Array.isArray(keyProps)) {
keyProps = [keyProps]
}
// this conserves order and types
return encodeURIComponent(JSON.stringify(keyProps))
}
// should always return an array
exports.breakRowIdField = _id => {
if (!_id) {
return null
}
return JSON.parse(decodeURIComponent(_id))
}