Skip to content

Commit

Permalink
fix(core): process upsert data to allow using entity instances in pla…
Browse files Browse the repository at this point in the history
…ce of relations

Closes #5165
  • Loading branch information
B4nan committed Feb 2, 2024
1 parent 35d607c commit 9305653
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 4 deletions.
8 changes: 4 additions & 4 deletions packages/core/src/EntityManager.ts
Expand Up @@ -872,14 +872,14 @@ export class EntityManager<Driver extends IDatabaseDriver = IDatabaseDriver> {
where = helper(entity).getPrimaryKey() as FilterQuery<Entity>;
data = em.comparator.prepareEntity(entity);
} else {
data = Utils.copy(data);
data = Utils.copy(QueryHelper.processParams(data));
where = Utils.extractPK(data, meta) as FilterQuery<Entity>;

if (where) {
const exists = em.unitOfWork.getById<Entity>(entityName, where as Primary<Entity>, options.schema);

if (exists) {
return em.assign(exists, data) as any;
return em.assign(exists, data as any) as any;
}
}
}
Expand Down Expand Up @@ -1033,14 +1033,14 @@ export class EntityManager<Driver extends IDatabaseDriver = IDatabaseDriver> {
where = helper(entity).getPrimaryKey() as FilterQuery<Entity>;
row = em.comparator.prepareEntity(entity);
} else {
row = data[i] = Utils.copy(row);
row = data[i] = Utils.copy(QueryHelper.processParams(row));
where = Utils.extractPK(row, meta) as FilterQuery<Entity>;

if (where) {
const exists = em.unitOfWork.getById<Entity>(entityName, where as Primary<Entity>, options.schema);

if (exists) {
em.assign(exists, row);
em.assign(exists, row as any);
entities.set(exists, row);
entitiesByData.set(row, exists);
continue;
Expand Down
143 changes: 143 additions & 0 deletions tests/features/upsert/GH5165.test.ts
@@ -0,0 +1,143 @@
import {
Entity,
ManyToOne,
OneToOne,
PrimaryKey,
Property,
Ref,
Unique,
MikroORM,
OneToMany,
Collection,
} from '@mikro-orm/sqlite';

@Entity({ tableName: 'servers_clients_tags' })
@Unique({
properties: ['purchase', 'name'],
})
class Note {

@PrimaryKey()
readonly id?: number;

@ManyToOne(() => Purchases, {
nullable: false,
})
purchase?: Ref<Purchases>;

@Property({ length: 100 })
name!: string;

@Property({ length: 2000 })
value!: string;

}

@Entity()
class Purchases {

@PrimaryKey()
readonly id?: number;

@ManyToOne({ entity: () => Account, ref: true })
account?: Ref<Account>;

@OneToMany(() => Note, x => x.purchase)
notes = new Collection<Note>(this);

}

@Entity()
class Account {

@PrimaryKey()
readonly id?: number;

@OneToOne(() => Address, billingDetail => billingDetail.account, {
ref: true,
nullable: true,
})
address?: Ref<Address>;

@OneToMany(() => Purchases, x => x.account)
serverClients = new Collection<Purchases>(this);

}

@Entity()
class Address {

@PrimaryKey()
readonly id?: number;

@Property({ length: 100 })
company!: string;

@OneToOne({
entity: () => Account,
unique: 'billing_details_account_id_key',
owner: true,
ref: true,
})
account!: Ref<Account>;

}

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
entities: [Note, Purchases, Account, Address],
dbName: ':memory:',
loadStrategy: 'select-in',
});
await orm.schema.refreshDatabase();
const billingDetail = orm.em.create(Address, {
company: 'testBillingDetail',
account: orm.em.create(Account, {}),
});

const serverClient = orm.em.create(Purchases, {
account: billingDetail.account,
});

orm.em.create(Note, {
purchase: serverClient,
name: 'testKey',
value: 'testValue',
});
await orm.em.flush();
});

afterAll(async () => {
await orm.close(true);
});

test(`GH issue 5165 upsert one`, async () => {
const purchase = await orm.em.findOneOrFail(Purchases, { id: 1 }, {
populate: ['notes'],
});
await orm.em.upsert(Note, {
purchase,
name: 'testKey',
value: 'newTestValue',
});
});

test(`GH issue 5165 upsert many`, async () => {
const purchase = await orm.em.findOneOrFail(Purchases, { id: 1 }, {
populate: ['notes'],
});
await orm.em.upsertMany(Note, [
{
purchase,
name: 'testKey',
value: 'newTestValue',
},
{
purchase,
name: 'testKey2',
value: 'newTestValue2',
},
]);
});

0 comments on commit 9305653

Please sign in to comment.