mirror of
https://github.com/directus/directus.git
synced 2026-04-03 03:00:39 -04:00
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user