333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
{"version":3,"sources":["../../src/query-builder/ReturningResultsEntityUpdator.ts"],"names":[],"mappings":";;;AAEA,6CAA0C;AAK1C,8DAA2D;AAE3D;;GAEG;AACH;IAEI,4EAA4E;IAC5E,cAAc;IACd,4EAA4E;IAE5E,uCAAsB,WAAwB,EACxB,aAAiC;QADjC,gBAAW,GAAX,WAAW,CAAa;QACxB,kBAAa,GAAb,aAAa,CAAoB;IACvD,CAAC;IAED,4EAA4E;IAC5E,iBAAiB;IACjB,4EAA4E;IAE5E;;OAEG;IACG,8CAAM,GAAZ,UAAa,YAA0B,EAAE,QAAyB;;;;;;;wBACxD,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,SAAU,CAAC,QAAQ,CAAC;wBAExD,qBAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAO,MAAM,EAAE,WAAW;;;;;;iDAGjD,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,uBAAuB,EAAE,EAA5D,wBAA4D;4CAC5D,IAAI,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,YAAY,2BAAY,IAAI,YAAY,CAAC,GAAG,YAAY,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE;gDACxJ,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,UAAC,MAAM,EAAE,OAAO,EAAE,YAAY;oDACrE,MAAM,CAAC,KAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;oDACzF,OAAO,MAAM,CAAC;gDAClB,CAAC,EAAE,EAAmB,CAAC,CAAC;6CAC3B;4CACK,MAAM,GAAG,YAAY,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;4CAC9F,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;4CACjG,IAAI,gBAAgB,EAAE;gDAClB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAa,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;gDACjF,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;6CACrD;;;4CAKK,eAAe,GAAG,IAAI,CAAC,2BAA2B,EAAE,CAAC;iDACvD,CAAA,eAAe,CAAC,MAAM,GAAG,CAAC,CAAA,EAA1B,wBAA0B;4CAGpB,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,SAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;4CAC/E,IAAI,CAAC,QAAQ;gDACT,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;4CAGzD,qBAAM,IAAI,CAAC,WAAW,CAAC,OAAO;qDACxD,kBAAkB,EAAE;qDACpB,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,QAAQ,CAAC,UAAU,GAAG,GAAG,GAAG,MAAM,CAAC,YAAY,EAA/C,CAA+C,CAAC,CAAC;qDAC9F,SAAS,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,QAAQ,CAAC,UAAU,GAAG,GAAG,GAAG,MAAM,CAAC,YAAY,EAA/C,CAA+C,CAAC,CAAC;qDAC5G,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC;qDAC1C,KAAK,CAAC,QAAQ,CAAC;qDACf,SAAS,CAAC,aAAa,CAAC,CAAC,8IAA8I;qDACvK,MAAM,EAAE,EAAA;;4CAPP,sBAAsB,GAAG,SAOlB;4CAEb,IAAI,sBAAsB,EAAE;gDACxB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAa,EAAE,MAAM,EAAE,sBAAsB,CAAC,CAAC;gDACvF,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;6CAC3D;;;;;iCAGZ,CAAC,CAAC,EAAA;;wBA5CH,SA4CG,CAAC;;;;;KACP;IAED;;OAEG;IACG,8CAAM,GAAZ,UAAa,YAA0B,EAAE,QAAyB;;;;;;;wBACxD,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,SAAU,CAAC,QAAQ,CAAC;wBAClD,gBAAgB,GAAG,IAAI,CAAC,4BAA4B,EAAE,CAAC;wBAEvD,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAC,MAAM,EAAE,WAAW;4BACnD,IAAI,KAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,YAAY,2BAAY,IAAI,YAAY,CAAC,GAAG,YAAY,KAAK,IAAI,KAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE;gCACxJ,YAAY,CAAC,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,UAAC,MAAM,EAAE,OAAO,EAAE,YAAY;oCACrE,MAAM,CAAC,KAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;oCACzF,OAAO,MAAM,CAAC;gCAClB,CAAC,EAAE,EAAmB,CAAC,CAAC;6BAC3B;4BACD,gDAAgD;4BAChD,IAAM,MAAM,GAAG,YAAY,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;4BACpG,IAAM,YAAY,GAAG,KAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;4BAEnG,0EAA0E;4BAC1E,oDAAoD;4BACpD,IAAI,KAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,yBAAyB,EAAE,KAAK,KAAK,EAAE;gCAC1E,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAA,eAAe;oCAC7C,IAAI,eAAe,CAAC,kBAAkB,KAAK,MAAM,EAAE;wCAC/C,qEAAqE;wCACrE,IAAI,IAAI,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;wCAClD,IAAI,CAAC,IAAI,EAAE,iHAAiH;4CACxH,IAAI,GAAG,KAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,OAAO,GAAG,eAAe,CAAC,YAAY,GAAG,WAAW,CAAC,CAAC;wCAErG,mBAAQ,CAAC,SAAS,CAAC,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;qCAC1E;gCACL,CAAC,CAAC,CAAC;6BACN;4BAED,KAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,6DAA6D;4BAC3I,OAAO,YAAY,CAAC;wBACxB,CAAC,CAAC,CAAC;6BAIC,CAAA,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,uBAAuB,EAAE,KAAK,KAAK,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAA,EAArG,wBAAqG;wBACrG,qBAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAO,MAAM,EAAE,WAAW;;;;;4CAC/C,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAE,CAAC;4CAQrB,qBAAM,IAAI,CAAC,WAAW,CAAC,OAAO;qDACtD,kBAAkB,EAAE;qDACpB,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,QAAQ,CAAC,UAAU,GAAG,GAAG,GAAG,MAAM,CAAC,YAAY,EAA/C,CAA+C,CAAC,CAAC;qDAC9F,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,QAAQ,CAAC,UAAU,GAAG,GAAG,GAAG,MAAM,CAAC,YAAY,EAA/C,CAA+C,CAAC,CAAC;qDAC1F,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC;qDAC1C,KAAK,CAAC,QAAQ,CAAC;qDACf,SAAS,CAAC,aAAa,CAAC,CAAC,8IAA8I;qDACvK,MAAM,EAAE,EAAA;;4CAPP,eAAe,GAAQ,SAOhB;4CAEb,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAa,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,eAAe,CAAC,CAAC;;;;iCACvG,CAAC,CAAC,EAAA;;wBAnBH,SAmBG,CAAC;;;wBAGR,QAAQ,CAAC,OAAO,CAAC,UAAC,MAAM,EAAE,WAAW;4BACjC,IAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAE,CAAC;4BAClD,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;4BACxC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;4BAC5D,KAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAI,CAAC,aAAa,CAAC,SAAU,CAAC,QAAQ,CAAC,MAAa,EAAE,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,oBAAoB;wBAC9K,CAAC,CAAC,CAAC;;;;;KACN;IAED;;OAEG;IACH,oEAA4B,GAA5B;QAEI,0FAA0F;QAC1F,+FAA+F;QAC/F,IAAM,oBAAoB,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,uBAAuB,EAAE,CAAC;QAE1F,wFAAwF;QACxF,OAAO,IAAI,CAAC,aAAa,CAAC,SAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAA,MAAM;YAC/D,OAAQ,MAAM,CAAC,OAAO,KAAK,SAAS;gBAC5B,CAAC,oBAAoB,IAAI,MAAM,CAAC,WAAW,CAAC;gBAC5C,MAAM,CAAC,YAAY;gBACnB,MAAM,CAAC,YAAY;gBACnB,MAAM,CAAC,SAAS,CAAC;QAC7B,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,mEAA2B,GAA3B;QACI,OAAO,IAAI,CAAC,aAAa,CAAC,SAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAA,MAAM;YAC/D,OAAO,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC;QACnD,CAAC,CAAC,CAAC;IACP,CAAC;IAEL,oCAAC;AAAD,CArKA,AAqKC,IAAA;AArKY,sEAA6B","file":"ReturningResultsEntityUpdator.js","sourcesContent":["import {ObjectLiteral} from \"../common/ObjectLiteral\";\nimport {QueryRunner} from \"../query-runner/QueryRunner\";\nimport {OrmUtils} from \"../util/OrmUtils\";\nimport {QueryExpressionMap} from \"./QueryExpressionMap\";\nimport {ColumnMetadata} from \"../metadata/ColumnMetadata\";\nimport {UpdateResult} from \"./result/UpdateResult\";\nimport {InsertResult} from \"./result/InsertResult\";\nimport {OracleDriver} from \"../driver/oracle/OracleDriver\";\n\n/**\n * Updates entity with returning results in the entity insert and update operations.\n */\nexport class ReturningResultsEntityUpdator {\n\n    // -------------------------------------------------------------------------\n    // Constructor\n    // -------------------------------------------------------------------------\n\n    constructor(protected queryRunner: QueryRunner,\n                protected expressionMap: QueryExpressionMap) {\n    }\n\n    // -------------------------------------------------------------------------\n    // Public Methods\n    // -------------------------------------------------------------------------\n\n    /**\n     * Updates entities with a special columns after updation query execution.\n     */\n    async update(updateResult: UpdateResult, entities: ObjectLiteral[]): Promise<void> {\n        const metadata = this.expressionMap.mainAlias!.metadata;\n\n        await Promise.all(entities.map(async (entity, entityIndex) => {\n\n            // if database supports returning/output statement then we already should have updating values in the raw data returned by insert query\n            if (this.queryRunner.connection.driver.isReturningSqlSupported()) {\n                if (this.queryRunner.connection.driver instanceof OracleDriver && updateResult.raw instanceof Array && this.expressionMap.extraReturningColumns.length > 0) {\n                    updateResult.raw = updateResult.raw.reduce((newRaw, rawItem, rawItemIndex) => {\n                        newRaw[this.expressionMap.extraReturningColumns[rawItemIndex].databaseName] = rawItem[0];\n                        return newRaw;\n                    }, {} as ObjectLiteral);\n                }\n                const result = updateResult.raw instanceof Array ? updateResult.raw[entityIndex] : updateResult.raw;\n                const returningColumns = this.queryRunner.connection.driver.createGeneratedMap(metadata, result);\n                if (returningColumns) {\n                    this.queryRunner.manager.merge(metadata.target as any, entity, returningColumns);\n                    updateResult.generatedMaps.push(returningColumns);\n                }\n\n            } else {\n\n                // for driver which do not support returning/output statement we need to perform separate query and load what we need\n                const updationColumns = this.getUpdationReturningColumns();\n                if (updationColumns.length > 0) {\n\n                    // get entity id by which we will get needed data\n                    const entityId = this.expressionMap.mainAlias!.metadata.getEntityIdMap(entity);\n                    if (!entityId)\n                        throw new Error(`Cannot update entity because entity id is not set in the entity.`);\n\n                    // execute query to get needed data\n                    const loadedReturningColumns = await this.queryRunner.manager\n                        .createQueryBuilder()\n                        .select(metadata.primaryColumns.map(column => metadata.targetName + \".\" + column.propertyPath))\n                        .addSelect(this.getUpdationReturningColumns().map(column => metadata.targetName + \".\" + column.propertyPath))\n                        .from(metadata.target, metadata.targetName)\n                        .where(entityId)\n                        .setOption(\"create-pojo\") // use POJO because created object can contain default values, e.g. property = null and those properties maight be overridden by merge process\n                        .getOne();\n\n                    if (loadedReturningColumns) {\n                        this.queryRunner.manager.merge(metadata.target as any, entity, loadedReturningColumns);\n                        updateResult.generatedMaps.push(loadedReturningColumns);\n                    }\n                }\n            }\n        }));\n    }\n\n    /**\n     * Updates entities with a special columns after insertion query execution.\n     */\n    async insert(insertResult: InsertResult, entities: ObjectLiteral[]): Promise<void> {\n        const metadata = this.expressionMap.mainAlias!.metadata;\n        const insertionColumns = this.getInsertionReturningColumns();\n\n        const generatedMaps = entities.map((entity, entityIndex) => {\n            if (this.queryRunner.connection.driver instanceof OracleDriver && insertResult.raw instanceof Array && this.expressionMap.extraReturningColumns.length > 0) {\n                insertResult.raw = insertResult.raw.reduce((newRaw, rawItem, rawItemIndex) => {\n                    newRaw[this.expressionMap.extraReturningColumns[rawItemIndex].databaseName] = rawItem[0];\n                    return newRaw;\n                }, {} as ObjectLiteral);\n            }\n            // get all values generated by a database for us\n            const result = insertResult.raw instanceof Array ? insertResult.raw[entityIndex] : insertResult.raw;\n            const generatedMap = this.queryRunner.connection.driver.createGeneratedMap(metadata, result) || {};\n\n            // if database does not support uuid generation we need to get uuid values\n            // generated by orm and set them to the generatedMap\n            if (this.queryRunner.connection.driver.isUUIDGenerationSupported() === false) {\n                metadata.generatedColumns.forEach(generatedColumn => {\n                    if (generatedColumn.generationStrategy === \"uuid\") {\n                        // uuid can be defined by user in a model, that's why first we get it\n                        let uuid = generatedColumn.getEntityValue(entity);\n                        if (!uuid) // if it was not defined by a user then InsertQueryBuilder generates it by its own, get this generated uuid value\n                            uuid = this.expressionMap.nativeParameters[\"uuid_\" + generatedColumn.databaseName + entityIndex];\n\n                        OrmUtils.mergeDeep(generatedMap, generatedColumn.createValueMap(uuid));\n                    }\n                });\n            }\n\n            this.queryRunner.manager.merge(metadata.target as any, entity, generatedMap); // todo: this should not be here, but problem with below line\n            return generatedMap;\n        });\n\n        // for postgres and mssql we use returning/output statement to get values of inserted default and generated values\n        // for other drivers we have to re-select this data from the database\n        if (this.queryRunner.connection.driver.isReturningSqlSupported() === false && insertionColumns.length > 0) {\n            await Promise.all(entities.map(async (entity, entityIndex) => {\n                const entityId = metadata.getEntityIdMap(entity)!;\n\n                // to select just inserted entity we need a criteria to select by.\n                // for newly inserted entities in drivers which do not support returning statement\n                // row identifier can only be an increment column\n                // (since its the only thing that can be generated by those databases)\n                // or (and) other primary key which is defined by a user and inserted value has it\n\n                const returningResult: any = await this.queryRunner.manager\n                    .createQueryBuilder()\n                    .select(metadata.primaryColumns.map(column => metadata.targetName + \".\" + column.propertyPath))\n                    .addSelect(insertionColumns.map(column => metadata.targetName + \".\" + column.propertyPath))\n                    .from(metadata.target, metadata.targetName)\n                    .where(entityId)\n                    .setOption(\"create-pojo\") // use POJO because created object can contain default values, e.g. property = null and those properties maight be overridden by merge process\n                    .getOne();\n\n                this.queryRunner.manager.merge(metadata.target as any, generatedMaps[entityIndex], returningResult);\n            }));\n        }\n\n        entities.forEach((entity, entityIndex) => {\n            const entityId = metadata.getEntityIdMap(entity)!;\n            insertResult.identifiers.push(entityId);\n            insertResult.generatedMaps.push(generatedMaps[entityIndex]);\n            this.queryRunner.manager.merge(this.expressionMap.mainAlias!.metadata.target as any, entity, generatedMaps[entityIndex], generatedMaps[entityIndex]); // todo: why twice?!\n        });\n    }\n\n    /**\n     * Columns we need to be returned from the database when we insert entity.\n     */\n    getInsertionReturningColumns(): ColumnMetadata[] {\n\n        // for databases which support returning statement we need to return extra columns like id\n        // for other databases we don't need to return id column since its returned by a driver already\n        const needToCheckGenerated = this.queryRunner.connection.driver.isReturningSqlSupported();\n\n        // filter out the columns of which we need database inserted values to update our entity\n        return this.expressionMap.mainAlias!.metadata.columns.filter(column => {\n            return  column.default !== undefined ||\n                    (needToCheckGenerated && column.isGenerated)  ||\n                    column.isCreateDate ||\n                    column.isUpdateDate ||\n                    column.isVersion;\n        });\n    }\n\n    /**\n     * Columns we need to be returned from the database when we update entity.\n     */\n    getUpdationReturningColumns(): ColumnMetadata[] {\n        return this.expressionMap.mainAlias!.metadata.columns.filter(column => {\n            return column.isUpdateDate || column.isVersion;\n        });\n    }\n\n}\n"],"sourceRoot":".."}