This commit is contained in:
Adria Navarro 2024-10-15 18:50:58 +02:00
parent 225d062fcc
commit 8a6dbef249
2 changed files with 28 additions and 39 deletions

View File

@ -406,23 +406,26 @@ class InternalBuilder {
addRelationshipForFilter(
query: Knex.QueryBuilder,
filterKey: string,
whereCb: (query: Knex.QueryBuilder) => Knex.QueryBuilder
whereCb: (filterKey: string, query: Knex.QueryBuilder) => Knex.QueryBuilder
): Knex.QueryBuilder {
const mainKnex = this.knex
const { relationships, endpoint, tableAliases: aliases } = this.query
const tableName = endpoint.entityId
const fromAlias = aliases?.[tableName] || tableName
const matches = (possibleTable: string) =>
filterKey.startsWith(`${possibleTable}`)
const matches = (value: string) => filterKey.startsWith(`${value}`)
if (!relationships) {
return query
}
for (const relationship of relationships) {
const relatedTableName = relationship.tableName
const toAlias = aliases?.[relatedTableName] || relatedTableName
const matchesTableName = matches(relatedTableName) || matches(toAlias)
const matchesRelationName = matches(relationship.column)
// this is the relationship which is being filtered
if (
(matches(relatedTableName) || matches(toAlias)) &&
(matchesTableName || matchesRelationName) &&
relationship.to &&
relationship.tableName
) {
@ -430,6 +433,17 @@ class InternalBuilder {
.select(mainKnex.raw(1))
.from({ [toAlias]: relatedTableName })
const manyToMany = validateManyToMany(relationship)
let updatedKey
if (matchesRelationName) {
updatedKey = filterKey.replace(
new RegExp(`^${relationship.column}.`),
`${aliases![relationship.tableName]}.`
)
} else {
updatedKey = filterKey
}
if (manyToMany) {
const throughAlias =
aliases?.[manyToMany.through] || relationship.through
@ -470,7 +484,7 @@ class InternalBuilder {
)
)
}
query = query.whereExists(whereCb(subQuery))
query = query.whereExists(whereCb(updatedKey, subQuery))
break
}
}
@ -558,9 +572,13 @@ class InternalBuilder {
if (allOr) {
query = query.or
}
query = builder.addRelationshipForFilter(query, updatedKey, q => {
return handleRelationship(q, updatedKey, value)
})
query = builder.addRelationshipForFilter(
query,
updatedKey,
(updatedKey, q) => {
return handleRelationship(q, updatedKey, value)
}
)
}
}
}

View File

@ -39,11 +39,6 @@ import AliasTables from "../../sqlAlias"
import { outputProcessing } from "../../../../../utilities/rowProcessor"
import pick from "lodash/pick"
import { processRowCountResponse } from "../../utils"
import {
getRelationshipColumns,
getTableIDList,
updateFilterKeys,
} from "../filters"
import {
dataFilters,
helpers,
@ -133,31 +128,7 @@ async function buildInternalFieldList(
return [...new Set(fieldList)]
}
function cleanupFilters(
filters: SearchFilters,
table: Table,
allTables: Table[]
) {
// get a list of all relationship columns in the table for updating
const relationshipColumns = getRelationshipColumns(table)
// get table names to ID map for relationships
const tableNameToID = getTableIDList(allTables)
// all should be applied at once
filters = updateFilterKeys(
filters,
relationshipColumns
.map(({ name, definition }) => ({
original: name,
updated: definition.tableId,
}))
.concat(
tableNameToID.map(({ name, id }) => ({
original: name,
updated: id,
}))
)
)
function cleanupFilters(filters: SearchFilters, allTables: Table[]) {
// generate a map of all possible column names (these can be duplicated across tables
// the map of them will always be the same
const userColumnMap: Record<string, string> = {}
@ -356,7 +327,7 @@ export async function search(
const relationships = buildInternalRelationships(table, allTables)
const searchFilters: SearchFilters = {
...cleanupFilters(query, table, allTables),
...cleanupFilters(query, allTables),
documentType: DocumentType.ROW,
}