Move responsability

This commit is contained in:
Adria Navarro 2024-08-29 11:06:41 +02:00
parent 383aad7265
commit adc2e983b5
8 changed files with 74 additions and 66 deletions

View File

@ -17,9 +17,10 @@ import {
FieldType, FieldType,
LinkDocumentValue, LinkDocumentValue,
Row, Row,
SquashTableFields,
Table, Table,
TableSchema, TableSchema,
ViewFieldMetadata,
ViewV2,
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../sdk" import sdk from "../../sdk"
@ -242,6 +243,8 @@ function getPrimaryDisplayValue(row: Row, table?: Table) {
} }
} }
export type SquashTableFields = Record<string, { visibleFieldNames: string[] }>
/** /**
* This function will take the given enriched rows and squash the links to only contain the primary display field. * This function will take the given enriched rows and squash the links to only contain the primary display field.
* @param table The table from which the rows originated. * @param table The table from which the rows originated.
@ -252,8 +255,40 @@ function getPrimaryDisplayValue(row: Row, table?: Table) {
export async function squashLinks<T = Row[] | Row>( export async function squashLinks<T = Row[] | Row>(
table: Table, table: Table,
enriched: T, enriched: T,
squashFields?: SquashTableFields options?: {
fromViewId?: string
}
): Promise<T> { ): Promise<T> {
// export function outputRowOptions(
// table: Table,
// viewId: string
// ): OutputRowOptions {
// const view = Object.values(table.views || {}).find(
// (v): v is ViewV2 => sdk.views.isV2(v) && v.id === viewId
// )
// const viewSchema = view?.schema || {}
// const squashFields: SquashTableFields = {}
// for (const key of Object.keys(viewSchema)) {
// if (viewSchema[key].columns) {
// squashFields[key] = {
// visibleFieldNames: Object.entries(viewSchema[key].columns)
// .filter(([_, c]) => c.visible !== false)
// .map(([columnName]) => columnName),
// }
// }
// }
// return { squashNestedFields: squashFields }
// }
let viewSchema: Record<string, ViewFieldMetadata> = {}
if (options?.fromViewId) {
const view = Object.values(table.views || {}).find(
(v): v is ViewV2 => sdk.views.isV2(v) && v.id === options?.fromViewId
)
viewSchema = view?.schema || {}
}
// will populate this as we find them // will populate this as we find them
const linkedTables = [table] const linkedTables = [table]
const isArray = Array.isArray(enriched) const isArray = Array.isArray(enriched)
@ -273,8 +308,27 @@ export async function squashLinks<T = Row[] | Row>(
const obj: any = { _id: link._id } const obj: any = { _id: link._id }
obj.primaryDisplay = getPrimaryDisplayValue(link, linkedTable) obj.primaryDisplay = getPrimaryDisplayValue(link, linkedTable)
if (squashFields && squashFields[column]) { if (viewSchema[column]?.columns) {
for (const relField of squashFields[column].visibleFieldNames) { const squashFields = Object.entries(viewSchema[column].columns)
.filter(([columnName, viewColumnConfig]) => {
const tableColumn = linkedTable.schema[columnName]
if (!tableColumn) {
return false
}
if (
[FieldType.LINK, FieldType.FORMULA].includes(tableColumn.type)
) {
return false
}
return (
tableColumn.visible !== false &&
viewColumnConfig.visible !== false
)
})
.map(([columnName]) => columnName)
for (const relField of squashFields) {
obj[relField] = link[relField] obj[relField] = link[relField]
} }
} }

View File

@ -86,21 +86,16 @@ export async function search(
options.query = removeInvalidFilters(options.query, queriableFields) options.query = removeInvalidFilters(options.query, queriableFields)
} }
let outputRowOptions
if (options.viewId) {
outputRowOptions = sdk.views.outputRowOptions(table, options.viewId)
}
let result: SearchResponse<Row> let result: SearchResponse<Row>
if (isExternalTable) { if (isExternalTable) {
span?.addTags({ searchType: "external" }) span?.addTags({ searchType: "external" })
result = await external.search(options, table, outputRowOptions) result = await external.search(options, table)
} else if (dbCore.isSqsEnabledForTenant()) { } else if (dbCore.isSqsEnabledForTenant()) {
span?.addTags({ searchType: "sqs" }) span?.addTags({ searchType: "sqs" })
result = await internal.sqs.search(options, table, { outputRowOptions }) result = await internal.sqs.search(options, table)
} else { } else {
span?.addTags({ searchType: "lucene" }) span?.addTags({ searchType: "lucene" })
result = await internal.lucene.search(options, table, outputRowOptions) result = await internal.lucene.search(options, table)
} }
span?.addTags({ span?.addTags({

View File

@ -1,7 +1,6 @@
import { import {
IncludeRelationship, IncludeRelationship,
Operation, Operation,
OutputRowOptions,
PaginationJson, PaginationJson,
Row, Row,
RowSearchParams, RowSearchParams,
@ -61,8 +60,7 @@ function getPaginationAndLimitParameters(
export async function search( export async function search(
options: RowSearchParams, options: RowSearchParams,
table: Table, table: Table
outputRowOptions?: OutputRowOptions
): Promise<SearchResponse<Row>> { ): Promise<SearchResponse<Row>> {
const { tableId } = options const { tableId } = options
const { countRows, paginate, query, ...params } = options const { countRows, paginate, query, ...params } = options
@ -117,7 +115,7 @@ export async function search(
let processed = await outputProcessing(table, rows, { let processed = await outputProcessing(table, rows, {
preserveLinks: true, preserveLinks: true,
squash: true, squash: true,
squashNestedFields: outputRowOptions?.squashNestedFields, fromViewId: options.viewId,
}) })
let hasNextPage = false let hasNextPage = false

View File

@ -2,7 +2,6 @@ import { PROTECTED_INTERNAL_COLUMNS } from "@budibase/shared-core"
import { fullSearch, paginatedSearch } from "../utils" import { fullSearch, paginatedSearch } from "../utils"
import { InternalTables } from "../../../../../db/utils" import { InternalTables } from "../../../../../db/utils"
import { import {
OutputRowOptions,
Row, Row,
RowSearchParams, RowSearchParams,
SearchResponse, SearchResponse,
@ -16,8 +15,7 @@ import pick from "lodash/pick"
export async function search( export async function search(
options: RowSearchParams, options: RowSearchParams,
table: Table, table: Table
outputRowOptions?: OutputRowOptions
): Promise<SearchResponse<Row>> { ): Promise<SearchResponse<Row>> {
const { tableId } = options const { tableId } = options
@ -62,7 +60,7 @@ export async function search(
} }
response.rows = await outputProcessing(table, response.rows, { response.rows = await outputProcessing(table, response.rows, {
squashNestedFields: outputRowOptions?.squashNestedFields, fromViewId: options.viewId,
}) })
} }

View File

@ -4,7 +4,6 @@ import {
FieldType, FieldType,
isLogicalSearchOperator, isLogicalSearchOperator,
Operation, Operation,
OutputRowOptions,
QueryJson, QueryJson,
RelationshipFieldMetadata, RelationshipFieldMetadata,
RelationshipsJson, RelationshipsJson,
@ -284,7 +283,7 @@ function resyncDefinitionsRequired(status: number, message: string) {
export async function search( export async function search(
options: RowSearchParams, options: RowSearchParams,
table: Table, table: Table,
opts?: { retrying?: boolean; outputRowOptions?: OutputRowOptions } opts?: { retrying?: boolean }
): Promise<SearchResponse<Row>> { ): Promise<SearchResponse<Row>> {
let { paginate, query, ...params } = options let { paginate, query, ...params } = options
@ -383,7 +382,7 @@ export async function search(
let finalRows = await outputProcessing(table, processed, { let finalRows = await outputProcessing(table, processed, {
preserveLinks: true, preserveLinks: true,
squash: true, squash: true,
squashNestedFields: opts?.outputRowOptions?.squashNestedFields, fromViewId: options.viewId,
}) })
// check if we need to pick specific rows out // check if we need to pick specific rows out
@ -411,10 +410,7 @@ export async function search(
const msg = typeof err === "string" ? err : err.message const msg = typeof err === "string" ? err : err.message
if (!opts?.retrying && resyncDefinitionsRequired(err.status, msg)) { if (!opts?.retrying && resyncDefinitionsRequired(err.status, msg)) {
await sdk.tables.sqs.syncDefinition() await sdk.tables.sqs.syncDefinition()
return search(options, table, { return search(options, table, { retrying: true })
retrying: true,
outputRowOptions: opts?.outputRowOptions,
})
} }
// previously the internal table didn't error when a column didn't exist in search // previously the internal table didn't error when a column didn't exist in search
if (err.status === 400 && msg?.match(MISSING_COLUMN_REGEX)) { if (err.status === 400 && msg?.match(MISSING_COLUMN_REGEX)) {

View File

@ -1,9 +1,7 @@
import { import {
FieldType, FieldType,
OutputRowOptions,
RelationSchemaField, RelationSchemaField,
RenameColumn, RenameColumn,
SquashTableFields,
Table, Table,
TableSchema, TableSchema,
View, View,
@ -252,26 +250,3 @@ export function syncSchema(
return view return view
} }
export function outputRowOptions(
table: Table,
viewId: string
): OutputRowOptions {
const view = Object.values(table.views || {}).find(
(v): v is ViewV2 => sdk.views.isV2(v) && v.id === viewId
)
const viewSchema = view?.schema || {}
const squashFields: SquashTableFields = {}
for (const key of Object.keys(viewSchema)) {
if (viewSchema[key].columns) {
squashFields[key] = {
visibleFieldNames: Object.entries(viewSchema[key].columns)
.filter(([_, c]) => c.visible !== false)
.map(([columnName]) => columnName),
}
}
}
return { squashNestedFields: squashFields }
}

View File

@ -16,7 +16,6 @@ import {
IdentityType, IdentityType,
Row, Row,
RowAttachment, RowAttachment,
SquashTableFields,
Table, Table,
User, User,
} from "@budibase/types" } from "@budibase/types"
@ -36,6 +35,7 @@ import {
import { processString } from "@budibase/string-templates" import { processString } from "@budibase/string-templates"
import { isUserMetadataTable } from "../../api/controllers/row/utils" import { isUserMetadataTable } from "../../api/controllers/row/utils"
export * from "./utils" export * from "./utils"
export * from "./attachments" export * from "./attachments"
@ -248,7 +248,7 @@ export async function outputProcessing<T extends Row[] | Row>(
preserveLinks?: boolean preserveLinks?: boolean
fromRow?: Row fromRow?: Row
skipBBReferences?: boolean skipBBReferences?: boolean
squashNestedFields?: SquashTableFields fromViewId?: string
} = { } = {
squash: true, squash: true,
preserveLinks: false, preserveLinks: false,
@ -344,12 +344,10 @@ export async function outputProcessing<T extends Row[] | Row>(
// process formulas after the complex types had been processed // process formulas after the complex types had been processed
enriched = await processFormulas(table, enriched, { dynamic: true }) enriched = await processFormulas(table, enriched, { dynamic: true })
if (opts.squash || opts.squashNestedFields) { if (opts.squash) {
enriched = await linkRows.squashLinks( enriched = await linkRows.squashLinks(table, enriched, {
table, fromViewId: opts?.fromViewId,
enriched, })
opts.squashNestedFields
)
} }
// remove null properties to match internal API // remove null properties to match internal API
const isExternal = isExternalTableID(table._id!) const isExternal = isExternalTableID(table._id!)

View File

@ -37,9 +37,3 @@ export enum RowExportFormat {
JSON = "json", JSON = "json",
JSON_WITH_SCHEMA = "jsonWithSchema", JSON_WITH_SCHEMA = "jsonWithSchema",
} }
export interface OutputRowOptions {
squashNestedFields: SquashTableFields
}
export type SquashTableFields = Record<string, { visibleFieldNames: string[] }>