import { Injectable } from '@nestjs/common'; import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm'; import { EntityManager, Repository, TreeRepository } from 'typeorm'; import { NewItemInput } from './dto/new-item.input'; import { Item } from './items.entity'; import { ItemModel } from './items.model'; @Injectable() export class ItemsService { constructor( @InjectRepository(Item) private itemRepository: Repository, @InjectEntityManager() private entityManager: EntityManager, ) { this.treeRepository = this.entityManager.getTreeRepository(Item); } treeRepository: TreeRepository; async getItem(id: string): Promise { return this.itemRepository.findOne(id); } async getItemParent(item: ItemModel): Promise { const childItem = await this.itemRepository.findOneOrFail(item.id, { relations: ['parent'], }); return childItem.parent; } async getItemChildren(item: ItemModel): Promise { return this.itemRepository.find({ where: { parent: item.id, }, }); } async getItemDescendents(item: ItemModel): Promise { const parentItem = await this.itemRepository.findOneOrFail(item.id, { relations: ['parent'], }); return this.treeRepository.findDescendants(parentItem); } async createItem(input: NewItemInput): Promise { const item = this.itemRepository.create({ ...input, id: input.id || undefined, parent: input.parent ? await this.itemRepository.findOneOrFail(input.parent) : undefined, }); const highestIdQuery = this.itemRepository .createQueryBuilder() .select('id') .orderBy('id', 'DESC') .limit(1); const insert = await this.itemRepository .createQueryBuilder() .insert() .into(Item) .values({ ...item, // if id is specified, use it. // if not, get the highest id in table and use highest_id+1 id: input.id || (() => `((${highestIdQuery.getSql()}) + 1)`), }) .returning(['id']) .execute(); item.id = insert.identifiers[0].id || item.id; return item; } }