Skip to content

Commit

Permalink
US06
Browse files Browse the repository at this point in the history
  • Loading branch information
leafrse committed Feb 12, 2025
1 parent 61e26e5 commit 9338d5a
Show file tree
Hide file tree
Showing 7 changed files with 502 additions and 0 deletions.
95 changes: 95 additions & 0 deletions src/livros/Livro.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
HttpException,
HttpStatus,
NotFoundException,
ValidationPipe,
UsePipes
} from '@nestjs/common';
import { LivrosService } from './livro.service';
import { Livro } from './entities/livro.entity';
import { CreateLivroDto } from './dto/create-livro.dto'
import { UpdateLivroDto } from './dto/update-livro.dto';
@Controller('livros')
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
export class LivrosController {
constructor(private readonly livrosService: LivrosService) {}

@Get()
async findAll(): Promise<Livro[]> {
return this.livrosService.buscarLivros();
}

@Get('buscar')
async buscarlivros(
@Query('titulo') titulo: string,
@Query('autor') autor: string,
) {
try {
const livros = await this.livrosService.buscarLivros(titulo, autor);
return livros;
} catch (error) {
throw new HttpException(error.message, HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@Get(':id')
async findOne(@Param('id') id: string): Promise<Livro> {
const livro = await this.livrosService.buscarLivroPorId(id);
if (!livro) {
throw new NotFoundException(`Livro com ID ${id} não encontrado`);
}
return livro;
}

@Post()
async create(@Body() createLivroDto: CreateLivroDto): Promise<Livro> {
try {
return await this.livrosService.criarLivro(createLivroDto);
} catch (error) {
// Trata erros de validação (do TypeORM) e outros erros
if (error.name === 'QueryFailedError') {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
throw new HttpException('Erro ao criar livro', HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@Put(':id')
async update(
@Param('id') id: string,
@Body() updateLivroDto: UpdateLivroDto,
): Promise<Livro> {
try {
const livro = await this.livrosService.atualizarLivro(id, updateLivroDto);
if (!livro) {
throw new NotFoundException(`Livro com ID ${id} não encontrado`);
}
return livro;
} catch (error) {
if (error instanceof NotFoundException) { // Trata NotFoundException do serviço
throw error;
}
// Trata erros de validação (do TypeORM) e outros erros
if (error.name === 'QueryFailedError') {
throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
}
throw new HttpException('Erro ao atualizar livro', HttpStatus.INTERNAL_SERVER_ERROR);
}
}

@Delete(':id')
async remove(@Param('id') id: string): Promise<void> {
const result = await this.livrosService.removerLivro(id);
if (result.affected === 0) { // Verifica se algo foi deletado
throw new NotFoundException(`Livro com ID ${id} não encontrado`);
}
}
}
30 changes: 30 additions & 0 deletions src/livros/dto/create-livro.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { IsString, IsNotEmpty, IsOptional, Min, Max, IsInt } from 'class-validator';

export class CreateLivroDto {
@IsString()
@IsNotEmpty()
titulo: string;

@IsString()
@IsNotEmpty()
autor: string;

@IsInt()
@IsOptional()
@Min(0)
@Max(new Date().getFullYear())
anoPublicacao?: number;

@IsString()
@IsOptional()
editora?: string;

@IsString()
@IsOptional()
genero?: string;

preco?: number;
descricao?: string


}
13 changes: 13 additions & 0 deletions src/livros/dto/update-livro.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { PartialType } from '@nestjs/mapped-types';
import { CreateLivroDto } from './create-livro.dto';

export class UpdateLivroDto extends PartialType(CreateLivroDto) {

titulo?: string;
autor?: string;
anoPublicacao?: number;
editora?: string;
genero?: string;
preco?: number;
descricao?: string
}
42 changes: 42 additions & 0 deletions src/livros/entities/livro.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';

@Entity()
export class Livro {
@PrimaryGeneratedColumn('uuid')
id: string;

@Column()
titulo: string;

@Column()
autor: string;

@Column({ type: 'int', nullable: true })
anoPublicacao: number;

@Column({ nullable: true })
editora: string;

@Column({ nullable: true })
genero: string;

@Column({ nullable: true, type: 'real' })
preco?: number;

@Column({ nullable: true, type: 'text' })
descricao?: string;

@CreateDateColumn()
createdAt: Date;

@UpdateDateColumn()
updatedAt: Date;
}

export default Livro;
34 changes: 34 additions & 0 deletions src/livros/livro.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { EntityRepository, FindOneOptions, Repository } from 'typeorm';
import { Livro } from './entities/livro.entity';

@EntityRepository(Livro)
export class LivroRepository extends Repository<Livro> {

async buscarLivros(titulo?: string, autor?: string): Promise<Livro[]> {
const queryBuilder = this.createQueryBuilder('livro')
.select(['livro.id', 'livro.titulo', 'livro.autor', 'livro.anoPublicacao', 'livro.editora', 'livro.genero'])
.leftJoinAndSelect('livro.autor', 'autor')
.leftJoinAndSelect('livro.editora', 'editora');

if (titulo) {
queryBuilder.andWhere('livro.titulo ILIKE :titulo', { titulo: `%${titulo}%` });
}
if (autor) {
queryBuilder.andWhere('livro.autor ILIKE :autor', { autor: `%${autor}%` });
}

return queryBuilder.getMany();
}

async buscarLivroPorId(id: string): Promise<Livro | undefined> {
const options: FindOneOptions<Livro> = {
where: { id },
relations: ['autor', 'editora'],
select: ['id', 'titulo', 'autor', 'anoPublicacao', 'editora', 'genero'],
};

return this.findOne(options);
}


}
Loading

0 comments on commit 9338d5a

Please sign in to comment.