Move responsability
This commit is contained in:
parent
383aad7265
commit
adc2e983b5
|
@ -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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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 }
|
|
||||||
}
|
|
||||||
|
|
|
@ -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!)
|
||||||
|
|
|
@ -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[] }>
|
|
||||||
|
|
Loading…
Reference in New Issue