diff --git a/src/entity-manager/EntityManager.ts b/src/entity-manager/EntityManager.ts index 213dfe915d..2168d3f4dc 100644 --- a/src/entity-manager/EntityManager.ts +++ b/src/entity-manager/EntityManager.ts @@ -700,7 +700,9 @@ export class EntityManager { } const conflictColumns = metadata.mapPropertyPathsToColumns( - options.conflictPaths, + Array.isArray(options.conflictPaths) + ? options.conflictPaths + : Object.keys(options.conflictPaths), ) const overwriteColumns = metadata.columns.filter( diff --git a/src/repository/UpsertOptions.ts b/src/repository/UpsertOptions.ts index 6f138eb18a..4e7a7f8825 100644 --- a/src/repository/UpsertOptions.ts +++ b/src/repository/UpsertOptions.ts @@ -3,7 +3,7 @@ */ // eslint-disable-next-line @typescript-eslint/no-unused-vars export interface UpsertOptions { - conflictPaths: string[] + conflictPaths: string[] | { [P in keyof Entity]?: true } /** * If true, postgres will skip the update if no values would be changed (reduces writes) */ diff --git a/test/github-issues/9412/entity/Post.ts b/test/github-issues/9412/entity/Post.ts new file mode 100644 index 0000000000..edad7e2301 --- /dev/null +++ b/test/github-issues/9412/entity/Post.ts @@ -0,0 +1,15 @@ +import { Entity } from "../../../../src/decorator/entity/Entity" +import { PrimaryGeneratedColumn } from "../../../../src/decorator/columns/PrimaryGeneratedColumn" +import { Column } from "../../../../src/decorator/columns/Column" + +@Entity() +export class Post { + @PrimaryGeneratedColumn() + id: number + + @Column({unique: true}) + title: string + + @Column({unique: true}) + author: string +} diff --git a/test/github-issues/9412/issue-9412.ts b/test/github-issues/9412/issue-9412.ts new file mode 100644 index 0000000000..441da4730e --- /dev/null +++ b/test/github-issues/9412/issue-9412.ts @@ -0,0 +1,46 @@ +import 'reflect-metadata' +import { + closeTestingConnections, + createTestingConnections, + reloadTestingDatabases, +} from '../../utils/test-utils' +import { DataSource } from '../../../src/data-source/DataSource' +import { Post } from './entity/Post' +import { expect } from 'chai' + +describe('github issues > #9365 ', () => { + let connections: DataSource[] + before( + async () => + (connections = await createTestingConnections({ + entities: [ __dirname + '/entity/*{.js,.ts}' ], + enabledDrivers: [ 'postgres' ], + })), + ) + beforeEach(() => reloadTestingDatabases(connections)) + after(() => closeTestingConnections(connections)) + + it('should work with conflict path', () => + Promise.all( + connections.map(async (connection) => { + const postRepository = connection.getRepository(Post) + + const post1 = new Post() + post1.title = 'Test1' + post1.author = 'Test1' + await postRepository.save(post1) + + const post2 = new Post() + post2.title = 'Test' + post2.author = 'Test2' + + await postRepository.upsert(post2, { conflictPaths: { author: true }, skipUpdateIfNoValuesChanged: true }) + const allPostsAfterUpsert1= await postRepository.find() + expect(allPostsAfterUpsert1.length).equal(2) + + await postRepository.upsert(post2, { conflictPaths: { title: true }, skipUpdateIfNoValuesChanged: true }) + const allPostsAfterUpsert2= await postRepository.find() + expect(allPostsAfterUpsert2.length).equal(2) + }), + )) +})