Apply search to filter_count

Fixes #4121
This commit is contained in:
rijkvanzanten
2021-02-17 10:47:57 -05:00
parent 07ea3870ba
commit 3615612da0
4 changed files with 48 additions and 44 deletions

View File

@@ -130,7 +130,7 @@ async function parseCurrentLevel(
return { columnsToSelect, nestedCollectionNodes, primaryKeyField };
}
async function getDBQuery(
function getDBQuery(
knex: Knex,
table: string,
columns: string[],
@@ -138,7 +138,7 @@ async function getDBQuery(
primaryKeyField: string,
schema: SchemaOverview,
nested?: boolean
): Promise<QueryBuilder> {
): QueryBuilder {
let dbQuery = knex.select(columns.map((column) => `${table}.${column}`)).from(table);
const queryCopy = clone(query);
@@ -154,7 +154,7 @@ async function getDBQuery(
query.sort = query.sort || [{ column: primaryKeyField, order: 'asc' }];
await applyQuery(table, dbQuery, queryCopy, schema);
applyQuery(table, dbQuery, queryCopy, schema);
// Nested filters use joins to filter on the parent level, to prevent duplicate
// parents, we group the query by the current tables primary key (which is unique)

View File

@@ -2,7 +2,7 @@ import { Query } from '../types/query';
import database from '../database';
import { AbstractServiceOptions, Accountability, SchemaOverview } from '../types';
import Knex from 'knex';
import { applyFilter } from '../utils/apply-query';
import { applyFilter, applySearch } from '../utils/apply-query';
export class MetaService {
knex: Knex;
@@ -42,7 +42,11 @@ export class MetaService {
const dbQuery = this.knex(collection).count('*', { as: 'count' });
if (query.filter) {
await applyFilter(this.schema, dbQuery, query.filter, collection);
applyFilter(this.schema, dbQuery, query.filter, collection);
}
if (query.search) {
applySearch(this.schema, dbQuery, query.search, collection);
}
const records = await dbQuery;

View File

@@ -6,16 +6,7 @@ import { nanoid } from 'nanoid';
import getLocalType from './get-local-type';
import validate from 'uuid-validate';
export default async function applyQuery(
collection: string,
dbQuery: QueryBuilder,
query: Query,
schema: SchemaOverview
) {
if (query.filter) {
await applyFilter(schema, dbQuery, query.filter, collection);
}
export default function applyQuery(collection: string, dbQuery: QueryBuilder, query: Query, schema: SchemaOverview) {
if (query.sort) {
dbQuery.orderBy(query.sort);
}
@@ -36,38 +27,16 @@ export default async function applyQuery(
dbQuery.limit(1).first();
}
if (query.search) {
const columns = Object.values(schema.tables[collection].columns);
if (query.filter) {
applyFilter(schema, dbQuery, query.filter, collection);
}
dbQuery.andWhere(function () {
columns
.map((column) => ({
...column,
localType: getLocalType(column),
}))
.forEach((column) => {
if (['text', 'string'].includes(column.localType)) {
this.orWhereRaw(`LOWER(??) LIKE ?`, [
`${column.table_name}.${column.column_name}`,
`%${query.search!.toLowerCase()}%`,
]);
} else if (['bigInteger', 'integer', 'decimal', 'float'].includes(column.localType)) {
const number = Number(query.search!);
if (!isNaN(number)) this.orWhere({ [`${column.table_name}.${column.column_name}`]: number });
} else if (column.localType === 'uuid' && validate(query.search!)) {
this.orWhere({ [`${column.table_name}.${column.column_name}`]: query.search! });
}
});
});
if (query.search) {
applySearch(schema, dbQuery, query.search, collection);
}
}
export async function applyFilter(
schema: SchemaOverview,
rootQuery: QueryBuilder,
rootFilter: Filter,
collection: string
) {
export function applyFilter(schema: SchemaOverview, rootQuery: QueryBuilder, rootFilter: Filter, collection: string) {
const relations: Relation[] = [...schema.relations, ...systemRelationRows];
const aliasMap: Record<string, string> = {};
@@ -293,6 +262,36 @@ export async function applyFilter(
}
}
export async function applySearch(
schema: SchemaOverview,
dbQuery: QueryBuilder,
searchQuery: string,
collection: string
) {
const columns = Object.values(schema.tables[collection].columns);
dbQuery.andWhere(function () {
columns
.map((column) => ({
...column,
localType: getLocalType(column),
}))
.forEach((column) => {
if (['text', 'string'].includes(column.localType)) {
this.orWhereRaw(`LOWER(??) LIKE ?`, [
`${column.table_name}.${column.column_name}`,
`%${searchQuery.toLowerCase()}%`,
]);
} else if (['bigInteger', 'integer', 'decimal', 'float'].includes(column.localType)) {
const number = Number(searchQuery);
if (!isNaN(number)) this.orWhere({ [`${column.table_name}.${column.column_name}`]: number });
} else if (column.localType === 'uuid' && validate(searchQuery)) {
this.orWhere({ [`${column.table_name}.${column.column_name}`]: searchQuery });
}
});
});
}
function getFilterPath(key: string, value: Record<string, any>) {
const path = [key];

View File

@@ -187,6 +187,7 @@ import { userName } from '@/utils/user-name';
import { usePermissions } from '@/composables/use-permissions';
import { unexpectedError } from '@/utils/unexpected-error';
import { addTokenToURL } from '@/api';
import { useUserStore } from '@/stores';
export default defineComponent({
name: 'users-item',
@@ -217,6 +218,7 @@ export default defineComponent({
const form = ref<HTMLElement>();
const fieldsStore = useFieldsStore();
const collectionsStore = useCollectionsStore();
const userStore = useUserStore();
const { primaryKey } = toRefs(props);
const { breadcrumb } = useBreadcrumb();
@@ -231,7 +233,6 @@ export default defineComponent({
item,
saving,
loading,
error,
save,
remove,
deleting,