Skip to content

Commit

Permalink
fix: Resolve SQL Relationship Filtering
Browse files Browse the repository at this point in the history
In this commit, I address the issue where relations filters were not being applied. Also adding tests.
  • Loading branch information
cbjjensen committed Dec 5, 2023
1 parent d59e602 commit 25b892f
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nestjs-query",
"version": "4.3.2",
"version": "4.3.3",
"private": true,
"workspaces": [
"packages/**"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ FROM
"test_entity" "TestEntity""
`;

exports[`FilterQueryBuilder #select with paging should apply filtering on one to many relations query filter 1`] = `
"SELECT
"TestEntity"."test_entity_pk" AS "TestEntity_test_entity_pk",
"TestEntity"."string_type" AS "TestEntity_string_type",
"TestEntity"."bool_type" AS "TestEntity_bool_type",
"TestEntity"."number_type" AS "TestEntity_number_type",
"TestEntity"."date_type" AS "TestEntity_date_type",
"TestEntity"."many_to_one_relation_id" AS "TestEntity_many_to_one_relation_id",
"TestEntity"."many_to_one_soft_delete_relation_id" AS "TestEntity_many_to_one_soft_delete_relation_id",
"TestEntity"."oneTestRelationTestRelationPk" AS "TestEntity_oneTestRelationTestRelationPk",
"oneTestRelation"."test_relation_pk" AS "oneTestRelation_test_relation_pk",
"oneTestRelation"."relation_name" AS "oneTestRelation_relation_name",
"oneTestRelation"."test_entity_id" AS "oneTestRelation_test_entity_id",
"oneTestRelation"."uni_directional_test_entity_id" AS "oneTestRelation_uni_directional_test_entity_id",
"oneTestRelation"."uni_directional_relation_test_entity_id" AS "oneTestRelation_uni_directional_relation_test_entity_id"
FROM
"test_entity" "TestEntity"
LEFT JOIN "test_relation" "oneTestRelation" ON "oneTestRelation"."test_relation_pk" = "TestEntity"."oneTestRelationTestRelationPk""
`;

exports[`FilterQueryBuilder #select with paging should apply paging args going backward 1`] = `
"SELECT
"TestEntity"."test_entity_pk" AS "TestEntity_test_entity_pk",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Class, Filter, Query, SortDirection, SortNulls } from '@ptc-org/nestjs-query-core'
import { format as formatSql } from 'sql-formatter'
import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito'
import { DataSource, QueryBuilder, WhereExpressionBuilder } from 'typeorm'
import { Connection, DataSource, Driver, EntityManager, QueryBuilder, Repository, WhereExpressionBuilder } from 'typeorm'

import { FilterQueryBuilder, WhereBuilder } from '../../src/query'
import { createTestConnection } from '../__fixtures__/connection.fixture'
Expand Down Expand Up @@ -230,6 +230,7 @@ describe('FilterQueryBuilder', (): void => {
})
})


describe('#select', () => {
const expectSelectSQLSnapshot = (query: Query<TestEntity>, whereBuilder: WhereBuilder<TestEntity>): void => {
const selectQueryBuilder = getEntityQueryBuilder(TestEntity, whereBuilder).select(query)
Expand Down Expand Up @@ -303,6 +304,28 @@ describe('FilterQueryBuilder', (): void => {
)
})

it('should apply filtering on one to many relations query filter', () => {
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder)
when(mockWhereBuilder.build(anything(), anything(), anything(), anything())).thenCall((qb: WhereExpressionBuilder) => qb)

expectSelectSQLSnapshot(
{
filter: { stringType: { eq: 'test' } },
relations: [{
name: 'oneTestRelation',
query: {
filter: {
numberType: { eq: 123 }
},
},

}]
},
instance(mockWhereBuilder)
)
})


it('should use limit/offset when filtering on one to one relation', () => {
const mockWhereBuilder = mock<WhereBuilder<TestEntity>>(WhereBuilder)
when(mockWhereBuilder.build(anything(), anything(), anything(), anything())).thenCall((qb: WhereExpressionBuilder) => qb)
Expand Down Expand Up @@ -422,6 +445,7 @@ describe('FilterQueryBuilder', (): void => {
instance(mockWhereBuilder)
)
})

})
})

Expand Down
13 changes: 5 additions & 8 deletions packages/query-typeorm/src/query/filter-query.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class FilterQueryBuilder<Entity> {
readonly repo: Repository<Entity>,
readonly whereBuilder: WhereBuilder<Entity> = new WhereBuilder<Entity>(),
readonly aggregateBuilder: AggregateBuilder<Entity> = new AggregateBuilder<Entity>(repo)
) {}
) { }

/**
* Create a `typeorm` SelectQueryBuilder with `WHERE`, `ORDER BY` and `LIMIT/OFFSET` clauses.
Expand Down Expand Up @@ -278,17 +278,14 @@ export class FilterQueryBuilder<Entity> {
const relationAlias = relation.alias
const relationChildren = relation.relations

// TODO:: Change to find and also apply the query for the relation
const selectRelation = selectRelations && selectRelations.find(({ name }) => name === relationKey)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion

if (selectRelation) {
return this.applyRelationJoinsRecursive(
rqb.leftJoinAndSelect(`${alias ?? rqb.alias}.${relationKey}`, relationAlias),
relationChildren,
selectRelation.query.relations,
relationAlias
)
rqb = rqb.leftJoinAndSelect(`${alias ?? rqb.alias}.${relationKey}`, relationAlias);
// Apply filter for the current relation
rqb = this.applyFilter(rqb, selectRelation.query.filter, relationAlias);
return this.applyRelationJoinsRecursive(rqb, relationChildren, selectRelation.query.relations, relationAlias);
}

return this.applyRelationJoinsRecursive(
Expand Down

0 comments on commit 25b892f

Please sign in to comment.