use hash map for op function lookup
This commit is contained in:
parent
7d85cf94b0
commit
3b09c1c90d
@ -5,8 +5,8 @@ import {
|
||||
PaginateConfig,
|
||||
FilterOperator,
|
||||
isOperator,
|
||||
getOperatorFn,
|
||||
getFilterTokens,
|
||||
OperatorSymbolToFunction,
|
||||
} from './paginate'
|
||||
import { PaginateQuery } from './decorator'
|
||||
import { Entity, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm'
|
||||
@ -45,7 +45,7 @@ describe('paginate', () => {
|
||||
repo = connection.getRepository(CatEntity)
|
||||
cats = await repo.save([
|
||||
repo.create({ name: 'Milo', color: 'brown', age: 6 }),
|
||||
repo.create({ name: 'Garfield', color: 'ginger', age: null }),
|
||||
repo.create({ name: 'Garfield', color: 'ginger', age: 5 }),
|
||||
repo.create({ name: 'Shadow', color: 'black', age: 4 }),
|
||||
repo.create({ name: 'George', color: 'white', age: 3 }),
|
||||
repo.create({ name: 'Leche', color: 'white', age: null }),
|
||||
@ -342,7 +342,7 @@ describe('paginate', () => {
|
||||
|
||||
const result = await paginate<CatEntity>(query, repo, config)
|
||||
|
||||
expect(result.data).toStrictEqual([cats[0], cats[2]])
|
||||
expect(result.data).toStrictEqual([cats[0], cats[1], cats[2]])
|
||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$gte:4')
|
||||
})
|
||||
|
||||
@ -356,14 +356,14 @@ describe('paginate', () => {
|
||||
const query: PaginateQuery = {
|
||||
path: '',
|
||||
filter: {
|
||||
age: '$btw:4,6',
|
||||
age: '$btw:4,5',
|
||||
},
|
||||
}
|
||||
|
||||
const result = await paginate<CatEntity>(query, repo, config)
|
||||
|
||||
expect(result.data).toStrictEqual([cats[0], cats[2]])
|
||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$btw:4,6')
|
||||
expect(result.data).toStrictEqual([cats[1], cats[2]])
|
||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$btw:4,5')
|
||||
})
|
||||
|
||||
it('should return result based on is null query', async () => {
|
||||
@ -382,7 +382,7 @@ describe('paginate', () => {
|
||||
|
||||
const result = await paginate<CatEntity>(query, repo, config)
|
||||
|
||||
expect(result.data).toStrictEqual([cats[1], cats[4]])
|
||||
expect(result.data).toStrictEqual([cats[4]])
|
||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$null')
|
||||
})
|
||||
|
||||
@ -402,7 +402,7 @@ describe('paginate', () => {
|
||||
|
||||
const result = await paginate<CatEntity>(query, repo, config)
|
||||
|
||||
expect(result.data).toStrictEqual([cats[0], cats[2], cats[3]])
|
||||
expect(result.data).toStrictEqual([cats[0], cats[1], cats[2], cats[3]])
|
||||
expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&filter.age=$not:$null')
|
||||
})
|
||||
|
||||
@ -487,7 +487,7 @@ describe('paginate', () => {
|
||||
{ operator: '$btw', name: 'Between' },
|
||||
{ operator: '$not', name: 'Not' },
|
||||
])('should get operator function $name for "$operator"', ({ operator, name }) => {
|
||||
const func = getOperatorFn<CatEntity>(operator as FilterOperator)
|
||||
const func = OperatorSymbolToFunction.get(operator as FilterOperator)
|
||||
expect(func.name).toStrictEqual(name)
|
||||
})
|
||||
|
||||
|
@ -72,28 +72,17 @@ export function isOperator(value: unknown): value is FilterOperator {
|
||||
return values(FilterOperator).includes(value as any)
|
||||
}
|
||||
|
||||
export function getOperatorFn<T>(op: FilterOperator): (...args: any[]) => FindOperator<T> {
|
||||
switch (op) {
|
||||
case FilterOperator.EQ:
|
||||
return Equal
|
||||
case FilterOperator.GT:
|
||||
return MoreThan
|
||||
case FilterOperator.GTE:
|
||||
return MoreThanOrEqual
|
||||
case FilterOperator.IN:
|
||||
return In
|
||||
case FilterOperator.NULL:
|
||||
return IsNull
|
||||
case FilterOperator.LT:
|
||||
return LessThan
|
||||
case FilterOperator.LTE:
|
||||
return LessThanOrEqual
|
||||
case FilterOperator.BTW:
|
||||
return Between
|
||||
case FilterOperator.NOT:
|
||||
return Not
|
||||
}
|
||||
}
|
||||
export const OperatorSymbolToFunction = new Map<FilterOperator, (...args: any[]) => FindOperator<string>>([
|
||||
[FilterOperator.EQ, Equal],
|
||||
[FilterOperator.GT, MoreThan],
|
||||
[FilterOperator.GTE, MoreThanOrEqual],
|
||||
[FilterOperator.IN, In],
|
||||
[FilterOperator.NULL, IsNull],
|
||||
[FilterOperator.LT, LessThan],
|
||||
[FilterOperator.LTE, LessThanOrEqual],
|
||||
[FilterOperator.BTW, Between],
|
||||
[FilterOperator.NOT, Not],
|
||||
])
|
||||
|
||||
export function getFilterTokens(raw: string): string[] {
|
||||
const tokens = []
|
||||
@ -125,12 +114,11 @@ export function getFilterTokens(raw: string): string[] {
|
||||
|
||||
function parseFilter<T>(query: PaginateQuery, config: PaginateConfig<T>) {
|
||||
const filter = {}
|
||||
|
||||
for (const column of Object.keys(query.filter)) {
|
||||
if (!(column in config.filterableColumns)) {
|
||||
continue
|
||||
}
|
||||
const allowedOperators = config.filterableColumns[column as Column<T>]
|
||||
const allowedOperators = config.filterableColumns[column]
|
||||
const input = query.filter[column]
|
||||
const statements = !Array.isArray(input) ? [input] : input
|
||||
for (const raw of statements) {
|
||||
@ -147,12 +135,20 @@ function parseFilter<T>(query: PaginateQuery, config: PaginateConfig<T>) {
|
||||
continue
|
||||
}
|
||||
if (isOperator(op1)) {
|
||||
const args = op1 === FilterOperator.IN || op1 === FilterOperator.BTW ? value.split(',') : value
|
||||
filter[column] =
|
||||
op1 === FilterOperator.BTW ? getOperatorFn<T>(op1)(args[0], args[1]) : getOperatorFn<T>(op1)(args)
|
||||
switch (op1) {
|
||||
case FilterOperator.BTW:
|
||||
filter[column] = OperatorSymbolToFunction.get(op1)(...value.split(','))
|
||||
break
|
||||
case FilterOperator.IN:
|
||||
filter[column] = OperatorSymbolToFunction.get(op1)(value.split(','))
|
||||
break
|
||||
default:
|
||||
filter[column] = OperatorSymbolToFunction.get(op1)(value)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (isOperator(op2)) {
|
||||
filter[column] = getOperatorFn<T>(op2)(filter[column])
|
||||
filter[column] = OperatorSymbolToFunction.get(op2)(filter[column])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,7 +232,7 @@ export async function paginate<T>(
|
||||
}
|
||||
|
||||
if (query.filter) {
|
||||
const filter = parseFilter<T>(query, config)
|
||||
const filter = parseFilter(query, config)
|
||||
queryBuilder.andWhere(new Brackets((qb) => qb.andWhere(filter)))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user