Fix multiple relations to same table for external
This commit is contained in:
parent
f5fe3c0bdf
commit
b01564c934
|
@ -412,7 +412,8 @@ class InternalBuilder {
|
||||||
const { relationships, endpoint, tableAliases: aliases } = this.query
|
const { relationships, endpoint, tableAliases: aliases } = this.query
|
||||||
const tableName = endpoint.entityId
|
const tableName = endpoint.entityId
|
||||||
const fromAlias = aliases?.[tableName] || tableName
|
const fromAlias = aliases?.[tableName] || tableName
|
||||||
const matches = (value: string) => filterKey.startsWith(`${value}`)
|
const matches = (value: string) =>
|
||||||
|
filterKey.match(new RegExp(`^${value}\\.`))
|
||||||
if (!relationships) {
|
if (!relationships) {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
@ -435,7 +436,7 @@ class InternalBuilder {
|
||||||
const manyToMany = validateManyToMany(relationship)
|
const manyToMany = validateManyToMany(relationship)
|
||||||
let updatedKey
|
let updatedKey
|
||||||
|
|
||||||
if (matchesRelationName) {
|
if (!matchesTableName) {
|
||||||
updatedKey = filterKey.replace(
|
updatedKey = filterKey.replace(
|
||||||
new RegExp(`^${relationship.column}.`),
|
new RegExp(`^${relationship.column}.`),
|
||||||
`${aliases![relationship.tableName]}.`
|
`${aliases![relationship.tableName]}.`
|
||||||
|
@ -485,7 +486,6 @@ class InternalBuilder {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
query = query.whereExists(whereCb(updatedKey, subQuery))
|
query = query.whereExists(whereCb(updatedKey, subQuery))
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return query
|
return query
|
||||||
|
|
|
@ -204,18 +204,6 @@ export class ExternalRequest<T extends Operation> {
|
||||||
filters: SearchFilters,
|
filters: SearchFilters,
|
||||||
table: Table
|
table: Table
|
||||||
): SearchFilters {
|
): 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
|
const primary = table.primary
|
||||||
// if passed in array need to copy for shifting etc
|
// if passed in array need to copy for shifting etc
|
||||||
let idCopy: undefined | string | any[] = cloneDeep(id)
|
let idCopy: undefined | string | any[] = cloneDeep(id)
|
||||||
|
|
|
@ -3,14 +3,12 @@ import * as rows from "./rows"
|
||||||
import * as search from "./search"
|
import * as search from "./search"
|
||||||
import * as utils from "./utils"
|
import * as utils from "./utils"
|
||||||
import * as external from "./external"
|
import * as external from "./external"
|
||||||
import * as filters from "./search/filters"
|
|
||||||
import AliasTables from "./sqlAlias"
|
import AliasTables from "./sqlAlias"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
...attachments,
|
...attachments,
|
||||||
...rows,
|
...rows,
|
||||||
...search,
|
...search,
|
||||||
filters,
|
|
||||||
utils,
|
utils,
|
||||||
external,
|
external,
|
||||||
AliasTables,
|
AliasTables,
|
||||||
|
|
|
@ -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)
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
Reference in New Issue