333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
{"version":3,"sources":["../browser/src/query-builder/RelationQueryBuilder.ts"],"names":[],"mappings":"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","file":"RelationQueryBuilder.js","sourcesContent":["import {QueryBuilder} from \"./QueryBuilder\";\nimport {RelationUpdater} from \"./RelationUpdater\";\nimport {RelationRemover} from \"./RelationRemover\";\n\n/**\n * Allows to work with entity relations and perform specific operations with those relations.\n *\n * todo: add transactions everywhere\n */\nexport class RelationQueryBuilder<Entity> extends QueryBuilder<Entity> {\n\n    // -------------------------------------------------------------------------\n    // Public Implemented Methods\n    // -------------------------------------------------------------------------\n\n    /**\n     * Gets generated sql query without parameters being replaced.\n     */\n    getQuery(): string {\n        return \"\";\n    }\n\n    // -------------------------------------------------------------------------\n    // Public Methods\n    // -------------------------------------------------------------------------\n\n    /**\n     * Sets entity (target) which relations will be updated.\n     */\n    of(entity: any|any[]): this {\n        this.expressionMap.of = entity;\n        return this;\n    }\n\n    /**\n     * Sets entity relation's value.\n     * Value can be entity, entity id or entity id map (if entity has composite ids).\n     * Works only for many-to-one and one-to-one relations.\n     * For many-to-many and one-to-many relations use #add and #remove methods instead.\n     */\n    async set(value: any): Promise<void> {\n        const relation = this.expressionMap.relationMetadata;\n\n        if (!this.expressionMap.of) // todo: move this check before relation query builder creation?\n            throw new Error(`Entity whose relation needs to be set is not set. Use .of method to define whose relation you want to set.`);\n\n        if (relation.isManyToMany || relation.isOneToMany)\n            throw new Error(`Set operation is only supported for many-to-one and one-to-one relations. ` +\n                `However given \"${relation.propertyPath}\" has ${relation.relationType} relation. ` +\n                `Use .add() method instead.`);\n\n        // if there are multiple join columns then user must send id map as \"value\" argument. check if he really did it\n        if (relation.joinColumns &&\n            relation.joinColumns.length > 1 &&\n            (!(value instanceof Object) || Object.keys(value).length < relation.joinColumns.length))\n            throw new Error(`Value to be set into the relation must be a map of relation ids, for example: .set({ firstName: \"...\", lastName: \"...\" })`);\n\n        const updater = new RelationUpdater(this, this.expressionMap);\n        return updater.update(value);\n    }\n\n    /**\n     * Adds (binds) given value to entity relation.\n     * Value can be entity, entity id or entity id map (if entity has composite ids).\n     * Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids).\n     * Works only for many-to-many and one-to-many relations.\n     * For many-to-one and one-to-one use #set method instead.\n     */\n    async add(value: any|any[]): Promise<void> {\n        if (value instanceof Array && value.length === 0)\n            return;\n\n        const relation = this.expressionMap.relationMetadata;\n\n        if (!this.expressionMap.of) // todo: move this check before relation query builder creation?\n            throw new Error(`Entity whose relation needs to be set is not set. Use .of method to define whose relation you want to set.`);\n\n        if (relation.isManyToOne || relation.isOneToOne)\n            throw new Error(`Add operation is only supported for many-to-many and one-to-many relations. ` +\n                `However given \"${relation.propertyPath}\" has ${relation.relationType} relation. ` +\n                `Use .set() method instead.`);\n\n        // if there are multiple join columns then user must send id map as \"value\" argument. check if he really did it\n        if (relation.joinColumns &&\n            relation.joinColumns.length > 1 &&\n            (!(value instanceof Object) || Object.keys(value).length < relation.joinColumns.length))\n            throw new Error(`Value to be set into the relation must be a map of relation ids, for example: .set({ firstName: \"...\", lastName: \"...\" })`);\n\n        const updater = new RelationUpdater(this, this.expressionMap);\n        return updater.update(value);\n    }\n\n    /**\n     * Removes (unbinds) given value from entity relation.\n     * Value can be entity, entity id or entity id map (if entity has composite ids).\n     * Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids).\n     * Works only for many-to-many and one-to-many relations.\n     * For many-to-one and one-to-one use #set method instead.\n     */\n    async remove(value: any|any[]): Promise<void> {\n        if (value instanceof Array && value.length === 0)\n            return;\n\n        const relation = this.expressionMap.relationMetadata;\n\n        if (!this.expressionMap.of) // todo: move this check before relation query builder creation?\n            throw new Error(`Entity whose relation needs to be set is not set. Use .of method to define whose relation you want to set.`);\n\n        if (relation.isManyToOne || relation.isOneToOne)\n            throw new Error(`Add operation is only supported for many-to-many and one-to-many relations. ` +\n                `However given \"${relation.propertyPath}\" has ${relation.relationType} relation. ` +\n                `Use .set(null) method instead.`);\n\n        const remover = new RelationRemover(this, this.expressionMap);\n        return remover.remove(value);\n    }\n\n    /**\n     * Adds (binds) and removes (unbinds) given values to/from entity relation.\n     * Value can be entity, entity id or entity id map (if entity has composite ids).\n     * Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids).\n     * Works only for many-to-many and one-to-many relations.\n     * For many-to-one and one-to-one use #set method instead.\n     */\n    async addAndRemove(added: any|any[], removed: any|any[]): Promise<void> {\n        await this.remove(removed);\n        await this.add(added);\n    }\n\n    /**\n     * Gets entity's relation id.\n    async getId(): Promise<any> {\n\n    }*/\n\n    /**\n     * Gets entity's relation ids.\n    async getIds(): Promise<any[]> {\n        return [];\n    }*/\n\n    /**\n     * Loads a single entity (relational) from the relation.\n     * You can also provide id of relational entity to filter by.\n     */\n    async loadOne<T = any>(): Promise<T|undefined> {\n        return this.loadMany<T>().then(results => results[0]);\n    }\n\n    /**\n     * Loads many entities (relational) from the relation.\n     * You can also provide ids of relational entities to filter by.\n     */\n    async loadMany<T = any>(): Promise<T[]> {\n        let of = this.expressionMap.of;\n        if (!(of instanceof Object)) {\n            const metadata = this.expressionMap.mainAlias!.metadata;\n            if (metadata.hasMultiplePrimaryKeys)\n                throw new Error(`Cannot load entity because only one primary key was specified, however entity contains multiple primary keys`);\n\n            of = metadata.primaryColumns[0].createValueMap(of);\n        }\n\n        return this.connection.relationLoader.load(this.expressionMap.relationMetadata, of);\n    }\n\n}"],"sourceRoot":".."}