{"version":3,"sources":["../browser/src/query-builder/relation-count/RelationCountLoader.ts"],"names":[],"mappings":"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","file":"RelationCountLoader.js","sourcesContent":["import {ColumnMetadata} from \"../../metadata/ColumnMetadata\";\nimport {Connection} from \"../../connection/Connection\";\nimport {RelationCountAttribute} from \"./RelationCountAttribute\";\nimport {RelationCountLoadResult} from \"./RelationCountLoadResult\";\nimport {QueryRunner} from \"../../query-runner/QueryRunner\";\n\nexport class RelationCountLoader {\n\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(protected connection: Connection,\n protected queryRunner: QueryRunner|undefined,\n protected relationCountAttributes: RelationCountAttribute[]) {\n }\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n async load(rawEntities: any[]): Promise<RelationCountLoadResult[]> {\n\n const onlyUnique = (value: any, index: number, self: any) => {\n return self.indexOf(value) === index;\n };\n\n const promises = this.relationCountAttributes.map(async relationCountAttr => {\n\n if (relationCountAttr.relation.isOneToMany) {\n // example: Post and Category\n // loadRelationCountAndMap(\"post.categoryCount\", \"post.categories\")\n // we expect it to load array of post ids\n\n // todo(dima): fix issues wit multiple primary keys and remove joinColumns[0]\n const relation = relationCountAttr.relation; // \"category.posts\"\n const inverseRelation = relation.inverseRelation!; // \"post.category\"\n const referenceColumnName = inverseRelation.joinColumns[0].referencedColumn!.propertyName; // post id\n const inverseSideTable = relation.inverseEntityMetadata.target; // Post\n const inverseSideTableName = relation.inverseEntityMetadata.tableName; // post\n const inverseSideTableAlias = relationCountAttr.alias || inverseSideTableName; // if condition (custom query builder factory) is set then relationIdAttr.alias defined\n const inverseSidePropertyName = inverseRelation.propertyName; // \"category\" from \"post.category\"\n\n let referenceColumnValues = rawEntities\n .map(rawEntity => rawEntity[relationCountAttr.parentAlias + \"_\" + referenceColumnName])\n .filter(value => !!value);\n referenceColumnValues = referenceColumnValues.filter(onlyUnique);\n\n // ensure we won't perform redundant queries for joined data which was not found in selection\n // example: if post.category was not found in db then no need to execute query for category.imageIds\n if (referenceColumnValues.length === 0)\n return { relationCountAttribute: relationCountAttr, results: [] };\n\n // generate query:\n // SELECT category.post as parentId, COUNT(*) AS cnt FROM category category WHERE category.post IN (1, 2) GROUP BY category.post\n const qb = this.connection.createQueryBuilder(this.queryRunner);\n qb.select(inverseSideTableAlias + \".\" + inverseSidePropertyName, \"parentId\")\n .addSelect(\"COUNT(*)\", \"cnt\")\n .from(inverseSideTable, inverseSideTableAlias)\n .where(inverseSideTableAlias + \".\" + inverseSidePropertyName + \" IN (:...ids)\")\n .addGroupBy(inverseSideTableAlias + \".\" + inverseSidePropertyName)\n .setParameter(\"ids\", referenceColumnValues);\n\n // apply condition (custom query builder factory)\n if (relationCountAttr.queryBuilderFactory)\n relationCountAttr.queryBuilderFactory(qb);\n\n return {\n relationCountAttribute: relationCountAttr,\n results: await qb.getRawMany()\n };\n\n } else {\n // example: Post and Category\n // owner side: loadRelationIdAndMap(\"post.categoryIds\", \"post.categories\")\n // inverse side: loadRelationIdAndMap(\"category.postIds\", \"category.posts\")\n // we expect it to load array of post ids\n\n let joinTableColumnName: string;\n let inverseJoinColumnName: string;\n let firstJunctionColumn: ColumnMetadata;\n let secondJunctionColumn: ColumnMetadata;\n\n if (relationCountAttr.relation.isOwning) { // todo fix joinColumns[0] and inverseJoinColumns[0].\n joinTableColumnName = relationCountAttr.relation.joinColumns[0].referencedColumn!.databaseName;\n inverseJoinColumnName = relationCountAttr.relation.inverseJoinColumns[0].referencedColumn!.databaseName;\n firstJunctionColumn = relationCountAttr.relation.junctionEntityMetadata!.columns[0];\n secondJunctionColumn = relationCountAttr.relation.junctionEntityMetadata!.columns[1];\n\n } else {\n joinTableColumnName = relationCountAttr.relation.inverseRelation!.inverseJoinColumns[0].referencedColumn!.databaseName;\n inverseJoinColumnName = relationCountAttr.relation.inverseRelation!.joinColumns[0].referencedColumn!.databaseName;\n firstJunctionColumn = relationCountAttr.relation.junctionEntityMetadata!.columns[1];\n secondJunctionColumn = relationCountAttr.relation.junctionEntityMetadata!.columns[0];\n }\n\n let referenceColumnValues = rawEntities\n .map(rawEntity => rawEntity[relationCountAttr.parentAlias + \"_\" + joinTableColumnName])\n .filter(value => !!value);\n referenceColumnValues = referenceColumnValues.filter(onlyUnique);\n\n // ensure we won't perform redundant queries for joined data which was not found in selection\n // example: if post.category was not found in db then no need to execute query for category.imageIds\n if (referenceColumnValues.length === 0)\n return { relationCountAttribute: relationCountAttr, results: [] };\n\n const junctionAlias = relationCountAttr.junctionAlias;\n const inverseSideTableName = relationCountAttr.joinInverseSideMetadata.tableName;\n const inverseSideTableAlias = relationCountAttr.alias || inverseSideTableName;\n const junctionTableName = relationCountAttr.relation.junctionEntityMetadata!.tableName;\n const condition = junctionAlias + \".\" + firstJunctionColumn.propertyName + \" IN (\" + referenceColumnValues + \")\" +\n \" AND \" + junctionAlias + \".\" + secondJunctionColumn.propertyName + \" = \" + inverseSideTableAlias + \".\" + inverseJoinColumnName;\n\n const qb = this.connection.createQueryBuilder(this.queryRunner);\n qb.select(junctionAlias + \".\" + firstJunctionColumn.propertyName, \"parentId\")\n .addSelect(\"COUNT(\" + qb.escape(inverseSideTableAlias) + \".\" + qb.escape(inverseJoinColumnName) + \")\", \"cnt\")\n .from(inverseSideTableName, inverseSideTableAlias)\n .innerJoin(junctionTableName, junctionAlias, condition)\n .addGroupBy(junctionAlias + \".\" + firstJunctionColumn.propertyName);\n\n // apply condition (custom query builder factory)\n if (relationCountAttr.queryBuilderFactory)\n relationCountAttr.queryBuilderFactory(qb);\n\n return {\n relationCountAttribute: relationCountAttr,\n results: await qb.getRawMany()\n };\n }\n });\n\n return Promise.all(promises);\n }\n\n}\n"],"sourceRoot":"../.."}
|