Skip to content

Commit 1883c2d

Browse files
authored
fix: sql query for multifilter (#970)
1 parent 189f937 commit 1883c2d

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed

src/filter.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ export function addFilter<T>(
322322
const filter = parseFilter(query, filterableColumns)
323323

324324
const filterEntries = Object.entries(filter)
325-
const orFilters = filterEntries.filter(([_, value]) => value.some((v) => v.comparator === '$or'))
326-
const andFilters = filterEntries.filter(([_, value]) => value.some((v) => v.comparator !== '$or'))
325+
const orFilters = filterEntries.filter(([_, value]) => value[0].comparator === '$or')
326+
const andFilters = filterEntries.filter(([_, value]) => value[0].comparator === '$and')
327327

328328
qb.andWhere(
329329
new Brackets((qb: SelectQueryBuilder<T>) => {
@@ -333,13 +333,13 @@ export function addFilter<T>(
333333
})
334334
)
335335

336-
qb.andWhere(
337-
new Brackets((qb: SelectQueryBuilder<T>) => {
338-
for (const [column] of andFilters) {
336+
for (const [column] of andFilters) {
337+
qb.andWhere(
338+
new Brackets((qb: SelectQueryBuilder<T>) => {
339339
addWhereCondition(qb, column, filter)
340-
}
341-
})
342-
)
340+
})
341+
)
342+
}
343343

344344
return qb
345345
}

src/paginate.spec.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,6 +2255,89 @@ describe('paginate', () => {
22552255
)
22562256
})
22572257

2258+
it('should return result based on two multifilters chained together with and operator', async () => {
2259+
const config: PaginateConfig<CatEntity> = {
2260+
sortableColumns: ['id'],
2261+
filterableColumns: {
2262+
name: true,
2263+
color: true,
2264+
},
2265+
}
2266+
const query: PaginateQuery = {
2267+
path: '',
2268+
filter: {
2269+
name: ['Milo', '$or:Garfield'],
2270+
color: ['brown', '$or:white'],
2271+
},
2272+
}
2273+
const result = await paginate<CatEntity>(query, catRepo, config)
2274+
const expected = cats.filter(
2275+
(cat) =>
2276+
(cat.name === 'Milo' || cat.name === 'Garfield') && (cat.color === 'brown' || cat.color === 'white')
2277+
)
2278+
expect(result.data).toStrictEqual(expected)
2279+
expect(result.links.current).toBe(
2280+
'?page=1&limit=20&sortBy=id:ASC&filter.name=Milo&filter.name=$or:Garfield&filter.color=brown&filter.color=$or:white'
2281+
)
2282+
})
2283+
2284+
it('should return result based on two multifilters chained together with or operator', async () => {
2285+
const config: PaginateConfig<CatEntity> = {
2286+
sortableColumns: ['id'],
2287+
filterableColumns: {
2288+
name: true,
2289+
color: true,
2290+
},
2291+
}
2292+
const query: PaginateQuery = {
2293+
path: '',
2294+
filter: {
2295+
name: ['$or:Milo', '$or:Garfield'],
2296+
color: ['$or:brown', '$or:white'],
2297+
},
2298+
}
2299+
const result = await paginate<CatEntity>(query, catRepo, config)
2300+
const expected = cats.filter(
2301+
(cat) => cat.name === 'Milo' || cat.name === 'Garfield' || cat.color === 'brown' || cat.color === 'white'
2302+
)
2303+
expect(result.data).toStrictEqual(expected)
2304+
expect(result.links.current).toBe(
2305+
'?page=1&limit=20&sortBy=id:ASC&filter.name=$or:Milo&filter.name=$or:Garfield&filter.color=$or:brown&filter.color=$or:white'
2306+
)
2307+
})
2308+
2309+
it('should return result based on filters chained together with and operators and or operators', async () => {
2310+
const config: PaginateConfig<CatEntity> = {
2311+
sortableColumns: ['id'],
2312+
filterableColumns: {
2313+
name: true,
2314+
color: true,
2315+
age: true,
2316+
cutenessLevel: true,
2317+
},
2318+
}
2319+
const query: PaginateQuery = {
2320+
path: '',
2321+
filter: {
2322+
name: ['$or:Milo', '$or:Garfield'],
2323+
age: '$or:$null',
2324+
color: ['brown', '$or:white'],
2325+
cutenessLevel: [CutenessLevel.HIGH, `$or:${CutenessLevel.LOW}`],
2326+
},
2327+
}
2328+
const result = await paginate<CatEntity>(query, catRepo, config)
2329+
const expected = cats.filter(
2330+
(cat) =>
2331+
(cat.name === 'Milo' || cat.name === 'Garfield' || !cat.age) &&
2332+
(cat.color === 'brown' || cat.color === 'white') &&
2333+
(cat.cutenessLevel === CutenessLevel.HIGH || cat.cutenessLevel === CutenessLevel.LOW)
2334+
)
2335+
expect(result.data).toStrictEqual(expected)
2336+
expect(result.links.current).toBe(
2337+
'?page=1&limit=20&sortBy=id:ASC&filter.name=$or:Milo&filter.name=$or:Garfield&filter.age=$or:$null&filter.color=brown&filter.color=$or:white&filter.cutenessLevel=high&filter.cutenessLevel=$or:low'
2338+
)
2339+
})
2340+
22582341
it("should return all columns if select doesn't contain all primary columns", async () => {
22592342
const config: PaginateConfig<CatEntity> = {
22602343
sortableColumns: ['id', 'name'],

0 commit comments

Comments
 (0)