undeexcepturi
Version:
TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.
116 lines (83 loc) • 2.9 kB
text/typescript
import type { Platform } from '@mikro-orm/sqlite';
import { Cascade, Collection, Entity, ManyToOne, MikroORM, OneToMany, PrimaryKey, Property, Type } from '@mikro-orm/sqlite';
import { mockLogger } from '../helpers';
export class Sku {
private constructor(private readonly value: string) {}
static create(value: string): Sku {
return new Sku(value);
}
toString(): string {
return this.value;
}
}
export class SkuType extends Type<Sku, string> {
override convertToDatabaseValue(value: Sku | string, platform: Platform): string {
return value.toString();
}
override convertToJSValue(value: Sku | string, platform: Platform): Sku {
if (value instanceof Sku) {
return value;
}
return Sku.create(value);
}
}
()
export class Cart {
()
readonly id: string;
({ entity: 'CartItem', mappedBy: 'cart', cascade: [Cascade.MERGE, Cascade.PERSIST] })
readonly items = new Collection<CartItem>(this);
constructor(id: string, items: CartItem[]) {
this.id = id;
this.items.add(items);
}
addItem(item: CartItem): void {
this.items.add(item);
}
removeItem(item: CartItem): void {
this.items.remove(item);
}
}
()
export class CartItem {
({ primary: true, entity: 'Cart' })
readonly cart!: Cart;
({ type: SkuType })
readonly sku: Sku;
()
quantity: number;
constructor(sku: Sku, quantity: number) {
this.sku = sku;
this.quantity = quantity;
}
updateQuantity(quantity: number) {
this.quantity = quantity;
}
}
describe('GH issue 910', () => {
test(`composite keys with custom type PK that uses object value`, async () => {
const orm = await MikroORM.init({
entities: [Cart, CartItem],
dbName: ':memory:',
});
await orm.schema.createSchema();
const mock = mockLogger(orm, ['query', 'query-params']);
const id = '123';
const item1 = new CartItem(Sku.create('sku1'), 10);
const item2 = new CartItem(Sku.create('sku2'), 10);
const cart = new Cart(id, [item1, item2]);
await orm.em.persistAndFlush(cart);
const item3 = new CartItem(Sku.create('sku3'), 100);
await orm.em.flush();
item2.updateQuantity(33);
await orm.em.flush();
expect(mock.mock.calls[0][0]).toMatch('begin');
expect(mock.mock.calls[1][0]).toMatch('insert into `cart` (`id`) values (\'123\')');
expect(mock.mock.calls[2][0]).toMatch('insert into `cart_item` (`cart_id`, `sku`, `quantity`) values (\'123\', \'sku1\', 10), (\'123\', \'sku2\', 10)');
expect(mock.mock.calls[3][0]).toMatch('commit');
expect(mock.mock.calls[4][0]).toMatch('begin');
expect(mock.mock.calls[5][0]).toMatch('update `cart_item` set `quantity` = 33 where `cart_id` = \'123\' and `sku` = \'sku2\'');
expect(mock.mock.calls[6][0]).toMatch('commit');
await orm.close();
});
});