Getting functions in place which make it easy to update pats of a filter list by their keys - getting this to work for SQS and external.

This commit is contained in:
mike12345567 2024-06-21 17:00:12 +01:00
parent 6812c21076
commit 28d0d627ce
3 changed files with 89 additions and 29 deletions

View File

@ -3,12 +3,14 @@ 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,

View File

@ -0,0 +1,56 @@
import {
FieldType,
RelationshipFieldMetadata,
SearchFilters,
Table,
} from "@budibase/types"
export function getRelationshipColumns(table: Table): {
name: string
definition: RelationshipFieldMetadata
}[] {
return Object.entries(table.schema)
.filter(entry => entry[1].type === FieldType.LINK)
.map(entry => ({
name: entry[0],
definition: entry[1] as RelationshipFieldMetadata,
}))
}
export function getTableIDList(
tables: Table[]
): { name: string; id: string }[] {
return tables
.filter(table => table.originalName)
.map(table => ({ id: table._id!, name: table.originalName! }))
}
export function updateFilterKeys(
filters: SearchFilters,
updates: { original: string; updated: string }[]
): SearchFilters {
// sort the updates by length first - this is necessary to avoid replacing sub-strings
updates = updates.sort((a, b) => b.original.length - a.original.length)
const makeFilterKeyRegex = (str: string) =>
new RegExp(`^${str}.|:${str}.`, "g")
for (let filter of Object.values(filters)) {
if (typeof filter !== "object") {
continue
}
for (let [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(possibleKey.original, possibleKey.updated)] =
filter[key]
delete filter[key]
}
}
}
return filters
}

View File

@ -1,4 +1,5 @@
import {
Datasource,
DocumentType,
FieldType,
Operation,
@ -12,7 +13,6 @@ import {
SortType,
SqlClient,
Table,
Datasource,
} from "@budibase/types"
import {
buildInternalRelationships,
@ -30,6 +30,11 @@ import AliasTables from "../sqlAlias"
import { outputProcessing } from "../../../../utilities/rowProcessor"
import pick from "lodash/pick"
import { processRowCountResponse } from "../utils"
import {
updateFilterKeys,
getRelationshipColumns,
getTableIDList,
} from "./filters"
const builder = new sql.Sql(SqlClient.SQL_LITE)
@ -60,34 +65,31 @@ function buildInternalFieldList(
return fieldList
}
function tableNameInFieldRegex(tableName: string) {
return new RegExp(`^${tableName}.|:${tableName}.`, "g")
}
function cleanupFilters(filters: SearchFilters, tables: Table[]) {
for (let filter of Object.values(filters)) {
if (typeof filter !== "object") {
continue
}
for (let [key, keyFilter] of Object.entries(filter)) {
if (keyFilter === "") {
delete filter[key]
}
// relationship, switch to table ID
const tableRelated = tables.find(
table =>
table.originalName &&
key.match(tableNameInFieldRegex(table.originalName))
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,
}))
)
if (tableRelated && tableRelated.originalName) {
// only replace the first, not replaceAll
filter[key.replace(tableRelated.originalName, tableRelated._id!)] =
filter[key]
delete filter[key]
}
}
}
)
return filters
}
@ -176,7 +178,7 @@ export async function search(
operation: Operation.READ,
},
filters: {
...cleanupFilters(query, allTables),
...cleanupFilters(query, table, allTables),
documentType: DocumentType.ROW,
},
table,