budibase/packages/server/src/sdk/app/rows/internal.ts

85 lines
2.4 KiB
TypeScript
Raw Normal View History

import { context, db, HTTPError } from "@budibase/backend-core"
import { Row, Table, ViewV2 } from "@budibase/types"
2023-12-20 15:41:25 +01:00
import sdk from "../../../sdk"
2023-12-20 16:25:08 +01:00
import { finaliseRow } from "../../../api/controllers/row/staticFormula"
2024-07-23 15:16:15 +02:00
import {
inputProcessing,
outputProcessing,
} from "../../../utilities/rowProcessor"
2023-12-20 15:41:25 +01:00
import * as linkRows from "../../../db/linkedRows"
2024-07-23 15:16:15 +02:00
import { InternalTables } from "../../../db/utils"
import { getFullUser } from "../../../utilities/users"
import { getSource, tryExtractingTableAndViewId } from "./utils"
import { helpers } from "@budibase/shared-core"
2023-12-20 15:41:25 +01:00
export async function save(
2024-08-29 12:16:44 +02:00
tableOrViewId: string,
2023-12-20 15:41:25 +01:00
inputs: Row,
userId: string | undefined
) {
2024-08-29 12:16:44 +02:00
const { tableId, viewId } = tryExtractingTableAndViewId(tableOrViewId)
2023-12-20 15:41:25 +01:00
inputs.tableId = tableId
let source: Table | ViewV2
let table: Table
if (viewId) {
source = await sdk.views.get(viewId)
table = await sdk.views.getTable(viewId)
} else {
source = await sdk.tables.getTable(tableId)
table = source
}
if (sdk.views.isView(source) && helpers.views.isCalculationView(source)) {
throw new HTTPError("Cannot insert rows through a calculation view", 400)
}
2023-12-20 15:41:25 +01:00
if (!inputs._rev && !inputs._id) {
inputs._id = db.generateRowID(inputs.tableId)
}
2024-09-26 16:48:44 +02:00
let row = await inputProcessing(userId, source, inputs)
2023-12-20 15:41:25 +01:00
const validateResult = await sdk.rows.utils.validate({
row,
source,
2023-12-20 15:41:25 +01:00
})
if (!validateResult.valid) {
throw { validation: validateResult.errors }
}
// make sure link rows are up-to-date
row = (await linkRows.updateLinks({
eventType: linkRows.EventType.ROW_SAVE,
row,
tableId: row.tableId,
table,
})) as Row
2024-09-24 18:46:38 +02:00
return finaliseRow(source, row, { updateFormula: true })
2023-12-20 15:41:25 +01:00
}
2024-07-23 15:16:15 +02:00
export async function find(sourceId: string, rowId: string): Promise<Row> {
const source = await getSource(sourceId)
return await outputProcessing(source, await findRow(sourceId, rowId), {
squash: true,
})
2024-07-23 15:16:15 +02:00
}
export async function findRow(sourceId: string, rowId: string) {
const { tableId } = tryExtractingTableAndViewId(sourceId)
2024-07-23 15:16:15 +02:00
const db = context.getAppDB()
let row: Row
// TODO remove special user case in future
if (tableId === InternalTables.USER_METADATA) {
row = await getFullUser(rowId)
} else {
row = await db.get(rowId)
}
if (row.tableId !== tableId) {
throw "Supplied tableId does not match the rows tableId"
}
return row
}