Browse Source

Fixing automation integration and various components around forms.

pull/4023/head
mike12345567 5 years ago
parent
commit
295c3ef1a3
  1. 48
      packages/server/src/api/controllers/row/external.js
  2. 10
      packages/server/src/automations/automationUtils.js
  3. 1
      packages/server/src/integrations/postgres.js
  4. 16
      packages/server/src/integrations/utils.js

48
packages/server/src/api/controllers/row/external.js

@ -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) {

10
packages/server/src/automations/automationUtils.js

@ -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 })
}

1
packages/server/src/integrations/postgres.js

@ -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 = {

16
packages/server/src/integrations/utils.js

@ -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))
}

Loading…
Cancel
Save