Skip to content

Commit

Permalink
fix(core): ensure custom types are processed in `em.upsert/upsertMany…
Browse files Browse the repository at this point in the history
…/insertMany`

Closes #4070
  • Loading branch information
B4nan committed Feb 26, 2023
1 parent a37415f commit 53a08ac
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 5 deletions.
6 changes: 4 additions & 2 deletions packages/core/src/EntityManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ export class EntityManager<D extends IDatabaseDriver = IDatabaseDriver> {
}

const meta = this.metadata.get(entityName);
const convertCustomTypes = !Utils.isEntity(data);

if (Utils.isEntity(data)) {
entity = data as Entity;
Expand Down Expand Up @@ -614,7 +615,7 @@ export class EntityManager<D extends IDatabaseDriver = IDatabaseDriver> {
const ret = await em.driver.nativeUpdate(entityName, where, data, {
ctx: em.transactionContext,
upsert: true,
convertCustomTypes: false,
convertCustomTypes,
...options,
});

Expand Down Expand Up @@ -682,6 +683,7 @@ export class EntityManager<D extends IDatabaseDriver = IDatabaseDriver> {
}

const meta = this.metadata.get(entityName);
const convertCustomTypes = !Utils.isEntity(data[0]);
const allData: EntityData<Entity>[] = [];
const allWhere: FilterQuery<Entity>[] = [];
const entities = new Map<Entity, EntityData<Entity>>();
Expand Down Expand Up @@ -752,7 +754,7 @@ export class EntityManager<D extends IDatabaseDriver = IDatabaseDriver> {
const ret = await em.driver.nativeUpdateMany(entityName, allWhere, allData, {
ctx: em.transactionContext,
upsert: true,
convertCustomTypes: false,
convertCustomTypes,
...options,
});

Expand Down
12 changes: 10 additions & 2 deletions packages/knex/src/AbstractSqlDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,14 @@ export abstract class AbstractSqlDriver<Connection extends AbstractSqlConnection
sql += ' ' + data.map(() => `select null as ${this.platform.quoteIdentifier(pks[0])}`).join(' union all ');
}

const addParams = (prop: EntityProperty<T>, row: Dictionary) => {
if (options.convertCustomTypes && prop.customType) {
return params.push(prop.customType.convertToDatabaseValue(row[prop.name], this.platform, { key: prop.name, mode: 'query' }));
}

params.push(row[prop.name]);
};

if (fields.length > 0 || this.platform.usesDefaultKeyword()) {
sql += data.map(row => {
const keys: string[] = [];
Expand All @@ -343,9 +351,9 @@ export abstract class AbstractSqlDriver<Connection extends AbstractSqlConnection
keys.push(...(row[prop.name] as unknown[] ?? prop.fieldNames).map(() => '?'));
} else if (prop.customType && 'convertToDatabaseValueSQL' in prop.customType && !this.platform.isRaw(row[prop.name])) {
keys.push(prop.customType.convertToDatabaseValueSQL!('?', this.platform));
params.push(row[prop.name]);
addParams(prop, row);
} else {
params.push(row[prop.name]);
addParams(prop, row);
keys.push('?');
}
});
Expand Down
1 change: 0 additions & 1 deletion tests/issues/GH4062.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ beforeAll(async () => {
entities: [Category],
dbName: `mikro_orm_4062`,
port: 3308,
debug: true,
});

await orm.schema.refreshDatabase();
Expand Down
104 changes: 104 additions & 0 deletions tests/issues/GH4070.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { Entity, PrimaryKey, Property } from '@mikro-orm/core';
import { MikroORM } from '@mikro-orm/sqlite';

@Entity()
class MyEntity {

@PrimaryKey()
id?: number;

@Property({ type: 'json' })
postIds!: number[];

}

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
entities: [MyEntity],
dbName: `:memory:`,
});
await orm.schema.refreshDatabase();
});

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

beforeEach(async () => {
await orm.schema.clearDatabase();
});

test('insertMany array of numbers to JSON', async () => {
await orm.em.insertMany(MyEntity, [
{
id: 1,
postIds: [10, 11, 12],
},
{
id: 2,
postIds: [20, 21],
},
]);
});

test('insertMany entities array of numbers to JSON', async () => {
await orm.em.insertMany([
orm.em.create(MyEntity, {
id: 1,
postIds: [10, 11, 12],
}),
orm.em.create(MyEntity, {
id: 2,
postIds: [20, 21],
}),
]);
});

test('upsertMany array of numbers to JSON', async () => {
await orm.em.upsertMany(MyEntity, [
{
id: 1,
postIds: [10, 11, 12],
},
{
id: 2,
postIds: [20, 21],
},
]);
});

test('upsert array of numbers to JSON', async () => {
await orm.em.upsert(MyEntity, {
id: 1,
postIds: [10, 11, 12],
});
});

test('insert array of numbers to JSON', async () => {
await orm.em.insert(MyEntity, {
id: 1,
postIds: [10, 11, 12],
});
});

test('flush one array of numbers to JSON', async () => {
orm.em.create(MyEntity, {
id: 1,
postIds: [10, 11, 12],
});
await orm.em.flush();
});

test('flush many array of numbers to JSON', async () => {
orm.em.create(MyEntity, {
id: 1,
postIds: [10, 11, 12],
});
orm.em.create(MyEntity, {
id: 2,
postIds: [20, 21],
});
await orm.em.flush();
});

0 comments on commit 53a08ac

Please sign in to comment.