From 9ac4659db1576a747d74d84e66c329e9d59540ca Mon Sep 17 00:00:00 2001 From: TheProgrammer21 Date: Fri, 30 Jul 2021 00:34:21 +0200 Subject: [PATCH 1/7] feat: add relation option to tree queries Add possibility to load relations of tree entities Closes: #7974 #4564 --- docs/tree-entities.md | 3 + src/find-options/FindOptionsUtils.ts | 54 ++++----- src/find-options/FindTreeOptions.ts | 11 ++ src/repository/TreeRepository.ts | 67 ++++++++--- test/github-issues/7974/entity/Category.ts | 25 ++++ test/github-issues/7974/entity/Site.ts | 21 ++++ test/github-issues/7974/issue-7974.ts | 126 +++++++++++++++++++++ 7 files changed, 262 insertions(+), 45 deletions(-) create mode 100644 src/find-options/FindTreeOptions.ts create mode 100644 test/github-issues/7974/entity/Category.ts create mode 100644 test/github-issues/7974/entity/Site.ts create mode 100644 test/github-issues/7974/issue-7974.ts diff --git a/docs/tree-entities.md b/docs/tree-entities.md index 0a0b5505e0..c75a90ce89 100644 --- a/docs/tree-entities.md +++ b/docs/tree-entities.md @@ -203,6 +203,9 @@ There are other special methods to work with tree entities through `TreeReposito ```typescript const treeCategories = await repository.findTrees(); // returns root categories with sub categories inside + +const treeCategories = await repository.findTrees({ relations: ["sites"] }); +// automatically joins the sites relation ``` * `findRoots` - Roots are entities that have no ancestors. Finds them all. diff --git a/src/find-options/FindOptionsUtils.ts b/src/find-options/FindOptionsUtils.ts index 61cd07bebb..da7dc3352e 100644 --- a/src/find-options/FindOptionsUtils.ts +++ b/src/find-options/FindOptionsUtils.ts @@ -1,9 +1,9 @@ -import {FindManyOptions} from "./FindManyOptions"; -import {FindOneOptions} from "./FindOneOptions"; -import {SelectQueryBuilder} from "../query-builder/SelectQueryBuilder"; -import {FindRelationsNotFoundError} from "../error/FindRelationsNotFoundError"; -import {EntityMetadata} from "../metadata/EntityMetadata"; -import {DriverUtils} from "../driver/DriverUtils"; +import { FindManyOptions } from "./FindManyOptions"; +import { FindOneOptions } from "./FindOneOptions"; +import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"; +import { FindRelationsNotFoundError } from "../error/FindRelationsNotFoundError"; +import { EntityMetadata } from "../metadata/EntityMetadata"; +import { DriverUtils } from "../driver/DriverUtils"; import { TypeORMError } from "../error"; /** @@ -21,23 +21,23 @@ export class FindOptionsUtils { static isFindOneOptions(obj: any): obj is FindOneOptions { const possibleOptions: FindOneOptions = obj; return possibleOptions && - ( - Array.isArray(possibleOptions.select) || - possibleOptions.where instanceof Object || - typeof possibleOptions.where === "string" || - Array.isArray(possibleOptions.relations) || - possibleOptions.join instanceof Object || - possibleOptions.order instanceof Object || - possibleOptions.cache instanceof Object || - typeof possibleOptions.cache === "boolean" || - typeof possibleOptions.cache === "number" || - possibleOptions.lock instanceof Object || - possibleOptions.loadRelationIds instanceof Object || - typeof possibleOptions.loadRelationIds === "boolean" || - typeof possibleOptions.loadEagerRelations === "boolean" || - typeof possibleOptions.withDeleted === "boolean" || - typeof possibleOptions.transaction === "boolean" - ); + ( + Array.isArray(possibleOptions.select) || + possibleOptions.where instanceof Object || + typeof possibleOptions.where === "string" || + Array.isArray(possibleOptions.relations) || + possibleOptions.join instanceof Object || + possibleOptions.order instanceof Object || + possibleOptions.cache instanceof Object || + typeof possibleOptions.cache === "boolean" || + typeof possibleOptions.cache === "number" || + possibleOptions.lock instanceof Object || + possibleOptions.loadRelationIds instanceof Object || + typeof possibleOptions.loadRelationIds === "boolean" || + typeof possibleOptions.loadEagerRelations === "boolean" || + typeof possibleOptions.withDeleted === "boolean" || + typeof possibleOptions.transaction === "boolean" + ); } /** @@ -57,7 +57,7 @@ export class FindOptionsUtils { /** * Checks if given object is really instance of FindOptions interface. */ - static extractFindManyOptionsAlias(object: any): string|undefined { + static extractFindManyOptionsAlias(object: any): string | undefined { if (this.isFindManyOptions(object) && object.join) return object.join.alias; @@ -67,7 +67,7 @@ export class FindOptionsUtils { /** * Applies give find many options to the given query builder. */ - static applyFindManyOptionsOrConditionsToQueryBuilder(qb: SelectQueryBuilder, options: FindManyOptions|Partial|undefined): SelectQueryBuilder { + static applyFindManyOptionsOrConditionsToQueryBuilder(qb: SelectQueryBuilder, options: FindManyOptions | Partial | undefined): SelectQueryBuilder { if (this.isFindManyOptions(options)) return this.applyOptionsToQueryBuilder(qb, options); @@ -80,7 +80,7 @@ export class FindOptionsUtils { /** * Applies give find options to the given query builder. */ - static applyOptionsToQueryBuilder(qb: SelectQueryBuilder, options: FindOneOptions|FindManyOptions|undefined): SelectQueryBuilder { + static applyOptionsToQueryBuilder(qb: SelectQueryBuilder, options: FindOneOptions | FindManyOptions | undefined): SelectQueryBuilder { // if options are not set then simply return query builder. This is made for simplicity of usage. if (!options || (!this.isFindOneOptions(options) && !this.isFindManyOptions(options))) @@ -222,7 +222,7 @@ export class FindOptionsUtils { /** * Adds joins for all relations and sub-relations of the given relations provided in the find options. */ - protected static applyRelationsRecursively(qb: SelectQueryBuilder, allRelations: string[], alias: string, metadata: EntityMetadata, prefix: string): void { + public static applyRelationsRecursively(qb: SelectQueryBuilder, allRelations: string[], alias: string, metadata: EntityMetadata, prefix: string): void { // find all relations that match given prefix let matchedBaseRelations: string[] = []; diff --git a/src/find-options/FindTreeOptions.ts b/src/find-options/FindTreeOptions.ts new file mode 100644 index 0000000000..8b4c8cdc3e --- /dev/null +++ b/src/find-options/FindTreeOptions.ts @@ -0,0 +1,11 @@ +/** + * Defines a special criteria to find specific entities. + */ +export interface FindTreeOptions { + + /** + * Indicates what relations of entity should be loaded (simplified left join form). + */ + relations?: string[]; + +} diff --git a/src/repository/TreeRepository.ts b/src/repository/TreeRepository.ts index b7957344e7..2ded58ff6e 100644 --- a/src/repository/TreeRepository.ts +++ b/src/repository/TreeRepository.ts @@ -1,8 +1,11 @@ -import {Repository} from "./Repository"; -import {SelectQueryBuilder} from "../query-builder/SelectQueryBuilder"; -import {ObjectLiteral} from "../common/ObjectLiteral"; -import {AbstractSqliteDriver} from "../driver/sqlite-abstract/AbstractSqliteDriver"; +import { Repository } from "./Repository"; +import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"; +import { ObjectLiteral } from "../common/ObjectLiteral"; +import { AbstractSqliteDriver } from "../driver/sqlite-abstract/AbstractSqliteDriver"; import { TypeORMError } from "../error/TypeORMError"; +import { FindTreeOptions } from "../find-options/FindTreeOptions"; +import { FindRelationsNotFoundError } from "../error"; +import { FindOptionsUtils } from "../find-options/FindOptionsUtils"; /** * Repository with additional functions to work with trees. @@ -18,23 +21,38 @@ export class TreeRepository extends Repository { /** * Gets complete trees for all roots in the table. */ - async findTrees(): Promise { - const roots = await this.findRoots(); - await Promise.all(roots.map(root => this.findDescendantsTree(root))); + async findTrees(options?: FindTreeOptions): Promise { + const roots = await this.findRoots(options); + await Promise.all(roots.map(root => this.findDescendantsTree(root, options))); return roots; } /** * Roots are entities that have no ancestors. Finds them all. */ - findRoots(): Promise { + findRoots(options?: FindTreeOptions): Promise { const escapeAlias = (alias: string) => this.manager.connection.driver.escape(alias); const escapeColumn = (column: string) => this.manager.connection.driver.escape(column); const parentPropertyName = this.manager.connection.namingStrategy.joinColumnName( this.metadata.treeParentRelation!.propertyName, this.metadata.primaryColumns[0].propertyName ); - return this.createQueryBuilder("treeEntity") + const qb = this.createQueryBuilder("treeEntity"); + + if (options?.relations) { + const allRelations = [...options.relations]; + + FindOptionsUtils.applyRelationsRecursively(qb, allRelations, qb.expressionMap.mainAlias!.name, qb.expressionMap.mainAlias!.metadata, ""); + + // recursive removes found relations from allRelations array + // if there are relations left in this array it means those relations were not found in the entity structure + // so, we give an exception about not found relations + if (allRelations.length > 0) + throw new FindRelationsNotFoundError(allRelations); + } + + + return qb .where(`${escapeAlias("treeEntity")}.${escapeColumn(parentPropertyName)} IS NULL`) .getMany(); } @@ -51,16 +69,29 @@ export class TreeRepository extends Repository { /** * Gets all children (descendants) of the given entity. Returns them in a tree - nested into each other. */ - findDescendantsTree(entity: Entity): Promise { + async findDescendantsTree(entity: Entity, options?: FindTreeOptions): Promise { // todo: throw exception if there is no column of this relation? - return this - .createDescendantsQueryBuilder("treeEntity", "treeClosure", entity) - .getRawAndEntities() - .then(entitiesAndScalars => { - const relationMaps = this.createRelationMaps("treeEntity", entitiesAndScalars.raw); - this.buildChildrenEntityTree(entity, entitiesAndScalars.entities, relationMaps); - return entity; - }); + + const qb: SelectQueryBuilder = this.createDescendantsQueryBuilder("treeEntity", "treeClosure", entity); + + if (options?.relations) { + // Copy because `applyRelationsRecursively` modifies it + const allRelations = [...options.relations]; + + FindOptionsUtils.applyRelationsRecursively(qb, allRelations, qb.expressionMap.mainAlias!.name, qb.expressionMap.mainAlias!.metadata, ""); + + // recursive removes found relations from allRelations array + // if there are relations left in this array it means those relations were not found in the entity structure + // so, we give an exception about not found relations + if (allRelations.length > 0) + throw new FindRelationsNotFoundError(allRelations); + } + + const entities = await qb.getRawAndEntities(); + const relationMaps = this.createRelationMaps("treeEntity", entities.raw); + this.buildChildrenEntityTree(entity, entities.entities, relationMaps); + + return entity; } /** diff --git a/test/github-issues/7974/entity/Category.ts b/test/github-issues/7974/entity/Category.ts new file mode 100644 index 0000000000..805913a53e --- /dev/null +++ b/test/github-issues/7974/entity/Category.ts @@ -0,0 +1,25 @@ +import { BaseEntity, Column, Entity, OneToMany, PrimaryGeneratedColumn, Tree, TreeChildren, TreeParent } from "../../../../src"; +import { Site } from "./Site"; + +@Entity() +@Tree("materialized-path") +export class Category extends BaseEntity { + + @PrimaryGeneratedColumn() + pk: number; + + @Column({ + length: 250, + nullable: false + }) + title: string; + + @TreeParent() + parentCategory: Category | null; + + @TreeChildren() + childCategories: Category[]; + + @OneToMany(() => Site, site => site.parentCategory) + sites: Site[]; +} \ No newline at end of file diff --git a/test/github-issues/7974/entity/Site.ts b/test/github-issues/7974/entity/Site.ts new file mode 100644 index 0000000000..7ce9b5e5a2 --- /dev/null +++ b/test/github-issues/7974/entity/Site.ts @@ -0,0 +1,21 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn } from "../../../../src"; +import { Category } from "./Category"; + +@Entity() +export class Site extends BaseEntity { + + @PrimaryGeneratedColumn() + pk: number; + + @CreateDateColumn() + createdAt: Date; + + @Column({ + length: 250, + nullable: false + }) + title: string; + + @ManyToOne(() => Category) + parentCategory: Category; +} \ No newline at end of file diff --git a/test/github-issues/7974/issue-7974.ts b/test/github-issues/7974/issue-7974.ts new file mode 100644 index 0000000000..1a3136e4a5 --- /dev/null +++ b/test/github-issues/7974/issue-7974.ts @@ -0,0 +1,126 @@ +import { expect } from "chai"; +import "reflect-metadata"; +import { Connection } from "../../../src"; +import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils"; +import { Category } from "./entity/Category"; +import { Site } from "./entity/Site"; + +describe("github issues > #7974 Adding relations option to findTrees()", () => { + + let connections: Connection[]; + + before(async () => connections = await createTestingConnections({ + entities: [Category, Site], + schemaCreate: true, + dropSchema: true, + enabledDrivers: ["mssql", "mariadb"] + })); + + beforeEach(async () => { + await reloadTestingDatabases(connections); + for (let connection of connections) { + let categoryRepo = connection.getRepository(Category); + let siteRepo = connection.getRepository(Site); + + let c1: Category = new Category(); + c1.title = "Category 1"; + c1.parentCategory = null; + c1.childCategories = []; + c1.sites = []; + + let c2: Category = new Category(); + c2.title = "Category 2"; + c2.parentCategory = null; + c2.childCategories = []; + c2.sites = []; + + let c3: Category = new Category(); + c3.title = "Category 1.1"; + c3.parentCategory = c1; + c3.childCategories = []; + c3.sites = []; + + let c4: Category = new Category(); + c4.title = "Category 1.1.1"; + c4.parentCategory = c3; + c4.childCategories = []; + c4.sites = []; + + c1.childCategories = [c3]; + c3.childCategories = [c4]; + + let s1: Site = new Site(); + s1.title = "Site of Category 1"; + s1.parentCategory = c1; + + let s2: Site = new Site(); + s2.title = "Site of Category 1"; + s2.parentCategory = c1; + + let s3: Site = new Site(); + s3.title = "Site of Category 1.1"; + s3.parentCategory = c3; + + let s4: Site = new Site(); + s4.title = "Site of Category 1.1"; + s4.parentCategory = c3; + + let s5: Site = new Site(); + s5.title = "Site of Category 1.1.1"; + s5.parentCategory = c4; + + // Create the categories + c1 = await categoryRepo.save(c1); + c2 = await categoryRepo.save(c2); + c3 = await categoryRepo.save(c3); + c4 = await categoryRepo.save(c4); + + // Create the sites + [s1, s2, s3, s4, s5] = + await Promise.all([ + siteRepo.save(s1), + siteRepo.save(s2), + siteRepo.save(s3), + siteRepo.save(s4), + siteRepo.save(s5) + ]); + + // Set the just created relations correctly + c1.sites = [s1, s2]; + c2.sites = []; + c3.sites = [s3, s4]; + c4.sites = [s5]; + } + }); + + after(() => closeTestingConnections(connections)); + + it("should return tree without sites relations", async () => await Promise.all(connections.map(async connection => { + + let result = await connection.getTreeRepository(Category).findTrees(); + + // The complete tree should exist but other relations than the parent- / child-relations should not be loaded + expect(result).to.have.lengthOf(2); + expect(result[0].sites).equals(undefined); + expect(result[0].childCategories).to.have.lengthOf(1); + expect(result[0].childCategories[0].childCategories).to.have.lengthOf(1); + expect(result[0].childCategories[0].childCategories[0].sites).equal(undefined); + + }))); + + it("should return tree with sites relations", async () => await Promise.all(connections.map(async connection => { + + let result = await connection.getTreeRepository(Category).findTrees({ relations: ["sites"] }); + + // The complete tree should exist and site relations should not be loaded for every category + expect(result).to.have.lengthOf(2); + expect(result[0].sites).lengthOf(2); + expect(result[1].sites).to.be.an("array"); + expect(result[1].sites).to.have.lengthOf(0); + expect(result[0].childCategories[0].sites).to.have.lengthOf(2); + expect(result[0].childCategories[0].childCategories[0].sites).to.have.lengthOf(1); + expect(result[0].childCategories[0].childCategories[0].sites).to.be.an("array"); + expect(result[0].childCategories[0].childCategories[0].sites[0].title).to.be.equal("Site of Category 1.1.1"); + }))); + +}); \ No newline at end of file From 9357058911cece8e54e44263e90d6c8817d60cfd Mon Sep 17 00:00:00 2001 From: Lukas Windisch <52009814+TheProgrammer21@users.noreply.github.com> Date: Fri, 30 Jul 2021 01:06:46 +0200 Subject: [PATCH 2/7] style: remove unused declaration remove unused declaration to satisfy linting. --- src/find-options/FindTreeOptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/find-options/FindTreeOptions.ts b/src/find-options/FindTreeOptions.ts index 8b4c8cdc3e..c8eb2002bc 100644 --- a/src/find-options/FindTreeOptions.ts +++ b/src/find-options/FindTreeOptions.ts @@ -1,7 +1,7 @@ /** * Defines a special criteria to find specific entities. */ -export interface FindTreeOptions { +export interface FindTreeOptions { /** * Indicates what relations of entity should be loaded (simplified left join form). From 44e35c5e38fedffb7569ed44a21ef2ba1a52fdfa Mon Sep 17 00:00:00 2001 From: TheProgrammer21 Date: Mon, 2 Aug 2021 20:38:56 +0200 Subject: [PATCH 3/7] Update tree-entities.md docs: rename variable for copy paste --- docs/tree-entities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tree-entities.md b/docs/tree-entities.md index c75a90ce89..5cbafc35af 100644 --- a/docs/tree-entities.md +++ b/docs/tree-entities.md @@ -204,7 +204,7 @@ There are other special methods to work with tree entities through `TreeReposito const treeCategories = await repository.findTrees(); // returns root categories with sub categories inside -const treeCategories = await repository.findTrees({ relations: ["sites"] }); +const treeCategoriesWithRelations = await repository.findTrees({ relations: ["sites"] }); // automatically joins the sites relation ``` From bba5d6acca109dcd614e11fe514ceb1faeed4f62 Mon Sep 17 00:00:00 2001 From: Lukas Windisch <52009814+TheProgrammer21@users.noreply.github.com> Date: Mon, 2 Aug 2021 20:46:06 +0200 Subject: [PATCH 4/7] Update FindOptionsUtils.ts style: remove prettified code --- src/find-options/FindOptionsUtils.ts | 55 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/find-options/FindOptionsUtils.ts b/src/find-options/FindOptionsUtils.ts index da7dc3352e..397d0bcaed 100644 --- a/src/find-options/FindOptionsUtils.ts +++ b/src/find-options/FindOptionsUtils.ts @@ -1,10 +1,10 @@ -import { FindManyOptions } from "./FindManyOptions"; -import { FindOneOptions } from "./FindOneOptions"; -import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"; -import { FindRelationsNotFoundError } from "../error/FindRelationsNotFoundError"; -import { EntityMetadata } from "../metadata/EntityMetadata"; -import { DriverUtils } from "../driver/DriverUtils"; -import { TypeORMError } from "../error"; +import {FindManyOptions} from "./FindManyOptions"; +import {FindOneOptions} from "./FindOneOptions"; +import {SelectQueryBuilder} from "../query-builder/SelectQueryBuilder"; +import {FindRelationsNotFoundError} from "../error/FindRelationsNotFoundError"; +import {EntityMetadata} from "../metadata/EntityMetadata"; +import {DriverUtils} from "../driver/DriverUtils"; +import {TypeORMError} from "../error"; /** * Utilities to work with FindOptions. @@ -21,23 +21,24 @@ export class FindOptionsUtils { static isFindOneOptions(obj: any): obj is FindOneOptions { const possibleOptions: FindOneOptions = obj; return possibleOptions && - ( - Array.isArray(possibleOptions.select) || - possibleOptions.where instanceof Object || - typeof possibleOptions.where === "string" || - Array.isArray(possibleOptions.relations) || - possibleOptions.join instanceof Object || - possibleOptions.order instanceof Object || - possibleOptions.cache instanceof Object || - typeof possibleOptions.cache === "boolean" || - typeof possibleOptions.cache === "number" || - possibleOptions.lock instanceof Object || - possibleOptions.loadRelationIds instanceof Object || - typeof possibleOptions.loadRelationIds === "boolean" || - typeof possibleOptions.loadEagerRelations === "boolean" || - typeof possibleOptions.withDeleted === "boolean" || - typeof possibleOptions.transaction === "boolean" - ); + ( + Array.isArray(possibleOptions.select) || + possibleOptions.where instanceof Object || + typeof possibleOptions.where === "string" || + Array.isArray(possibleOptions.relations) || + possibleOptions.join instanceof Object || + possibleOptions.order instanceof Object || + possibleOptions.cache instanceof Object || + typeof possibleOptions.cache === "boolean" || + typeof possibleOptions.cache === "number" || + possibleOptions.lock instanceof Object || + possibleOptions.loadRelationIds instanceof Object || + typeof possibleOptions.loadRelationIds === "boolean" || + typeof possibleOptions.loadEagerRelations === "boolean" || + typeof possibleOptions.withDeleted === "boolean" || + typeof possibleOptions.transaction === "boolean" + ); + } /** @@ -57,7 +58,7 @@ export class FindOptionsUtils { /** * Checks if given object is really instance of FindOptions interface. */ - static extractFindManyOptionsAlias(object: any): string | undefined { + static extractFindManyOptionsAlias(object: any): string|undefined { if (this.isFindManyOptions(object) && object.join) return object.join.alias; @@ -67,7 +68,7 @@ export class FindOptionsUtils { /** * Applies give find many options to the given query builder. */ - static applyFindManyOptionsOrConditionsToQueryBuilder(qb: SelectQueryBuilder, options: FindManyOptions | Partial | undefined): SelectQueryBuilder { + static applyFindManyOptionsOrConditionsToQueryBuilder(qb: SelectQueryBuilder, options: FindManyOptions|Partial|undefined): SelectQueryBuilder { if (this.isFindManyOptions(options)) return this.applyOptionsToQueryBuilder(qb, options); @@ -80,7 +81,7 @@ export class FindOptionsUtils { /** * Applies give find options to the given query builder. */ - static applyOptionsToQueryBuilder(qb: SelectQueryBuilder, options: FindOneOptions | FindManyOptions | undefined): SelectQueryBuilder { + static applyOptionsToQueryBuilder(qb: SelectQueryBuilder, options: FindOneOptions|FindManyOptions|undefined): SelectQueryBuilder { // if options are not set then simply return query builder. This is made for simplicity of usage. if (!options || (!this.isFindOneOptions(options) && !this.isFindManyOptions(options))) From 0546ef26bd3b3a981e446de8f92a1901f9a72786 Mon Sep 17 00:00:00 2001 From: Lukas Windisch <52009814+TheProgrammer21@users.noreply.github.com> Date: Mon, 2 Aug 2021 20:48:58 +0200 Subject: [PATCH 5/7] style: remove prettified code --- src/repository/TreeRepository.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/repository/TreeRepository.ts b/src/repository/TreeRepository.ts index 2ded58ff6e..e144e7a1a3 100644 --- a/src/repository/TreeRepository.ts +++ b/src/repository/TreeRepository.ts @@ -1,7 +1,7 @@ -import { Repository } from "./Repository"; -import { SelectQueryBuilder } from "../query-builder/SelectQueryBuilder"; -import { ObjectLiteral } from "../common/ObjectLiteral"; -import { AbstractSqliteDriver } from "../driver/sqlite-abstract/AbstractSqliteDriver"; +import {Repository} from "./Repository"; +import {SelectQueryBuilder} from "../query-builder/SelectQueryBuilder"; +import {ObjectLiteral} from "../common/ObjectLiteral"; +import {AbstractSqliteDriver} from "../driver/sqlite-abstract/AbstractSqliteDriver"; import { TypeORMError } from "../error/TypeORMError"; import { FindTreeOptions } from "../find-options/FindTreeOptions"; import { FindRelationsNotFoundError } from "../error"; From 230593625e21541c5f554e755a3f572c407b9da7 Mon Sep 17 00:00:00 2001 From: Lukas Windisch <52009814+TheProgrammer21@users.noreply.github.com> Date: Mon, 2 Aug 2021 20:50:55 +0200 Subject: [PATCH 6/7] style: remove prettified code --- src/find-options/FindOptionsUtils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/find-options/FindOptionsUtils.ts b/src/find-options/FindOptionsUtils.ts index 397d0bcaed..7fdd4a0e26 100644 --- a/src/find-options/FindOptionsUtils.ts +++ b/src/find-options/FindOptionsUtils.ts @@ -4,7 +4,7 @@ import {SelectQueryBuilder} from "../query-builder/SelectQueryBuilder"; import {FindRelationsNotFoundError} from "../error/FindRelationsNotFoundError"; import {EntityMetadata} from "../metadata/EntityMetadata"; import {DriverUtils} from "../driver/DriverUtils"; -import {TypeORMError} from "../error"; +import { TypeORMError } from "../error"; /** * Utilities to work with FindOptions. @@ -38,7 +38,6 @@ export class FindOptionsUtils { typeof possibleOptions.withDeleted === "boolean" || typeof possibleOptions.transaction === "boolean" ); - } /** From 7f7c7e97e76dc60e0c9fc7f481e083a7ef7d1135 Mon Sep 17 00:00:00 2001 From: Lukas Windisch <52009814+TheProgrammer21@users.noreply.github.com> Date: Wed, 4 Aug 2021 14:57:32 +0200 Subject: [PATCH 7/7] test: enable test for all drivers --- test/github-issues/7974/issue-7974.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/github-issues/7974/issue-7974.ts b/test/github-issues/7974/issue-7974.ts index 1a3136e4a5..31a7a0a1d0 100644 --- a/test/github-issues/7974/issue-7974.ts +++ b/test/github-issues/7974/issue-7974.ts @@ -12,8 +12,7 @@ describe("github issues > #7974 Adding relations option to findTrees()", () => { before(async () => connections = await createTestingConnections({ entities: [Category, Site], schemaCreate: true, - dropSchema: true, - enabledDrivers: ["mssql", "mariadb"] + dropSchema: true })); beforeEach(async () => { @@ -123,4 +122,4 @@ describe("github issues > #7974 Adding relations option to findTrees()", () => { expect(result[0].childCategories[0].childCategories[0].sites[0].title).to.be.equal("Site of Category 1.1.1"); }))); -}); \ No newline at end of file +});