From 9459dd1820ceeef7cd98b4f93d8e3f0910446c29 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 28 Aug 2024 12:41:42 +0200 Subject: [PATCH] getSourceId returns table & view data --- .../src/api/controllers/row/external.ts | 8 +++--- .../server/src/api/controllers/row/index.ts | 27 +++++++++---------- .../src/api/controllers/row/internal.ts | 8 +++--- .../src/api/controllers/row/utils/utils.ts | 25 +++++++++-------- .../server/src/middleware/trimViewRowInfo.ts | 14 ++-------- packages/server/src/sdk/app/rows/search.ts | 3 +-- .../src/sdk/app/rows/search/external.ts | 8 ------ 7 files changed, 38 insertions(+), 55 deletions(-) diff --git a/packages/server/src/api/controllers/row/external.ts b/packages/server/src/api/controllers/row/external.ts index f596b60101..e14e2d454a 100644 --- a/packages/server/src/api/controllers/row/external.ts +++ b/packages/server/src/api/controllers/row/external.ts @@ -38,7 +38,7 @@ export async function handleRequest( } export async function patch(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const { _id, ...rowData } = ctx.request.body const table = await sdk.tables.getTable(tableId) @@ -93,7 +93,7 @@ export async function patch(ctx: UserCtx) { } export async function destroy(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const _id = ctx.request.body._id const { row } = await handleRequest(Operation.DELETE, tableId, { id: breakRowIdField(_id), @@ -104,7 +104,7 @@ export async function destroy(ctx: UserCtx) { export async function bulkDestroy(ctx: UserCtx) { const { rows } = ctx.request.body - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) let promises: Promise<{ row: Row; table: Table }>[] = [] for (let row of rows) { promises.push( @@ -123,7 +123,7 @@ export async function bulkDestroy(ctx: UserCtx) { export async function fetchEnrichedRow(ctx: UserCtx) { const id = ctx.params.rowId - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const { datasourceId, tableName } = breakExternalTableId(tableId) const datasource: Datasource = await sdk.datasources.get(datasourceId) if (!datasource || !datasource.entities) { diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index 17cc9dc339..7d6448ca6b 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -47,7 +47,7 @@ export async function patch( ctx: UserCtx ): Promise { const appId = ctx.appId - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const body = ctx.request.body // if it doesn't have an _id then its save @@ -72,7 +72,7 @@ export async function patch( export const save = async (ctx: UserCtx) => { const appId = ctx.appId - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const body = ctx.request.body // user metadata doesn't exist yet - don't allow creation @@ -98,12 +98,11 @@ export const save = async (ctx: UserCtx) => { } export async function fetchView(ctx: any) { - const tableId = utils.getSourceId(ctx) const viewName = decodeURIComponent(ctx.params.viewName) const { calculation, group, field } = ctx.query - ctx.body = await sdk.rows.fetchView(tableId, viewName, { + ctx.body = await sdk.rows.fetchView(viewName, { calculation, group: calculation ? group : null, field, @@ -111,12 +110,12 @@ export async function fetchView(ctx: any) { } export async function fetch(ctx: any) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) ctx.body = await sdk.rows.fetch(tableId) } export async function find(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const rowId = ctx.params.rowId ctx.body = await sdk.rows.find(tableId, rowId) @@ -132,7 +131,7 @@ function isDeleteRow(input: any): input is DeleteRow { async function processDeleteRowsRequest(ctx: UserCtx) { let request = ctx.request.body as DeleteRows - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const processedRows = request.rows.map(row => { let processedRow: Row = typeof row == "string" ? { _id: row } : row @@ -148,7 +147,7 @@ async function processDeleteRowsRequest(ctx: UserCtx) { } async function deleteRows(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const appId = ctx.appId let deleteRequest = ctx.request.body as DeleteRows @@ -170,7 +169,7 @@ async function deleteRows(ctx: UserCtx) { async function deleteRow(ctx: UserCtx) { const appId = ctx.appId - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const resp = await pickApi(tableId).destroy(ctx) if (!tableId.includes("datasource_plus")) { @@ -204,7 +203,7 @@ export async function destroy(ctx: UserCtx) { } export async function search(ctx: Ctx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) await context.ensureSnippetContext(true) @@ -226,7 +225,7 @@ export async function search(ctx: Ctx) { } export async function validate(ctx: Ctx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) // external tables are hard to validate currently if (isExternalTableID(tableId)) { ctx.body = { valid: true, errors: {} } @@ -239,14 +238,14 @@ export async function validate(ctx: Ctx) { } export async function fetchEnrichedRow(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) ctx.body = await pickApi(tableId).fetchEnrichedRow(ctx) } export const exportRows = async ( ctx: Ctx ) => { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const format = ctx.query.format @@ -279,7 +278,7 @@ export const exportRows = async ( export async function downloadAttachment(ctx: UserCtx) { const { columnName } = ctx.params - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const rowId = ctx.params.rowId const row = await sdk.rows.find(tableId, rowId) diff --git a/packages/server/src/api/controllers/row/internal.ts b/packages/server/src/api/controllers/row/internal.ts index 47540baca3..e698efe981 100644 --- a/packages/server/src/api/controllers/row/internal.ts +++ b/packages/server/src/api/controllers/row/internal.ts @@ -23,7 +23,7 @@ import { getLinkedTableIDs } from "../../../db/linkedRows/linkUtils" import { flatten } from "lodash" export async function patch(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const inputs = ctx.request.body const isUserTable = tableId === InternalTables.USER_METADATA let oldRow @@ -97,7 +97,7 @@ export async function patch(ctx: UserCtx) { export async function destroy(ctx: UserCtx) { const db = context.getAppDB() - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const { _id } = ctx.request.body let row = await db.get(_id) let _rev = ctx.request.body._rev || row._rev @@ -136,7 +136,7 @@ export async function destroy(ctx: UserCtx) { } export async function bulkDestroy(ctx: UserCtx) { - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const table = await sdk.tables.getTable(tableId) let { rows } = ctx.request.body @@ -178,7 +178,7 @@ export async function bulkDestroy(ctx: UserCtx) { export async function fetchEnrichedRow(ctx: UserCtx) { const fieldName = ctx.request.query.field as string | undefined const db = context.getAppDB() - const tableId = utils.getSourceId(ctx) + const { tableId } = utils.getSourceId(ctx) const rowId = ctx.params.rowId as string // need table to work out where links go in row, as well as the link docs const [table, links] = await Promise.all([ diff --git a/packages/server/src/api/controllers/row/utils/utils.ts b/packages/server/src/api/controllers/row/utils/utils.ts index f52385c73c..46bdbb7662 100644 --- a/packages/server/src/api/controllers/row/utils/utils.ts +++ b/packages/server/src/api/controllers/row/utils/utils.ts @@ -1,4 +1,4 @@ -import { InternalTables } from "../../../../db/utils" +import * as utils from "../../../../db/utils" import { context } from "@budibase/backend-core" import { @@ -67,7 +67,7 @@ export async function findRow(tableId: string, rowId: string) { const db = context.getAppDB() let row: Row // TODO remove special user case in future - if (tableId === InternalTables.USER_METADATA) { + if (tableId === utils.InternalTables.USER_METADATA) { row = await getFullUser(rowId) } else { row = await db.get(rowId) @@ -78,22 +78,25 @@ export async function findRow(tableId: string, rowId: string) { return row } -export function getSourceId(ctx: Ctx): string { +export function getSourceId(ctx: Ctx): { tableId: string; viewId?: string } { // top priority, use the URL first if (ctx.params?.sourceId) { - return ctx.params.sourceId + const { sourceId } = ctx.params + if (utils.isViewID(sourceId)) { + return { + tableId: utils.extractViewInfoFromID(sourceId).tableId, + viewId: sourceId, + } + } + return { tableId: ctx.params.sourceId } } // now check for old way of specifying table ID if (ctx.params?.tableId) { - return ctx.params.tableId + return { tableId: ctx.params.tableId } } // check body for a table ID if (ctx.request.body?.tableId) { - return ctx.request.body.tableId - } - // now check if a specific view name - if (ctx.params?.viewName) { - return ctx.params.viewName + return { tableId: ctx.request.body.tableId } } throw new Error("Unable to find table ID in request") } @@ -198,7 +201,7 @@ export async function sqlOutputProcessing( } export function isUserMetadataTable(tableId: string) { - return tableId === InternalTables.USER_METADATA + return tableId === utils.InternalTables.USER_METADATA } export async function enrichArrayContext( diff --git a/packages/server/src/middleware/trimViewRowInfo.ts b/packages/server/src/middleware/trimViewRowInfo.ts index cdcddf2cc9..55efaee732 100644 --- a/packages/server/src/middleware/trimViewRowInfo.ts +++ b/packages/server/src/middleware/trimViewRowInfo.ts @@ -1,33 +1,23 @@ import { Ctx, Row } from "@budibase/types" -import * as utils from "../db/utils" + import sdk from "../sdk" import { Next } from "koa" import { getSourceId } from "../api/controllers/row/utils" export default async (ctx: Ctx, next: Next) => { const { body } = ctx.request - let { _viewId: viewId } = body - - const possibleViewId = getSourceId(ctx) - if (utils.isViewID(possibleViewId)) { - viewId = possibleViewId - } + const viewId = getSourceId(ctx).viewId ?? body._viewId // nothing to do, it is not a view (just a table ID) if (!viewId) { return next() } - const { tableId } = utils.extractViewInfoFromID(viewId) - // don't need to trim delete requests if (ctx?.method?.toLowerCase() !== "delete") { await trimViewFields(ctx.request.body, viewId) } - ctx.params.sourceId = tableId - ctx.params.viewId = viewId - return next() } diff --git a/packages/server/src/sdk/app/rows/search.ts b/packages/server/src/sdk/app/rows/search.ts index 6a4286814d..4aa091ce10 100644 --- a/packages/server/src/sdk/app/rows/search.ts +++ b/packages/server/src/sdk/app/rows/search.ts @@ -122,9 +122,8 @@ export async function fetchRaw(tableId: string): Promise { } export async function fetchView( - tableId: string, viewName: string, params: ViewParams ): Promise { - return pickApi(tableId).fetchView(viewName, params) + return internal.fetchView(viewName, params) } diff --git a/packages/server/src/sdk/app/rows/search/external.ts b/packages/server/src/sdk/app/rows/search/external.ts index 07181d259b..992596ab34 100644 --- a/packages/server/src/sdk/app/rows/search/external.ts +++ b/packages/server/src/sdk/app/rows/search/external.ts @@ -272,11 +272,3 @@ export async function fetchRaw(tableId: string): Promise { }) return response.rows } - -export async function fetchView(viewName: string) { - // there are no views in external datasources, shouldn't ever be called - // for now just fetch - const split = viewName.split("all_") - const tableId = split[1] ? split[1] : split[0] - return fetch(tableId) -}