diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index 46aec4e11c..0f0d99f1c3 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -115,10 +115,11 @@ export async function fetch(ctx: any) { } export async function find(ctx: UserCtx) { - const { tableId } = utils.getSourceId(ctx) + const { sourceId } = ctx.params const rowId = ctx.params.rowId - ctx.body = await sdk.rows.find(tableId, rowId) + const response = await sdk.rows.find(sourceId, rowId) + ctx.body = response } function isDeleteRows(input: any): input is DeleteRows { diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index c289d3251a..129e1e25d2 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -2596,7 +2596,7 @@ describe.each([ }) const testScenarios: [string, (row: Row) => Promise | Row][] = [ - // ["get row", (row: Row) => config.api.row.get(viewId, row._id!)], + ["get row", (row: Row) => config.api.row.get(viewId, row._id!)], // [ // "fetch", // async (row: Row) => { @@ -2690,7 +2690,7 @@ describe.each([ async () => { const otherRows = _.sampleSize(auxData, 5) - const row = await config.api.row.save(tableId, { + const row = await config.api.row.save(viewId, { title: generator.word(), relWithNoSchema: [otherRows[0]], relWithEmptySchema: [otherRows[1]], diff --git a/packages/server/src/sdk/app/rows/external.ts b/packages/server/src/sdk/app/rows/external.ts index f81d67f621..770284d55a 100644 --- a/packages/server/src/sdk/app/rows/external.ts +++ b/packages/server/src/sdk/app/rows/external.ts @@ -9,6 +9,7 @@ import { } from "../../../utilities/rowProcessor" import cloneDeep from "lodash/fp/cloneDeep" import isEqual from "lodash/fp/isEqual" +import { tryExtractingTableAndViewId } from "./utils" export async function getRow( tableId: string, @@ -70,7 +71,9 @@ export async function save( } } -export async function find(tableId: string, rowId: string): Promise { +export async function find(tableOrViewId: string, rowId: string): Promise { + const { tableId, viewId } = tryExtractingTableAndViewId(tableOrViewId) + const row = await getRow(tableId, rowId, { relationships: true, }) @@ -84,5 +87,6 @@ export async function find(tableId: string, rowId: string): Promise { return await outputProcessing(table, row, { squash: true, preserveLinks: true, + fromViewId: viewId, }) } diff --git a/packages/server/src/sdk/app/rows/internal.ts b/packages/server/src/sdk/app/rows/internal.ts index c21d3465a7..2285ae6ed6 100644 --- a/packages/server/src/sdk/app/rows/internal.ts +++ b/packages/server/src/sdk/app/rows/internal.ts @@ -10,6 +10,7 @@ import { import * as linkRows from "../../../db/linkedRows" import { InternalTables } from "../../../db/utils" import { getFullUser } from "../../../utilities/users" +import { tryExtractingTableAndViewId } from "./utils" export async function save( tableId: string, @@ -53,11 +54,13 @@ export async function save( }) } -export async function find(tableId: string, rowId: string): Promise { +export async function find(tableOrViewId: string, rowId: string): Promise { + const { tableId, viewId } = tryExtractingTableAndViewId(tableOrViewId) + const table = await sdk.tables.getTable(tableId) let row = await findRow(tableId, rowId) - row = await outputProcessing(table, row) + row = await outputProcessing(table, row, { squash: true, fromViewId: viewId }) return row } diff --git a/packages/server/src/sdk/app/rows/rows.ts b/packages/server/src/sdk/app/rows/rows.ts index ef03210800..0bf9120f73 100644 --- a/packages/server/src/sdk/app/rows/rows.ts +++ b/packages/server/src/sdk/app/rows/rows.ts @@ -1,6 +1,10 @@ import { db as dbCore, context } from "@budibase/backend-core" import { Database, Row } from "@budibase/types" -import { getRowParams } from "../../../db/utils" +import { + extractViewInfoFromID, + getRowParams, + isViewID, +} from "../../../db/utils" import { isExternalTableID } from "../../../integrations/utils" import * as internal from "./internal" import * as external from "./external" @@ -20,7 +24,12 @@ export async function getAllInternalRows(appId?: string) { return response.rows.map(row => row.doc) as Row[] } -function pickApi(tableId: any) { +function pickApi(tableOrViewId: string) { + let tableId = tableOrViewId + if (isViewID(tableOrViewId)) { + tableId = extractViewInfoFromID(tableOrViewId).tableId + } + if (isExternalTableID(tableId)) { return external } @@ -35,6 +44,6 @@ export async function save( return pickApi(tableId).save(tableId, row, userId) } -export async function find(tableId: string, rowId: string) { - return pickApi(tableId).find(tableId, rowId) +export async function find(tableOrViewId: string, rowId: string) { + return pickApi(tableOrViewId).find(tableOrViewId, rowId) } diff --git a/packages/server/src/sdk/app/rows/search/internal/lucene.ts b/packages/server/src/sdk/app/rows/search/internal/lucene.ts index 6f449a2bcb..2c149e5b21 100644 --- a/packages/server/src/sdk/app/rows/search/internal/lucene.ts +++ b/packages/server/src/sdk/app/rows/search/internal/lucene.ts @@ -60,6 +60,7 @@ export async function search( } response.rows = await outputProcessing(table, response.rows, { + squash: true, fromViewId: options.viewId, }) } diff --git a/packages/server/src/sdk/app/rows/utils.ts b/packages/server/src/sdk/app/rows/utils.ts index 0cae39f5a9..bc09116b3b 100644 --- a/packages/server/src/sdk/app/rows/utils.ts +++ b/packages/server/src/sdk/app/rows/utils.ts @@ -17,7 +17,11 @@ import { import { makeExternalQuery } from "../../../integrations/base/query" import { Format } from "../../../api/controllers/view/exporters" import sdk from "../.." -import { isRelationshipColumn } from "../../../db/utils" +import { + extractViewInfoFromID, + isRelationshipColumn, + isViewID, +} from "../../../db/utils" import { isSQL } from "../../../integrations/utils" const SQL_CLIENT_SOURCE_MAP: Record = { @@ -317,3 +321,14 @@ function validateTimeOnlyField( export function isArrayFilter(operator: any): operator is ArrayOperator { return Object.values(ArrayOperator).includes(operator) } + +export function tryExtractingTableAndViewId(tableOrViewId: string) { + if (isViewID(tableOrViewId)) { + return { + tableId: extractViewInfoFromID(tableOrViewId).tableId, + viewId: tableOrViewId, + } + } + + return { tableId: tableOrViewId } +}