1
0
Fork 0
mirror of synced 2024-09-25 22:01:43 +12:00

Got a test passing but I hate it a bit.

This commit is contained in:
Sam Rose 2024-09-20 16:37:23 +01:00
parent b8a3210286
commit c5db1d1da3
No known key found for this signature in database
7 changed files with 56 additions and 17 deletions

View file

@ -1,5 +1,12 @@
// need to handle table name + field or just field, depending on if relationships used // need to handle table name + field or just field, depending on if relationships used
import { FieldSchema, FieldType, Row, Table, JsonTypes } from "@budibase/types" import {
FieldSchema,
FieldType,
Row,
Table,
JsonTypes,
Aggregation,
} from "@budibase/types"
import { import {
helpers, helpers,
PROTECTED_EXTERNAL_COLUMNS, PROTECTED_EXTERNAL_COLUMNS,
@ -84,12 +91,14 @@ export function basicProcessing({
tables, tables,
isLinked, isLinked,
sqs, sqs,
aggregations,
}: { }: {
row: Row row: Row
table: Table table: Table
tables: Table[] tables: Table[]
isLinked: boolean isLinked: boolean
sqs?: boolean sqs?: boolean
aggregations?: Aggregation[]
}): Row { }): Row {
const thisRow: Row = {} const thisRow: Row = {}
// filter the row down to what is actually the row (not joined) // filter the row down to what is actually the row (not joined)
@ -108,6 +117,11 @@ export function basicProcessing({
thisRow[fieldName] = value thisRow[fieldName] = value
} }
} }
for (let aggregation of aggregations || []) {
thisRow[aggregation.name] = row[aggregation.name]
}
let columns: string[] = Object.keys(table.schema) let columns: string[] = Object.keys(table.schema)
if (!sqs) { if (!sqs) {
thisRow._id = generateIdForRow(row, table, isLinked) thisRow._id = generateIdForRow(row, table, isLinked)

View file

@ -2,6 +2,7 @@ import * as utils from "../../../../db/utils"
import { context } from "@budibase/backend-core" import { context } from "@budibase/backend-core"
import { import {
Aggregation,
Ctx, Ctx,
DatasourcePlusQueryResponse, DatasourcePlusQueryResponse,
FieldType, FieldType,
@ -129,7 +130,7 @@ export async function sqlOutputProcessing(
table: Table, table: Table,
tables: Record<string, Table>, tables: Record<string, Table>,
relationships: RelationshipsJson[], relationships: RelationshipsJson[],
opts?: { sqs?: boolean } opts?: { sqs?: boolean; aggregations?: Aggregation[] }
): Promise<Row[]> { ): Promise<Row[]> {
if (isKnexEmptyReadResponse(rows)) { if (isKnexEmptyReadResponse(rows)) {
return [] return []
@ -150,6 +151,7 @@ export async function sqlOutputProcessing(
tables: Object.values(tables), tables: Object.values(tables),
isLinked: false, isLinked: false,
sqs: opts?.sqs, sqs: opts?.sqs,
aggregations: opts?.aggregations,
}) })
if (thisRow._id == null) { if (thisRow._id == null) {
throw new Error("Unable to generate row ID for SQL rows") throw new Error("Unable to generate row ID for SQL rows")

View file

@ -37,13 +37,13 @@ import {
import sdk from "../../../sdk" import sdk from "../../../sdk"
describe.each([ describe.each([
["lucene", undefined], // ["lucene", undefined],
["sqs", undefined], ["sqs", undefined],
[DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)], // [DatabaseName.POSTGRES, getDatasource(DatabaseName.POSTGRES)],
[DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)], // [DatabaseName.MYSQL, getDatasource(DatabaseName.MYSQL)],
[DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)], // [DatabaseName.SQL_SERVER, getDatasource(DatabaseName.SQL_SERVER)],
[DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)], // [DatabaseName.MARIADB, getDatasource(DatabaseName.MARIADB)],
[DatabaseName.ORACLE, getDatasource(DatabaseName.ORACLE)], // [DatabaseName.ORACLE, getDatasource(DatabaseName.ORACLE)],
])("/v2/views (%s)", (name, dsProvider) => { ])("/v2/views (%s)", (name, dsProvider) => {
const config = setup.getConfig() const config = setup.getConfig()
const isSqs = name === "sqs" const isSqs = name === "sqs"
@ -2215,7 +2215,7 @@ describe.each([
) )
}) })
describe.skip("calculations", () => { describe("calculations", () => {
let table: Table let table: Table
let rows: Row[] let rows: Row[]
@ -2245,7 +2245,7 @@ describe.each([
) )
}) })
it("should be able to search by calculations", async () => { it.only("should be able to search by calculations", async () => {
const view = await config.api.viewV2.create({ const view = await config.api.viewV2.create({
tableId: table._id!, tableId: table._id!,
name: generator.guid(), name: generator.guid(),

View file

@ -20,10 +20,11 @@ import {
Row, Row,
Table, Table,
TableSchema, TableSchema,
ViewFieldMetadata, ViewUIFieldMetadata,
ViewV2, ViewV2,
} from "@budibase/types" } from "@budibase/types"
import sdk from "../../sdk" import sdk from "../../sdk"
import { helpers } from "@budibase/shared-core"
export { IncludeDocs, getLinkDocuments, createLinkView } from "./linkUtils" export { IncludeDocs, getLinkDocuments, createLinkView } from "./linkUtils"
@ -264,12 +265,19 @@ export async function squashLinks<T = Row[] | Row>(
FeatureFlag.ENRICHED_RELATIONSHIPS FeatureFlag.ENRICHED_RELATIONSHIPS
) )
let viewSchema: Record<string, ViewFieldMetadata> = {} let viewSchema: Record<string, ViewUIFieldMetadata> = {}
if (options?.fromViewId && allowRelationshipSchemas) { if (options?.fromViewId) {
const view = Object.values(table.views || {}).find( const view = Object.values(table.views || {}).find(
(v): v is ViewV2 => sdk.views.isV2(v) && v.id === options?.fromViewId (v): v is ViewV2 => sdk.views.isV2(v) && v.id === options?.fromViewId
) )
viewSchema = view?.schema || {}
if (view && helpers.views.isCalculationView(view)) {
return enriched
}
if (allowRelationshipSchemas && view) {
viewSchema = view.schema || {}
}
} }
// will populate this as we find them // will populate this as we find them

View file

@ -37,6 +37,7 @@ export async function search(
return await tracer.trace("search", async span => { return await tracer.trace("search", async span => {
span?.addTags({ span?.addTags({
tableId: options.tableId, tableId: options.tableId,
viewId: options.viewId,
query: options.query, query: options.query,
sort: options.sort, sort: options.sort,
sortOrder: options.sortOrder, sortOrder: options.sortOrder,

View file

@ -386,8 +386,9 @@ export async function search(
// make sure JSON columns corrected // make sure JSON columns corrected
const processed = builder.convertJsonStringColumns<Row>( const processed = builder.convertJsonStringColumns<Row>(
table, table,
await sqlOutputProcessing(rows, table!, allTablesMap, relationships, { await sqlOutputProcessing(rows, table, allTablesMap, relationships, {
sqs: true, sqs: true,
aggregations: options.aggregations,
}) })
) )
@ -406,11 +407,16 @@ export async function search(
preserveLinks: true, preserveLinks: true,
squash: true, squash: true,
fromViewId: options.viewId, fromViewId: options.viewId,
aggregations: options.aggregations,
}) })
// check if we need to pick specific rows out // check if we need to pick specific rows out
if (options.fields) { if (options.fields) {
const fields = [...options.fields, ...PROTECTED_INTERNAL_COLUMNS] const fields = [
...options.fields,
...PROTECTED_INTERNAL_COLUMNS,
...(options.aggregations || []).map(a => a.name),
]
finalRows = finalRows.map((r: any) => pick(r, fields)) finalRows = finalRows.map((r: any) => pick(r, fields))
} }
@ -440,6 +446,5 @@ export async function search(
return { rows: [] } return { rows: [] }
} }
throw err throw err
throw new Error(`Unable to search by SQL - ${msg}`, { cause: err })
} }
} }

View file

@ -11,6 +11,7 @@ import {
import { InternalTables } from "../../db/utils" import { InternalTables } from "../../db/utils"
import { TYPE_TRANSFORM_MAP } from "./map" import { TYPE_TRANSFORM_MAP } from "./map"
import { import {
Aggregation,
AutoFieldSubType, AutoFieldSubType,
FieldType, FieldType,
IdentityType, IdentityType,
@ -250,6 +251,7 @@ export async function outputProcessing<T extends Row[] | Row>(
fromRow?: Row fromRow?: Row
skipBBReferences?: boolean skipBBReferences?: boolean
fromViewId?: string fromViewId?: string
aggregations?: Aggregation[]
} = { } = {
squash: true, squash: true,
preserveLinks: false, preserveLinks: false,
@ -357,6 +359,7 @@ export async function outputProcessing<T extends Row[] | Row>(
fromViewId: opts?.fromViewId, fromViewId: opts?.fromViewId,
}) })
} }
// remove null properties to match internal API // remove null properties to match internal API
const isExternal = isExternalTableID(table._id!) const isExternal = isExternalTableID(table._id!)
if (isExternal || (await features.flags.isEnabled("SQS"))) { if (isExternal || (await features.flags.isEnabled("SQS"))) {
@ -385,9 +388,15 @@ export async function outputProcessing<T extends Row[] | Row>(
const tableFields = Object.keys(table.schema).filter( const tableFields = Object.keys(table.schema).filter(
f => table.schema[f].visible !== false f => table.schema[f].visible !== false
) )
const fields = [...tableFields, ...protectedColumns].map(f => const fields = [...tableFields, ...protectedColumns].map(f =>
f.toLowerCase() f.toLowerCase()
) )
for (const aggregation of opts.aggregations || []) {
fields.push(aggregation.name.toLowerCase())
}
for (const row of enriched) { for (const row of enriched) {
for (const key of Object.keys(row)) { for (const key of Object.keys(row)) {
if (!fields.includes(key.toLowerCase())) { if (!fields.includes(key.toLowerCase())) {