From 4908992a2ade8181aaf9950e6994f141d2396ef5 Mon Sep 17 00:00:00 2001 From: PedroGSDL Date: Wed, 4 Dec 2024 16:08:18 -0300 Subject: [PATCH] =?UTF-8?q?Api=20Constru=C3=ADda!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Context/OrganizadorContext.cs | 24 ++++-- Controllers/TarefaController.cs | 83 ++++++++++++++----- .../20241204185720_UpdateForMySql.Designer.cs | 49 +++++++++++ Migrations/20241204185720_UpdateForMySql.cs | 68 +++++++++++++++ Migrations/OrganizadorContextModelSnapshot.cs | 47 +++++++++++ Program.cs | 5 +- TrilhaApiDesafio.csproj | 5 ++ appsettings.Development.json | 2 +- appsettings.json | 5 +- trilha-net-api-desafio.sln | 25 ++++++ 10 files changed, 282 insertions(+), 31 deletions(-) create mode 100644 Migrations/20241204185720_UpdateForMySql.Designer.cs create mode 100644 Migrations/20241204185720_UpdateForMySql.cs create mode 100644 Migrations/OrganizadorContextModelSnapshot.cs create mode 100644 trilha-net-api-desafio.sln diff --git a/Context/OrganizadorContext.cs b/Context/OrganizadorContext.cs index d9128a34..06ce3e90 100644 --- a/Context/OrganizadorContext.cs +++ b/Context/OrganizadorContext.cs @@ -3,13 +3,27 @@ namespace TrilhaApiDesafio.Context { - public class OrganizadorContext : DbContext + public class AppDbContext : DbContext { - public OrganizadorContext(DbContextOptions options) : base(options) + public DbSet Tarefas { get; set; } + + // Construtor necessário para o AddDbContext funcionar + public AppDbContext(DbContextOptions options) + : base(options) { - } - public DbSet Tarefas { get; set; } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .Property(t => t.Titulo) + .HasColumnType("TEXT"); // MySQL-compatible type for large text + modelBuilder.Entity() + .Property(t => t.Descricao) + .HasColumnType("TEXT"); // MySQL-compatible type for large text + modelBuilder.Entity() + .Property(t => t.Data) + .HasColumnType("DATETIME"); // MySQL-compatible type for date and time + } } -} \ No newline at end of file +} diff --git a/Controllers/TarefaController.cs b/Controllers/TarefaController.cs index ba96b30f..30dfaf93 100644 --- a/Controllers/TarefaController.cs +++ b/Controllers/TarefaController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using TrilhaApiDesafio.Context; using TrilhaApiDesafio.Models; +using System.Linq; namespace TrilhaApiDesafio.Controllers { @@ -8,9 +9,9 @@ namespace TrilhaApiDesafio.Controllers [Route("[controller]")] public class TarefaController : ControllerBase { - private readonly OrganizadorContext _context; + private readonly AppDbContext _context; - public TarefaController(OrganizadorContext context) + public TarefaController(AppDbContext context) { _context = context; } @@ -18,41 +19,55 @@ public TarefaController(OrganizadorContext context) [HttpGet("{id}")] public IActionResult ObterPorId(int id) { - // TODO: Buscar o Id no banco utilizando o EF - // TODO: Validar o tipo de retorno. Se não encontrar a tarefa, retornar NotFound, - // caso contrário retornar OK com a tarefa encontrada - return Ok(); + // Buscar o ID no banco de dados + var tarefa = _context.Tarefas.Find(id); + + // Se não encontrar, retornar NotFound + if (tarefa == null) + return NotFound(); + + // Caso contrário, retornar OK com a tarefa encontrada + return Ok(tarefa); } [HttpGet("ObterTodos")] public IActionResult ObterTodos() { - // TODO: Buscar todas as tarefas no banco utilizando o EF - return Ok(); + // Buscar todas as tarefas no banco + var tarefas = _context.Tarefas.ToList(); + + // Retornar OK com a lista de tarefas + return Ok(tarefas); } [HttpGet("ObterPorTitulo")] public IActionResult ObterPorTitulo(string titulo) { - // TODO: Buscar as tarefas no banco utilizando o EF, que contenha o titulo recebido por parâmetro - // Dica: Usar como exemplo o endpoint ObterPorData - return Ok(); + // Buscar tarefas que contenham o título especificado + var tarefas = _context.Tarefas.Where(t => t.Titulo.Contains(titulo)).ToList(); + + // Retornar OK com a lista de tarefas encontradas + return Ok(tarefas); } [HttpGet("ObterPorData")] public IActionResult ObterPorData(DateTime data) { - var tarefa = _context.Tarefas.Where(x => x.Data.Date == data.Date); - return Ok(tarefa); + // Buscar tarefas com a mesma data (desconsiderando o horário) + var tarefas = _context.Tarefas.Where(x => x.Data.Date == data.Date).ToList(); + + // Retornar OK com as tarefas encontradas + return Ok(tarefas); } [HttpGet("ObterPorStatus")] public IActionResult ObterPorStatus(EnumStatusTarefa status) { - // TODO: Buscar as tarefas no banco utilizando o EF, que contenha o status recebido por parâmetro - // Dica: Usar como exemplo o endpoint ObterPorData - var tarefa = _context.Tarefas.Where(x => x.Status == status); - return Ok(tarefa); + // Buscar tarefas com o status especificado + var tarefas = _context.Tarefas.Where(x => x.Status == status).ToList(); + + // Retornar OK com as tarefas encontradas + return Ok(tarefas); } [HttpPost] @@ -61,35 +76,59 @@ public IActionResult Criar(Tarefa tarefa) if (tarefa.Data == DateTime.MinValue) return BadRequest(new { Erro = "A data da tarefa não pode ser vazia" }); - // TODO: Adicionar a tarefa recebida no EF e salvar as mudanças (save changes) + // Adicionar a nova tarefa ao banco + _context.Tarefas.Add(tarefa); + + // Salvar as mudanças + _context.SaveChanges(); + + // Retornar CreatedAtAction com os dados da nova tarefa return CreatedAtAction(nameof(ObterPorId), new { id = tarefa.Id }, tarefa); } [HttpPut("{id}")] public IActionResult Atualizar(int id, Tarefa tarefa) { + // Buscar a tarefa no banco pelo ID var tarefaBanco = _context.Tarefas.Find(id); + // Se não encontrar, retornar NotFound if (tarefaBanco == null) return NotFound(); if (tarefa.Data == DateTime.MinValue) return BadRequest(new { Erro = "A data da tarefa não pode ser vazia" }); - // TODO: Atualizar as informações da variável tarefaBanco com a tarefa recebida via parâmetro - // TODO: Atualizar a variável tarefaBanco no EF e salvar as mudanças (save changes) - return Ok(); + // Atualizar os dados da tarefaBanco com os dados recebidos + tarefaBanco.Titulo = tarefa.Titulo; + tarefaBanco.Descricao = tarefa.Descricao; + tarefaBanco.Data = tarefa.Data; + tarefaBanco.Status = tarefa.Status; + + // Salvar as mudanças no banco + _context.SaveChanges(); + + // Retornar OK + return Ok(tarefaBanco); } [HttpDelete("{id}")] public IActionResult Deletar(int id) { + // Buscar a tarefa no banco pelo ID var tarefaBanco = _context.Tarefas.Find(id); + // Se não encontrar, retornar NotFound if (tarefaBanco == null) return NotFound(); - // TODO: Remover a tarefa encontrada através do EF e salvar as mudanças (save changes) + // Remover a tarefa encontrada + _context.Tarefas.Remove(tarefaBanco); + + // Salvar as mudanças no banco + _context.SaveChanges(); + + // Retornar NoContent return NoContent(); } } diff --git a/Migrations/20241204185720_UpdateForMySql.Designer.cs b/Migrations/20241204185720_UpdateForMySql.Designer.cs new file mode 100644 index 00000000..a817d780 --- /dev/null +++ b/Migrations/20241204185720_UpdateForMySql.Designer.cs @@ -0,0 +1,49 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TrilhaApiDesafio.Context; + +#nullable disable + +namespace TrilhaApiDesafio.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20241204185720_UpdateForMySql")] + partial class UpdateForMySql + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.33") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("TrilhaApiDesafio.Models.Tarefa", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Data") + .HasColumnType("DATETIME"); + + b.Property("Descricao") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Titulo") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Tarefas"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20241204185720_UpdateForMySql.cs b/Migrations/20241204185720_UpdateForMySql.cs new file mode 100644 index 00000000..b7939931 --- /dev/null +++ b/Migrations/20241204185720_UpdateForMySql.cs @@ -0,0 +1,68 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace TrilhaApiDesafio.Migrations +{ + public partial class UpdateForMySql : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Titulo", + table: "Tarefas", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Descricao", + table: "Tarefas", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Data", + table: "Tarefas", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime2(6)"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Titulo", + table: "Tarefas", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Descricao", + table: "Tarefas", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Data", + table: "Tarefas", + type: "datetime2(6)", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + } + } +} diff --git a/Migrations/OrganizadorContextModelSnapshot.cs b/Migrations/OrganizadorContextModelSnapshot.cs new file mode 100644 index 00000000..c3e6573b --- /dev/null +++ b/Migrations/OrganizadorContextModelSnapshot.cs @@ -0,0 +1,47 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TrilhaApiDesafio.Context; + +#nullable disable + +namespace TrilhaApiDesafio.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class OrganizadorContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.33") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("TrilhaApiDesafio.Models.Tarefa", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Data") + .HasColumnType("DATETIME"); + + b.Property("Descricao") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Titulo") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Tarefas"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Program.cs b/Program.cs index eae6505e..df6d78d5 100644 --- a/Program.cs +++ b/Program.cs @@ -5,8 +5,9 @@ var builder = WebApplication.CreateBuilder(args); // Add services to the container. -builder.Services.AddDbContext(options => - options.UseSqlServer(builder.Configuration.GetConnectionString("ConexaoPadrao"))); +builder.Services.AddDbContext(options => + options.UseMySQL( + builder.Configuration.GetConnectionString("MySql"))); builder.Services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())); diff --git a/TrilhaApiDesafio.csproj b/TrilhaApiDesafio.csproj index ab338f7c..4d27db87 100644 --- a/TrilhaApiDesafio.csproj +++ b/TrilhaApiDesafio.csproj @@ -12,6 +12,11 @@ all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/appsettings.Development.json b/appsettings.Development.json index 9978cbfd..3b3ace22 100644 --- a/appsettings.Development.json +++ b/appsettings.Development.json @@ -6,6 +6,6 @@ } }, "ConnectionStrings": { - "ConexaoPadrao": "COLOCAR SUA CONNECTION STRING AQUI" + "MySql": "Server = localhost; Database = api_desafio; Uid = root; pwd = Gabrieleition2@" } } diff --git a/appsettings.json b/appsettings.json index 10f68b8c..b96a0126 100644 --- a/appsettings.json +++ b/appsettings.json @@ -5,5 +5,8 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "ConnectionStrings": { + "MySql": "Informações de conexão retiradas" + } } diff --git a/trilha-net-api-desafio.sln b/trilha-net-api-desafio.sln new file mode 100644 index 00000000..9b428c86 --- /dev/null +++ b/trilha-net-api-desafio.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrilhaApiDesafio", "TrilhaApiDesafio.csproj", "{368CECBF-0F59-4B41-A45F-882B5D4407A1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {368CECBF-0F59-4B41-A45F-882B5D4407A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {368CECBF-0F59-4B41-A45F-882B5D4407A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {368CECBF-0F59-4B41-A45F-882B5D4407A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {368CECBF-0F59-4B41-A45F-882B5D4407A1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0F7F305B-0F70-4153-A306-D7A0E574644C} + EndGlobalSection +EndGlobal