To end the core module, let's allow for the insertion of a bunch of fictional data to see the database populated.
Seeding is about loading the database with mocked entities and relations between them to test the system's functionalities.
TypeORM currently has no support for seeding, so we can write a route for doing such. For organization, let's create a very simple seeding resource inside the database structure. Choose no for CRUD entry points.
nestgresdatabase/seeding
In the controller, insert the route responsible for seeding.
@Post()seed() {returnthis.seedingService.seed();}
In the service, we need to perform several database operations and all of them need to be successful. In case any one fails, all of the already performed operations need to be reverted back in order to avoid inconsistencies. This means that we need to use a transaction.
To do so, first we need to inject in the service a DataSource.
Now we can use the seed itself. The following steps occur
First, repositories are obtained from the queryRunner. Only these repositories are able to rollback in case of a failed operation.
After that, the database tables are cleared. Note that some of them are not cleared directly because their records will be deleted due to cascade.
Finally, the entities and their relationships are created and saved in the database.
constusersRepository=queryRunner.manager.getRepository(User);constcategoriesRepository=queryRunner.manager.getRepository(Category);constproductsRepository=queryRunner.manager.getRepository(Product);constordersRepository=queryRunner.manager.getRepository(Order);constorderItemsRepository=queryRunner.manager.getRepository(OrderItem);constpaymentsRepository=queryRunner.manager.getRepository(Payment);constorders=awaitordersRepository.find();awaitordersRepository.remove(orders);constusers=awaitusersRepository.find();awaitusersRepository.remove(users);constproducts=awaitproductsRepository.find();awaitproductsRepository.remove(products);constcategories=awaitcategoriesRepository.find();awaitcategoriesRepository.remove(categories);constcat1=categoriesRepository.create({ name:'Electronics' });constcat2=categoriesRepository.create({ name:'Books' });constcat3=categoriesRepository.create({ name:'Computers' });constcat4=categoriesRepository.create({ name:'Games' });awaitcategoriesRepository.save([cat1, cat2, cat3, cat4]);constp1=productsRepository.create({ name:'Book of Cain', description:'The writings of an elderly scholar about this perilous world.', price:102.5, categories: [cat2],});constp2=productsRepository.create({ name:'Smart TV', price:2350, categories: [cat1, cat3],});constp3=productsRepository.create({ name:'Macbook Pro', price:1200, categories: [cat3],});constp4=productsRepository.create({ name:'Gaming PC', description:'Latest generation hardware for the best experience.', price:2000, categories: [cat3],});constp5=productsRepository.create({ name:'Game Mechanics: Advanced Game Design', description:'Learn how to craft well-designed game mechanics.', price:149.9, categories: [cat2],});constp6=productsRepository.create({ name:'Warcraft III: Reign of Chaos', description:'A true classic in the RTS genre.', price:25.99, categories: [cat4],});awaitproductsRepository.save([p1, p2, p3, p4, p5, p6]);constu1=usersRepository.create({ name:'Pedro Faria', email:'jarulf@mail.com', phone:'988888888', password:'123456',});constu2=usersRepository.create({ name:'Chris Metzen', email:'chris@blizz.com', phone:'977777777', password:'654321',});awaitusersRepository.save([u1, u2]);constoi1=orderItemsRepository.create({ product: p1, quantity:2, price:p1.price,});constoi2=orderItemsRepository.create({ product: p3, quantity:1, price:p3.price,});constoi3=orderItemsRepository.create({ product: p3, quantity:2, price:p3.price,});constoi4=orderItemsRepository.create({ product: p5, quantity:2, price:p5.price,});constpay1=paymentsRepository.create();consto1=ordersRepository.create({ customer: u1, items: [oi1, oi2], status:OrderStatus.AWAITING_SHIPMENT, payment: pay1,});consto2=ordersRepository.create({ customer: u2, items: [oi3], status:OrderStatus.AWAITING_PAYMENT,});consto3=ordersRepository.create({ customer: u1, items: [oi4], status:OrderStatus.AWAITING_PAYMENT,});awaitordersRepository.save([o1, o2, o3]);
In the Bonus Module 6 - Automated Testing (TBA), we'll learn how to perform these same operations by emulating requests from a user. This is possible with the supertest library. We'll also do so in a dedicated database purposed for testing.