333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
{"version":3,"sources":["../browser/src/query-builder/RelationLoader.ts"],"names":[],"mappings":"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","file":"RelationLoader.js","sourcesContent":["import {Connection, ObjectLiteral, QueryRunner} from \"../\";\nimport {RelationMetadata} from \"../metadata/RelationMetadata\";\n\n/**\n * Wraps entities and creates getters/setters for their relations\n * to be able to lazily load relations when accessing these relations.\n */\nexport class RelationLoader {\n\n    // -------------------------------------------------------------------------\n    // Constructor\n    // -------------------------------------------------------------------------\n\n    constructor(private connection: Connection) {\n    }\n\n    // -------------------------------------------------------------------------\n    // Public Methods\n    // -------------------------------------------------------------------------\n\n    /**\n     * Loads relation data for the given entity and its relation.\n     */\n    load(relation: RelationMetadata, entityOrEntities: ObjectLiteral|ObjectLiteral[], queryRunner?: QueryRunner): Promise<any[]> { // todo: check all places where it uses non array\n        if (queryRunner && queryRunner.isReleased) queryRunner = undefined; // get new one if already closed\n        if (relation.isManyToOne || relation.isOneToOneOwner) {\n            return this.loadManyToOneOrOneToOneOwner(relation, entityOrEntities, queryRunner);\n\n        } else if (relation.isOneToMany || relation.isOneToOneNotOwner) {\n            return this.loadOneToManyOrOneToOneNotOwner(relation, entityOrEntities, queryRunner);\n\n        } else if (relation.isManyToManyOwner) {\n            return this.loadManyToManyOwner(relation, entityOrEntities, queryRunner);\n\n        } else { // many-to-many non owner\n            return this.loadManyToManyNotOwner(relation, entityOrEntities, queryRunner);\n        }\n    }\n\n    /**\n     * Loads data for many-to-one and one-to-one owner relations.\n     *\n     * (ow) post.category<=>category.post\n     * loaded: category from post\n     * example: SELECT category.id AS category_id, category.name AS category_name FROM category category\n     *              INNER JOIN post Post ON Post.category=category.id WHERE Post.id=1\n     */\n    loadManyToOneOrOneToOneOwner(relation: RelationMetadata, entityOrEntities: ObjectLiteral|ObjectLiteral[], queryRunner?: QueryRunner): Promise<any> {\n        const entities = entityOrEntities instanceof Array ? entityOrEntities : [entityOrEntities];\n        const columns = relation.entityMetadata.primaryColumns;\n        const joinColumns = relation.isOwning ? relation.joinColumns : relation.inverseRelation!.joinColumns;\n        const conditions = joinColumns.map(joinColumn => {\n            return `${relation.entityMetadata.name}.${joinColumn.propertyName} = ${relation.propertyName}.${joinColumn.referencedColumn!.propertyName}`;\n        }).join(\" AND \");\n\n        const joinAliasName = relation.entityMetadata.name;\n        const qb = this.connection\n            .createQueryBuilder(queryRunner)\n            .select(relation.propertyName) // category\n            .from(relation.type, relation.propertyName) // Category, category\n            .innerJoin(relation.entityMetadata.target as Function, joinAliasName, conditions);\n\n        if (columns.length === 1) {\n            qb.where(`${joinAliasName}.${columns[0].propertyPath} IN (:...${joinAliasName + \"_\" + columns[0].propertyName})`);\n            qb.setParameter(joinAliasName + \"_\" + columns[0].propertyName, entities.map(entity => columns[0].getEntityValue(entity)));\n\n        } else {\n            const condition = entities.map((entity, entityIndex) => {\n                return columns.map((column, columnIndex) => {\n                    const paramName = joinAliasName + \"_entity_\" + entityIndex + \"_\" + columnIndex;\n                    qb.setParameter(paramName, column.getEntityValue(entity));\n                    return joinAliasName + \".\" + column.propertyPath + \" = :\" + paramName;\n                }).join(\" AND \");\n            }).map(condition => \"(\" + condition + \")\").join(\" OR \");\n            qb.where(condition);\n        }\n\n        return qb.getMany();\n        // return qb.getOne(); todo: fix all usages\n    }\n\n    /**\n     * Loads data for one-to-many and one-to-one not owner relations.\n     *\n     * SELECT post\n     * FROM post post\n     * WHERE post.[joinColumn.name] = entity[joinColumn.referencedColumn]\n     */\n    loadOneToManyOrOneToOneNotOwner(relation: RelationMetadata, entityOrEntities: ObjectLiteral|ObjectLiteral[], queryRunner?: QueryRunner): Promise<any> {\n        const entities = entityOrEntities instanceof Array ? entityOrEntities : [entityOrEntities];\n        const aliasName = relation.propertyName;\n        const columns = relation.inverseRelation!.joinColumns;\n        const qb = this.connection\n            .createQueryBuilder(queryRunner)\n            .select(aliasName)\n            .from(relation.inverseRelation!.entityMetadata.target, aliasName);\n\n        if (columns.length === 1) {\n            qb.where(`${aliasName}.${columns[0].propertyPath} IN (:...${aliasName + \"_\" + columns[0].propertyName})`);\n            qb.setParameter(aliasName + \"_\" + columns[0].propertyName, entities.map(entity => columns[0].referencedColumn!.getEntityValue(entity)));\n\n        } else {\n            const condition = entities.map((entity, entityIndex) => {\n                return columns.map((column, columnIndex) => {\n                    const paramName = aliasName + \"_entity_\" + entityIndex + \"_\" + columnIndex;\n                    qb.setParameter(paramName, column.referencedColumn!.getEntityValue(entity));\n                    return aliasName + \".\" + column.propertyPath + \" = :\" + paramName;\n                }).join(\" AND \");\n            }).map(condition => \"(\" + condition + \")\").join(\" OR \");\n            qb.where(condition);\n        }\n        return qb.getMany();\n        // return relation.isOneToMany ? qb.getMany() : qb.getOne(); todo: fix all usages\n    }\n\n    /**\n     * Loads data for many-to-many owner relations.\n     *\n     * SELECT category\n     * FROM category category\n     * INNER JOIN post_categories post_categories\n     * ON post_categories.postId = :postId\n     * AND post_categories.categoryId = category.id\n     */\n    loadManyToManyOwner(relation: RelationMetadata, entityOrEntities: ObjectLiteral|ObjectLiteral[], queryRunner?: QueryRunner): Promise<any> {\n        const entities = entityOrEntities instanceof Array ? entityOrEntities : [entityOrEntities];\n        const mainAlias = relation.propertyName;\n        const joinAlias = relation.junctionEntityMetadata!.tableName;\n        const joinColumnConditions = relation.joinColumns.map(joinColumn => {\n            return `${joinAlias}.${joinColumn.propertyName} IN (:...${joinColumn.propertyName})`;\n        });\n        const inverseJoinColumnConditions = relation.inverseJoinColumns.map(inverseJoinColumn => {\n            return `${joinAlias}.${inverseJoinColumn.propertyName}=${mainAlias}.${inverseJoinColumn.referencedColumn!.propertyName}`;\n        });\n        const parameters = relation.joinColumns.reduce((parameters, joinColumn) => {\n            parameters[joinColumn.propertyName] = entities.map(entity => joinColumn.referencedColumn!.getEntityValue(entity));\n            return parameters;\n        }, {} as ObjectLiteral);\n\n        return this.connection\n            .createQueryBuilder(queryRunner)\n            .select(mainAlias)\n            .from(relation.type, mainAlias)\n            .innerJoin(joinAlias, joinAlias, [...joinColumnConditions, ...inverseJoinColumnConditions].join(\" AND \"))\n            .setParameters(parameters)\n            .getMany();\n    }\n\n    /**\n     * Loads data for many-to-many not owner relations.\n     *\n     * SELECT post\n     * FROM post post\n     * INNER JOIN post_categories post_categories\n     * ON post_categories.postId = post.id\n     * AND post_categories.categoryId = post_categories.categoryId\n     */\n    loadManyToManyNotOwner(relation: RelationMetadata, entityOrEntities: ObjectLiteral|ObjectLiteral[], queryRunner?: QueryRunner): Promise<any> {\n        const entities = entityOrEntities instanceof Array ? entityOrEntities : [entityOrEntities];\n        const mainAlias = relation.propertyName;\n        const joinAlias = relation.junctionEntityMetadata!.tableName;\n        const joinColumnConditions = relation.inverseRelation!.joinColumns.map(joinColumn => {\n            return `${joinAlias}.${joinColumn.propertyName} = ${mainAlias}.${joinColumn.referencedColumn!.propertyName}`;\n        });\n        const inverseJoinColumnConditions = relation.inverseRelation!.inverseJoinColumns.map(inverseJoinColumn => {\n            return `${joinAlias}.${inverseJoinColumn.propertyName} IN (:...${inverseJoinColumn.propertyName})`;\n        });\n        const parameters = relation.inverseRelation!.inverseJoinColumns.reduce((parameters, joinColumn) => {\n            parameters[joinColumn.propertyName] = entities.map(entity => joinColumn.referencedColumn!.getEntityValue(entity));\n            return parameters;\n        }, {} as ObjectLiteral);\n\n        return this.connection\n            .createQueryBuilder(queryRunner)\n            .select(mainAlias)\n            .from(relation.type, mainAlias)\n            .innerJoin(joinAlias, joinAlias, [...joinColumnConditions, ...inverseJoinColumnConditions].join(\" AND \"))\n            .setParameters(parameters)\n            .getMany();\n    }\n\n    /**\n     * Wraps given entity and creates getters/setters for its given relation\n     * to be able to lazily load data when accessing this relation.\n     */\n    enableLazyLoad(relation: RelationMetadata, entity: ObjectLiteral, queryRunner?: QueryRunner) {\n        const relationLoader = this;\n        const dataIndex = \"__\" + relation.propertyName + \"__\"; // in what property of the entity loaded data will be stored\n        const promiseIndex = \"__promise_\" + relation.propertyName + \"__\"; // in what property of the entity loading promise will be stored\n        const resolveIndex = \"__has_\" + relation.propertyName + \"__\"; // indicates if relation data already was loaded or not, we need this flag if loaded data is empty\n\n        Object.defineProperty(entity, relation.propertyName, {\n            get: function() {\n                if (this[resolveIndex] === true || this[dataIndex]) // if related data already was loaded then simply return it\n                    return Promise.resolve(this[dataIndex]);\n\n                if (this[promiseIndex]) // if related data is loading then return a promise relationLoader loads it\n                    return this[promiseIndex];\n\n                // nothing is loaded yet, load relation data and save it in the model once they are loaded\n                this[promiseIndex] = relationLoader.load(relation, this, queryRunner).then(result => {\n                    if (relation.isOneToOne || relation.isManyToOne) result = result[0];\n                    this[dataIndex] = result;\n                    this[resolveIndex] = true;\n                    delete this[promiseIndex];\n                    return this[dataIndex];\n                });\n                return this[promiseIndex];\n            },\n            set: function(value: any|Promise<any>) {\n                if (value instanceof Promise) { // if set data is a promise then wait for its resolve and save in the object\n                    value.then(result => {\n                        this[dataIndex] = result;\n                        this[resolveIndex] = true;\n                    });\n\n                } else { // if its direct data set (non promise, probably not safe-typed)\n                    this[dataIndex] = value;\n                    this[resolveIndex] = true;\n                }\n            },\n            configurable: true\n        });\n    }\n\n}\n"],"sourceRoot":".."}