UNPKG

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.

153 lines (119 loc) 3.37 kB
import { MikroORM } from '@mikro-orm/better-sqlite'; import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property, Ref, ref, LoadStrategy } from '@mikro-orm/core'; @Entity() class Author { @PrimaryKey() id!: number; @Property() name: string; @Property({ unique: true }) email: string; @OneToMany({ entity: () => Publisher, mappedBy: p => p.bestSellingAuthor, eager: true, }) publishers = new Collection<Publisher>(this); @OneToMany({ entity: () => Book, mappedBy: b => b.author, }) books = new Collection<Book>(this); constructor(name: string, email: string) { this.name = name; this.email = email; } } @Entity() class Book { @PrimaryKey() id!: number; @Property() title: string; @ManyToOne({ entity: () => Author, ref: true, eager: true }) author: Ref<Author>; @ManyToOne(() => Publisher, { ref: true, nullable: true }) publisher?: Ref<Publisher>; constructor({ author, publisher, title }: { author: Author; publisher: Publisher; title: string; }) { this.author = ref(author); this.publisher = ref(publisher); this.title = title; } } @Entity() class Publisher { @PrimaryKey() id!: number; @Property() name: string; @Property() country!: string; @ManyToOne({ entity: () => Author, ref: true }) bestSellingAuthor: Ref<Author>; @OneToMany({ entity: () => Book, mappedBy: a => a.publisher, eager: true, }) books = new Collection<Book>(this); constructor(name: string, bestSellingAuthor: Author) { this.name = name; this.bestSellingAuthor = ref(bestSellingAuthor); } } async function seed(orm: MikroORM) { const em = orm.em.fork(); const author = em.create(Author, { name: `God`, email: `god@heaven.com`, }); const publisher = em.create(Publisher, { name: `pub`, country: 'neverland', bestSellingAuthor: author, }); for (let i = 0; i < 50; i += 1) { em.persist( new Book({ author, publisher, title: `Bible pt.${i}`, }), ); } await em.flush(); em.clear(); } let orm: MikroORM; beforeAll(async () => { orm = await MikroORM.init({ entities: [Author], dbName: ':memory:', }); await orm.schema.createSchema(); await seed(orm); }); beforeEach(() => orm.em.clear()); afterAll(() => orm.close(true)); // should run around 15ms when run separately (M1 Pro 32g) test('perf: eager loading with cycles (select-in)', async () => { console.time('perf: eager loading with cycles'); const res = await orm.em.find(Book, {}, { strategy: LoadStrategy.SELECT_IN }); console.timeEnd('perf: eager loading with cycles'); expect(res).toHaveLength(50); expect(res[0].author.unwrap().publishers[0].books[0].title).toBe('Bible pt.0'); expect(res[0]).toBe(res[0].author.unwrap().publishers[0].books[0]); }); // should run around 15ms when run separately (M1 Pro 32g) test('perf: eager loading with cycles (joined)', async () => { console.time('perf: eager loading with cycles'); const res = await orm.em.find(Book, {}, { strategy: LoadStrategy.JOINED }); console.timeEnd('perf: eager loading with cycles'); expect(res).toHaveLength(50); expect(res[0].author.unwrap().publishers[0].books[0].title).toBe('Bible pt.0'); expect(res[0]).toBe(res[0].author.unwrap().publishers[0].books[0]); });