From 08b862318d52f02855f7426346de023e11b60347 Mon Sep 17 00:00:00 2001 From: sanchezvem Date: Mon, 13 Oct 2025 14:22:43 +0200 Subject: [PATCH] new migration --- .../DTO/Login/Request/UpdateLoginDto.cs | 10 + .../Endpoints/Login/CreateLoginEndpoint.cs | 37 +++ .../Endpoints/Login/DeleteLoginEndpoint.cs | 36 +++ .../Endpoints/Login/GetAllLoginEndpoint.cs | 40 ++++ .../Endpoints/Login/GetLoginEndpoint.cs | 53 +++++ .../Endpoints/Login/UpdateLoginEndpoint.cs | 40 ++++ ...20251013121137_EditingDatabase.Designer.cs | 220 ++++++++++++++++++ .../20251013121137_EditingDatabase.cs | 22 ++ ApiEfCoreLibrary/Models/Login.cs | 4 +- 9 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 ApiEfCoreLibrary/DTO/Login/Request/UpdateLoginDto.cs create mode 100644 ApiEfCoreLibrary/Endpoints/Login/CreateLoginEndpoint.cs create mode 100644 ApiEfCoreLibrary/Endpoints/Login/DeleteLoginEndpoint.cs create mode 100644 ApiEfCoreLibrary/Endpoints/Login/GetAllLoginEndpoint.cs create mode 100644 ApiEfCoreLibrary/Endpoints/Login/GetLoginEndpoint.cs create mode 100644 ApiEfCoreLibrary/Endpoints/Login/UpdateLoginEndpoint.cs create mode 100644 ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.Designer.cs create mode 100644 ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.cs diff --git a/ApiEfCoreLibrary/DTO/Login/Request/UpdateLoginDto.cs b/ApiEfCoreLibrary/DTO/Login/Request/UpdateLoginDto.cs new file mode 100644 index 0000000..5bcaf6a --- /dev/null +++ b/ApiEfCoreLibrary/DTO/Login/Request/UpdateLoginDto.cs @@ -0,0 +1,10 @@ +namespace ApiEfCoreLibrary.DTO.Login.Request; + +public class UpdateLoginDto +{ + public int Id { get; set; } + public string? Username { get; set; } + public string? FullName { get; set; } + public string? Password { get; set; } + public string? Salt { get; set; } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Endpoints/Login/CreateLoginEndpoint.cs b/ApiEfCoreLibrary/Endpoints/Login/CreateLoginEndpoint.cs new file mode 100644 index 0000000..cae2199 --- /dev/null +++ b/ApiEfCoreLibrary/Endpoints/Login/CreateLoginEndpoint.cs @@ -0,0 +1,37 @@ +using ApiEfCoreLibrary.DTO.Author.Request; +using ApiEfCoreLibrary.DTO.Author.Response; + +namespace ApiEfCoreLibrary.Endpoints.Author; +using FastEndpoints; + +public class CreateLoginEndpoint(LibraryDbContext database) : Endpoint +{ + public override void Configure() + { + Post("/api/authors"); + AllowAnonymous(); + } + + public override async Task HandleAsync(CreateAuthorDto req, CancellationToken ct) + { + var author = new Models.Author() + { + Name = req.Name, + FirstName = req.FirstName + }; + + database.Authors.Add(author); + + await database.SaveChangesAsync(ct); + // Pour renvoyer une erreur : Send.StringAsync("Le message d'erreur", 400); + + GetAuthorDto responseDto = new() + { + Id = author.Id, + Name = author.Name, + FirstName = author.FirstName + }; + + await Send.OkAsync(responseDto, ct); + } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Endpoints/Login/DeleteLoginEndpoint.cs b/ApiEfCoreLibrary/Endpoints/Login/DeleteLoginEndpoint.cs new file mode 100644 index 0000000..0774f7a --- /dev/null +++ b/ApiEfCoreLibrary/Endpoints/Login/DeleteLoginEndpoint.cs @@ -0,0 +1,36 @@ +using ApiEfCoreLibrary.DTO.Author.Request; +using ApiEfCoreLibrary.DTO.Author.Response; +using FastEndpoints; +using Microsoft.EntityFrameworkCore; + +namespace ApiEfCoreLibrary.Endpoints.Author; + +public class DeleteAuthorRequest +{ + public int Id { get; set; } +} + +public class DeleteLoginEndpoint(LibraryDbContext database) : Endpoint +{ + public override void Configure() + { + Delete("/api/authors/{@Id}", x => new {x.Id}); + AllowAnonymous(); + } + + public override async Task HandleAsync(DeleteAuthorRequest req, CancellationToken ct) + { + var author = await database.Authors.SingleOrDefaultAsync(x => x.Id == req.Id, ct); + + if (author == null) + { + await Send.NotFoundAsync(ct); + return; + } + + database.Authors.Remove(author); + await database.SaveChangesAsync(ct); + + await Send.NoContentAsync(ct); + } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Endpoints/Login/GetAllLoginEndpoint.cs b/ApiEfCoreLibrary/Endpoints/Login/GetAllLoginEndpoint.cs new file mode 100644 index 0000000..9d47366 --- /dev/null +++ b/ApiEfCoreLibrary/Endpoints/Login/GetAllLoginEndpoint.cs @@ -0,0 +1,40 @@ +using ApiEfCoreLibrary.DTO.Author.Response; +using ApiEfCoreLibrary.DTO.Book.Response; +using FastEndpoints; +using Microsoft.EntityFrameworkCore; + +namespace ApiEfCoreLibrary.Endpoints.Author; + +public class GetAllLoginEndpoint(LibraryDbContext database) : EndpointWithoutRequest> +{ + public override void Configure() + { + Get("/api/authors"); + AllowAnonymous(); + } + + public override async Task HandleAsync(CancellationToken ct) + { + var authors = await database.Authors + .Include(x => x.Books) + .Select(author => new GetAuthorDto() + { + Id = author.Id, + Name = author.Name, + FirstName = author.FirstName, + Books = author.Books.Select(book => new GetBookDto + { + Id = book.Id, + Title = book.Title, + AuthorId = book.AuthorId, + BookAuthorName = book.Author.Name, + BookAuthorFirstName = book.Author.FirstName, + ReleaseYear = book.ReleaseYear, + Isbn = book.Isbn + }).ToList() + }) + .ToListAsync(ct); + + await Send.OkAsync(authors, ct); + } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Endpoints/Login/GetLoginEndpoint.cs b/ApiEfCoreLibrary/Endpoints/Login/GetLoginEndpoint.cs new file mode 100644 index 0000000..3a6fc46 --- /dev/null +++ b/ApiEfCoreLibrary/Endpoints/Login/GetLoginEndpoint.cs @@ -0,0 +1,53 @@ +using ApiEfCoreLibrary.DTO.Author.Request; +using ApiEfCoreLibrary.DTO.Author.Response; +using ApiEfCoreLibrary.DTO.Book.Response; +using FastEndpoints; +using Microsoft.EntityFrameworkCore; + +namespace ApiEfCoreLibrary.Endpoints.Author; + +public class GetAuthorRequest +{ + public int Id { get; set; } +} + +public class GetLoginEndpoint(LibraryDbContext database) : Endpoint +{ + public override void Configure() + { + Get("/api/authors/{@Id}", x => new {x.Id}); + AllowAnonymous(); + } + + public override async Task HandleAsync(GetAuthorRequest req, CancellationToken ct) + { + var author = await database.Authors + .Include(x => x.Books) + .SingleOrDefaultAsync(x => x.Id == req.Id, ct); + + if (author == null) + { + await Send.NotFoundAsync(ct); + return; + } + + GetAuthorDto responseDto = new() + { + Id = author.Id, + Name = author.Name, + FirstName = author.FirstName, + Books = author.Books.Select(book => new GetBookDto + { + Id = book.Id, + Title = book.Title, + AuthorId = book.AuthorId, + BookAuthorName = book.Author.Name, + BookAuthorFirstName = book.Author.FirstName, + ReleaseYear = book.ReleaseYear, + Isbn = book.Isbn + }).ToList() + }; + + await Send.OkAsync(responseDto, ct); + } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Endpoints/Login/UpdateLoginEndpoint.cs b/ApiEfCoreLibrary/Endpoints/Login/UpdateLoginEndpoint.cs new file mode 100644 index 0000000..7ea0feb --- /dev/null +++ b/ApiEfCoreLibrary/Endpoints/Login/UpdateLoginEndpoint.cs @@ -0,0 +1,40 @@ +using ApiEfCoreLibrary.DTO.Author.Request; +using ApiEfCoreLibrary.DTO.Author.Response; +using ApiEfCoreLibrary.DTO.Book.Response; +using FastEndpoints; +using Microsoft.EntityFrameworkCore; + +namespace ApiEfCoreLibrary.Endpoints.Author; + +public class UpdateLoginEndpoint(LibraryDbContext database) : Endpoint +{ + public override void Configure() + { + Put("/api/authors/{@Id}", x => new {x.Id}); + AllowAnonymous(); + } + + public override async Task HandleAsync(UpdateAuthorDto req, CancellationToken ct) + { + var author = await database.Authors.SingleOrDefaultAsync(x => x.Id == req.Id, ct); + + if (author == null) + { + await Send.NotFoundAsync(ct); + return; + } + + author.Name = req.Name; + author.FirstName = req.FirstName; + await database.SaveChangesAsync(ct); + + GetAuthorDto responseDto = new() + { + Id = author.Id, + Name = author.Name, + FirstName = author.FirstName, + }; + + await Send.OkAsync(responseDto, ct); + } +} \ No newline at end of file diff --git a/ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.Designer.cs b/ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.Designer.cs new file mode 100644 index 0000000..65d274a --- /dev/null +++ b/ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.Designer.cs @@ -0,0 +1,220 @@ +// +using System; +using ApiEfCoreLibrary; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ApiEfCoreLibrary.Migrations +{ + [DbContext(typeof(LibraryDbContext))] + [Migration("20251013121137_EditingDatabase")] + partial class EditingDatabase + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AuthorId") + .HasColumnType("int"); + + b.Property("Isbn") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("ReleaseYear") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Loan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BookId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("EffectiveReturningDate") + .HasColumnType("date"); + + b.Property("PlannedReturningDate") + .HasColumnType("date"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BookId"); + + b.HasIndex("UserId"); + + b.ToTable("Loans"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Login", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Salt") + .IsRequired() + .HasMaxLength(24) + .HasColumnType("nvarchar(24)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Logins"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BirthDate") + .HasColumnType("date"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Book", b => + { + b.HasOne("ApiEfCoreLibrary.Models.Author", "Author") + .WithMany("Books") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Loan", b => + { + b.HasOne("ApiEfCoreLibrary.Models.Book", "Book") + .WithMany() + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ApiEfCoreLibrary.Models.User", "User") + .WithMany("Loans") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.Author", b => + { + b.Navigation("Books"); + }); + + modelBuilder.Entity("ApiEfCoreLibrary.Models.User", b => + { + b.Navigation("Loans"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.cs b/ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.cs new file mode 100644 index 0000000..27fb9ce --- /dev/null +++ b/ApiEfCoreLibrary/Migrations/20251013121137_EditingDatabase.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ApiEfCoreLibrary.Migrations +{ + /// + public partial class EditingDatabase : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/ApiEfCoreLibrary/Models/Login.cs b/ApiEfCoreLibrary/Models/Login.cs index 62a2baf..6706108 100644 --- a/ApiEfCoreLibrary/Models/Login.cs +++ b/ApiEfCoreLibrary/Models/Login.cs @@ -6,6 +6,6 @@ public class Login [Key] public int Id { get; set; } [Required, MaxLength(100)] public string? Username { get; set; } [Required, MaxLength(200)] public string? FullName { get; set; } - [Required, MaxLength(255)] public string? Password { get; set; } - [Required, MinLength(24), MaxLength(24)] public string? Salt { get; set; } + [Required, Length(60, 60)] public string? Password { get; set; } + [Required, Length(24, 24)] public string? Salt { get; set; } } \ No newline at end of file