From b01564c934922c0acabfd5bea53861f511163fb5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 16 Oct 2024 10:21:17 +0200 Subject: [PATCH] Fix multiple relations to same table for external --- packages/backend-core/src/sql/sql.ts | 6 +- .../api/controllers/row/ExternalRequest.ts | 12 ---- packages/server/src/sdk/app/rows/index.ts | 2 - .../server/src/sdk/app/rows/search/filters.ts | 70 ------------------- 4 files changed, 3 insertions(+), 87 deletions(-) delete mode 100644 packages/server/src/sdk/app/rows/search/filters.ts diff --git a/packages/backend-core/src/sql/sql.ts b/packages/backend-core/src/sql/sql.ts index 83a4fd0d59..c47eabca57 100644 --- a/packages/backend-core/src/sql/sql.ts +++ b/packages/backend-core/src/sql/sql.ts @@ -412,7 +412,8 @@ class InternalBuilder { const { relationships, endpoint, tableAliases: aliases } = this.query const tableName = endpoint.entityId const fromAlias = aliases?.[tableName] || tableName - const matches = (value: string) => filterKey.startsWith(`${value}`) + const matches = (value: string) => + filterKey.match(new RegExp(`^${value}\\.`)) if (!relationships) { return query } @@ -435,7 +436,7 @@ class InternalBuilder { const manyToMany = validateManyToMany(relationship) let updatedKey - if (matchesRelationName) { + if (!matchesTableName) { updatedKey = filterKey.replace( new RegExp(`^${relationship.column}.`), `${aliases![relationship.tableName]}.` @@ -485,7 +486,6 @@ class InternalBuilder { ) } query = query.whereExists(whereCb(updatedKey, subQuery)) - break } } return query diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 56522acb33..7ac13d3200 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -204,18 +204,6 @@ export class ExternalRequest { filters: SearchFilters, table: Table ): SearchFilters { - // replace any relationship columns initially, table names and relationship column names are acceptable - const relationshipColumns = sdk.rows.filters.getRelationshipColumns(table) - filters = sdk.rows.filters.updateFilterKeys( - filters, - relationshipColumns.map(({ name, definition }) => { - const { tableName } = breakExternalTableId(definition.tableId) - return { - original: name, - updated: tableName, - } - }) - ) const primary = table.primary // if passed in array need to copy for shifting etc let idCopy: undefined | string | any[] = cloneDeep(id) diff --git a/packages/server/src/sdk/app/rows/index.ts b/packages/server/src/sdk/app/rows/index.ts index fb077509a9..c117941419 100644 --- a/packages/server/src/sdk/app/rows/index.ts +++ b/packages/server/src/sdk/app/rows/index.ts @@ -3,14 +3,12 @@ import * as rows from "./rows" import * as search from "./search" import * as utils from "./utils" import * as external from "./external" -import * as filters from "./search/filters" import AliasTables from "./sqlAlias" export default { ...attachments, ...rows, ...search, - filters, utils, external, AliasTables, diff --git a/packages/server/src/sdk/app/rows/search/filters.ts b/packages/server/src/sdk/app/rows/search/filters.ts deleted file mode 100644 index 9fab045554..0000000000 --- a/packages/server/src/sdk/app/rows/search/filters.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - FieldType, - RelationshipFieldMetadata, - SearchFilters, - Table, -} from "@budibase/types" -import { isPlainObject } from "lodash" -import { dataFilters } from "@budibase/shared-core" - -export function getRelationshipColumns(table: Table): { - name: string - definition: RelationshipFieldMetadata -}[] { - // performing this with a for loop rather than an array filter improves - // type guarding, as no casts are required - const linkEntries: [string, RelationshipFieldMetadata][] = [] - for (let entry of Object.entries(table.schema)) { - if (entry[1].type === FieldType.LINK) { - const linkColumn: RelationshipFieldMetadata = entry[1] - linkEntries.push([entry[0], linkColumn]) - } - } - return linkEntries.map(entry => ({ - name: entry[0], - definition: entry[1], - })) -} - -export function getTableIDList( - tables: Table[] -): { name: string; id: string }[] { - return tables - .filter(table => table.originalName && table._id) - .map(table => ({ id: table._id!, name: table.originalName! })) -} - -export function updateFilterKeys( - filters: SearchFilters, - updates: { original: string; updated: string }[] -): SearchFilters { - const makeFilterKeyRegex = (str: string) => - new RegExp(`^${str}\\.|:${str}\\.`) - for (let filter of Object.values(filters)) { - if (!isPlainObject(filter)) { - continue - } - for (const [key, keyFilter] of Object.entries(filter)) { - if (keyFilter === "") { - delete filter[key] - } - - const possibleKey = updates.find(({ original }) => - key.match(makeFilterKeyRegex(original)) - ) - if (possibleKey && possibleKey.original !== possibleKey.updated) { - // only replace the first, not replaceAll - filter[ - key.replace( - new RegExp(`^(\\d+:)?${possibleKey.original}\\.`), - `$1${possibleKey.updated}.` - ) - ] = filter[key] - delete filter[key] - } - } - } - return dataFilters.recurseLogicalOperators(filters, (f: SearchFilters) => { - return updateFilterKeys(f, updates) - }) -}