diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a0c693c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/John Peter/Stage 2 Project/bin/Debug/net6.0/Banking.dll", + "args": [], + "cwd": "${workspaceFolder}/John Peter/Stage 2 Project", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..e16611d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/John Peter/Stage 2 Project/Banking.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/John Peter/Stage 2 Project/Banking.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/John Peter/Stage 2 Project/Banking.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/John Peter/Library/.vscode/launch.json b/John Peter/Library/.vscode/launch.json new file mode 100644 index 0000000..0fd6fb1 --- /dev/null +++ b/John Peter/Library/.vscode/launch.json @@ -0,0 +1,36 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/net6.0/Library.dll", + "args": [], + "cwd": "${workspaceFolder}", + "stopAtEntry": false, + "requireExactSource": false, + // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} diff --git a/John Peter/Library/.vscode/tasks.json b/John Peter/Library/.vscode/tasks.json new file mode 100644 index 0000000..ed7655b --- /dev/null +++ b/John Peter/Library/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Library.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Library.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/Library.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/John Peter/Library/Context/LibraryContext.cs b/John Peter/Library/Context/LibraryContext.cs new file mode 100644 index 0000000..e1e3875 --- /dev/null +++ b/John Peter/Library/Context/LibraryContext.cs @@ -0,0 +1,133 @@ +using Microsoft.EntityFrameworkCore; +using Library.Models; + +namespace Library.Context; + +public partial class LibraryContext : DbContext +{ + public LibraryContext() { } + + public LibraryContext(DbContextOptions options) + : base(options) { } + + public virtual DbSet Authors { get; set; } + + public virtual DbSet Books { get; set; } + + public virtual DbSet Publishers { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => + optionsBuilder.UseMySql( + "name=ConnectionStrings:LocalSQL", + Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.32-mysql") + ); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.UseCollation("utf8mb4_0900_ai_ci").HasCharSet("utf8mb4"); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("Author"); + + entity.HasIndex(e => e.PublisherId, "publisher_id"); + + entity.Property(e => e.Id).HasColumnName("id"); + entity.Property(e => e.Name).HasMaxLength(255).HasColumnName("name"); + entity.Property(e => e.PublisherId).HasColumnName("publisher_id"); + + entity + .HasOne(d => d.Publisher) + .WithMany(p => p.Authors) + .HasForeignKey(d => d.PublisherId) + .HasConstraintName("Author_ibfk_1"); + + entity + .HasMany(d => d.Books) + .WithMany(p => p.Authors) + .UsingEntity>( + "AuthorBook", + r => + r.HasOne() + .WithMany() + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Author_Book_ibfk_2"), + l => + l.HasOne() + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Author_Book_ibfk_1"), + j => + { + j.HasKey("AuthorId", "BookId") + .HasName("PRIMARY") + .HasAnnotation("MySql:IndexPrefixLength", new[] { 0, 0 }); + j.ToTable("Author_Book"); + j.HasIndex(new[] { "BookId" }, "book_id"); + j.IndexerProperty("AuthorId").HasColumnName("author_id"); + j.IndexerProperty("BookId").HasColumnName("book_id"); + } + ); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("Book"); + + entity.HasIndex(e => e.AuthorId, "author_id"); + + entity.Property(e => e.Id).HasColumnName("id"); + entity.Property(e => e.AuthorId).HasColumnName("author_id"); + entity.Property(e => e.Title).HasMaxLength(255).HasColumnName("title"); + + entity + .HasMany(b => b.Authors) + .WithMany(a => a.Books) + .UsingEntity>( + "AuthorBook", + b => + b.HasOne() + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Author_Book_ibfk_1"), + a => + a.HasOne() + .WithMany() + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("Author_Book_ibfk_2"), + j => + { + j.HasKey("AuthorId", "BookId") + .HasName("PRIMARY") + .HasAnnotation("MySql:IndexPrefixLength", new[] { 0, 0 }); + j.ToTable("Author_Book"); + j.HasIndex(new[] { "BookId" }, "book_id"); + j.IndexerProperty("AuthorId").HasColumnName("author_id"); + j.IndexerProperty("BookId").HasColumnName("book_id"); + } + ); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id).HasName("PRIMARY"); + + entity.ToTable("Publisher"); + + entity.Property(e => e.Id).HasColumnName("id"); + entity.Property(e => e.Name).HasMaxLength(255).HasColumnName("name"); + }); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); +} diff --git a/John Peter/Library/Controllers/AuthorController.cs b/John Peter/Library/Controllers/AuthorController.cs new file mode 100644 index 0000000..3b4d87b --- /dev/null +++ b/John Peter/Library/Controllers/AuthorController.cs @@ -0,0 +1,51 @@ +using Library.DTO; +using Library.Interfaces; +using Library.Models; +using Microsoft.AspNetCore.Mvc; + +namespace Library.Controllers +{ + [ApiController] + [Route("authors")] + public class AuthorController : ControllerBase + { + private readonly IAuthorsRepository authorsRepository; + + public AuthorController(IAuthorsRepository authorsRepository) + { + this.authorsRepository = authorsRepository; + } + + [HttpPost] + public async Task> CreateAuthorAsync(CreateAuthorDTO authorDTO) + { + Author newAuthor = new() { Name = authorDTO.Name, PublisherId = authorDTO.PublisherId }; + return Ok(await authorsRepository.CreateAuthorAsync(newAuthor)); + } + + [HttpGet] + public async Task>> GetAuthorsAsync() + { + var authors = await authorsRepository.GetAuthorsAsync(); + return Ok(authors.Select(aut => aut.AuthorList())); + } + + [HttpGet("{id}")] + public async Task> GetAuthorByIdAsync(int id) + { + var author = await authorsRepository.GetAuthorByIdAsync(id); + if (author is null) + { + return NotFound(); + } + return Ok(author); + } + + [HttpGet("{id}/books")] + public async Task>> GetAuthorBooksByIdAsync(int id) + { + var books = await authorsRepository.GetBooksByAuthorIdAsync(id); + return Ok(books.Select(book => book.BookList())); + } + } +} diff --git a/John Peter/Library/Controllers/BookController.cs b/John Peter/Library/Controllers/BookController.cs new file mode 100644 index 0000000..9120ce7 --- /dev/null +++ b/John Peter/Library/Controllers/BookController.cs @@ -0,0 +1,36 @@ +using Library.Models; +using Microsoft.AspNetCore.Mvc; + +namespace Library.Controllers +{ + [ApiController] + [Route("books")] + public class BooksController : ControllerBase + { + private readonly IBooksRepository booksRepository; + + public BooksController(IBooksRepository repository) + { + this.booksRepository = repository; + } + + [HttpPost] + public async Task> CreateBookAsync(CreateBookDTO bookDTO) + { + Book newBook = new() { Title = bookDTO.Title, AuthorId = bookDTO.AuthorId }; + return Ok(await booksRepository.CreateBookAsync(newBook)); + } + + [HttpGet("{id}")] + public async Task> GetBookByIdAsync(int id) + { + return Ok(await booksRepository.GetBookAsync(id)); + } + + [HttpGet] + public async Task>> GetAllBooks() + { + return Ok(await booksRepository.GetBooksAsync()); + } + } +} diff --git a/John Peter/Library/Controllers/PublisherController.cs b/John Peter/Library/Controllers/PublisherController.cs new file mode 100644 index 0000000..ca25c7e --- /dev/null +++ b/John Peter/Library/Controllers/PublisherController.cs @@ -0,0 +1,63 @@ +using Library.DTO; +using Library.Interfaces; +using Library.Models; +using Library.Repositories; +using Microsoft.AspNetCore.Mvc; + +namespace Library.Controllers +{ + [ApiController] + [Route("publishers")] + public class PublisherController : ControllerBase + { + private readonly IPublisherRepository publisherRepository; + + public PublisherController(IPublisherRepository publisherRepository) + { + this.publisherRepository = publisherRepository; + } + + [HttpPost] + public async Task> CreatePublisherAsync( + CreatePublisherDTO publisherDTO + ) + { + Publisher pub = new() { Name = publisherDTO.Name, }; + + return Ok(await publisherRepository.CreatePublisherAsync(pub)); + } + + [HttpGet] + public async Task> GetPublishersAsync() + { + var publishers = (await publisherRepository.GetPublishersAsync()).Select( + pub => pub.AsIs() + ); + return publishers; + } + + [HttpGet("{id}")] + public async Task> GetPublisherAsync(int id) + { + var pub = await publisherRepository.GetPublisherAsync(id); + if (pub is null) + { + return NotFound(); + } + + return pub.AsIs(); + } + + [HttpGet("{id}/authors")] + public async Task>> GetAttachedAuthorsByIdAsync(int id) + { + var authors = await publisherRepository.GetAuthorsByPublisherIdAsync(id); + if (authors is null) + { + return NotFound(); + } + var authorsDTO = authors.Select(author => author.AuthorList()); + return Ok(authorsDTO); + } + } +} diff --git a/John Peter/Library/DTO/AuthorDTO.cs b/John Peter/Library/DTO/AuthorDTO.cs new file mode 100644 index 0000000..81621d5 --- /dev/null +++ b/John Peter/Library/DTO/AuthorDTO.cs @@ -0,0 +1,14 @@ +using System.Runtime.Serialization; +using Library.Models; + +public class AuthorDTO +{ + public int Id { get; set; } + + public string Name { get; set; } = null!; + public int? PublisherId { get; set; } + + public string? PublisherName { get; set; } + + public virtual ICollection? Books { get; set; } +} diff --git a/John Peter/Library/DTO/BookDTO.cs b/John Peter/Library/DTO/BookDTO.cs new file mode 100644 index 0000000..7872438 --- /dev/null +++ b/John Peter/Library/DTO/BookDTO.cs @@ -0,0 +1,12 @@ +using Library.Models; + +public class BookDTO +{ + public int Id { get; set; } + + public string Title { get; set; } = null!; + + public int AuthorId { get; set; } + public string AuthorName { get; set; } + public virtual ICollection Authors { get; set; } +} diff --git a/John Peter/Library/DTO/CreateAuthorDTO.cs b/John Peter/Library/DTO/CreateAuthorDTO.cs new file mode 100644 index 0000000..612fdd6 --- /dev/null +++ b/John Peter/Library/DTO/CreateAuthorDTO.cs @@ -0,0 +1,11 @@ +using Library.Models; + +namespace Library.DTO +{ + public class CreateAuthorDTO + { + public string Name { get; set; } = null!; + + public int? PublisherId { get; set; } + } +} diff --git a/John Peter/Library/DTO/CreateBookDTO.cs b/John Peter/Library/DTO/CreateBookDTO.cs new file mode 100644 index 0000000..d9dc655 --- /dev/null +++ b/John Peter/Library/DTO/CreateBookDTO.cs @@ -0,0 +1,6 @@ +public class CreateBookDTO +{ + public string Title { get; set; } + + public int AuthorId { get; set; } +} diff --git a/John Peter/Library/DTO/CreatePublisherDTO.cs b/John Peter/Library/DTO/CreatePublisherDTO.cs new file mode 100644 index 0000000..5a87704 --- /dev/null +++ b/John Peter/Library/DTO/CreatePublisherDTO.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; +using Library.Models; + +namespace Library.DTO +{ + public class CreatePublisherDTO + { + [Required] + public string Name { get; set; } + + public virtual ICollection Authors { get; } = new List(); + } +} diff --git a/John Peter/Library/DTO/PublisherDTO.cs b/John Peter/Library/DTO/PublisherDTO.cs new file mode 100644 index 0000000..75ecc41 --- /dev/null +++ b/John Peter/Library/DTO/PublisherDTO.cs @@ -0,0 +1,13 @@ +using Library.Models; + +namespace Library.DTO +{ + public class PublisherDTO + { + public int Id { get; set; } + + public string Name { get; set; } = null!; + + public virtual ICollection Authors { get; } = new List(); + } +} diff --git a/John Peter/Library/Extensions.cs b/John Peter/Library/Extensions.cs new file mode 100644 index 0000000..e59ce85 --- /dev/null +++ b/John Peter/Library/Extensions.cs @@ -0,0 +1,44 @@ +using Library.DTO; +using Library.Models; + +namespace Library +{ + public static class Extensions + { + public static PublisherDTO AsIs(this Publisher publisher) + { + return new PublisherDTO + { + Id = publisher.Id, + Name = publisher.Name, + // Authors = publisher.Authors + }; + } + + public static AuthorDTO AuthorList(this Author author) + { + if (author is null) + { + throw new ArgumentNullException(nameof(author)); + } + + return new AuthorDTO + { + Id = author.Id, + Name = author.Name, + PublisherName = author.Publisher.Name, + Books = author.Books.ToList() + }; + } + + public static BookDTO BookList(this Book book) + { + return new BookDTO + { + Id = book.Id, + Title = book.Title, + Authors = book.Authors + }; + } + } +} diff --git a/John Peter/Library/Interfaces/IAuthorRepository.cs b/John Peter/Library/Interfaces/IAuthorRepository.cs new file mode 100644 index 0000000..0f8cace --- /dev/null +++ b/John Peter/Library/Interfaces/IAuthorRepository.cs @@ -0,0 +1,12 @@ +using Library.Models; + +namespace Library.Interfaces +{ + public interface IAuthorsRepository + { + Task CreateAuthorAsync(Author author); + Task GetAuthorByIdAsync(int id); + Task> GetAuthorsAsync(); + Task> GetBooksByAuthorIdAsync(int id); + } +} diff --git a/John Peter/Library/Interfaces/IBooksRepository.cs b/John Peter/Library/Interfaces/IBooksRepository.cs new file mode 100644 index 0000000..bc03079 --- /dev/null +++ b/John Peter/Library/Interfaces/IBooksRepository.cs @@ -0,0 +1,8 @@ +using Library.Models; + +public interface IBooksRepository +{ + Task CreateBookAsync(Book book); + Task GetBookAsync(int bookId); + Task> GetBooksAsync(); +} diff --git a/John Peter/Library/Interfaces/IPublisherRepository.cs b/John Peter/Library/Interfaces/IPublisherRepository.cs new file mode 100644 index 0000000..584a546 --- /dev/null +++ b/John Peter/Library/Interfaces/IPublisherRepository.cs @@ -0,0 +1,13 @@ +using Library.DTO; +using Library.Models; + +namespace Library.Interfaces +{ + public interface IPublisherRepository + { + Task CreatePublisherAsync(Publisher publisher); + Task> GetAuthorsByPublisherIdAsync(int publisherId); + Task GetPublisherAsync(int id); + Task> GetPublishersAsync(); + } +} diff --git a/John Peter/Library/Library.csproj b/John Peter/Library/Library.csproj new file mode 100644 index 0000000..e800203 --- /dev/null +++ b/John Peter/Library/Library.csproj @@ -0,0 +1,15 @@ + + + net6.0 + enable + enable + aa1a745d-7537-4db0-b558-20df16d203c4 + + + + + + + + + \ No newline at end of file diff --git a/John Peter/Library/LibrarySchema.db b/John Peter/Library/LibrarySchema.db new file mode 100644 index 0000000..011265e --- /dev/null +++ b/John Peter/Library/LibrarySchema.db @@ -0,0 +1,127 @@ +-- MySQL dump 10.13 Distrib 8.0.32, for Linux (x86_64) +-- +-- Host: localhost Database: library +-- ------------------------------------------------------ +-- Server version 8.0.32-0ubuntu0.22.04.2 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `Author` +-- + +DROP TABLE IF EXISTS `Author`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `Author` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `publisher_id` int DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `publisher_id` (`publisher_id`), + CONSTRAINT `Author_ibfk_1` FOREIGN KEY (`publisher_id`) REFERENCES `Publisher` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `Author` +-- + +LOCK TABLES `Author` WRITE; +/*!40000 ALTER TABLE `Author` DISABLE KEYS */; +/*!40000 ALTER TABLE `Author` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `Author_Book` +-- + +DROP TABLE IF EXISTS `Author_Book`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `Author_Book` ( + `author_id` int NOT NULL, + `book_id` int NOT NULL, + PRIMARY KEY (`author_id`,`book_id`), + KEY `book_id` (`book_id`), + CONSTRAINT `Author_Book_ibfk_1` FOREIGN KEY (`author_id`) REFERENCES `Author` (`id`), + CONSTRAINT `Author_Book_ibfk_2` FOREIGN KEY (`book_id`) REFERENCES `Book` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `Author_Book` +-- + +LOCK TABLES `Author_Book` WRITE; +/*!40000 ALTER TABLE `Author_Book` DISABLE KEYS */; +/*!40000 ALTER TABLE `Author_Book` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `Book` +-- + +DROP TABLE IF EXISTS `Book`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `Book` ( + `id` int NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `author_id` int NOT NULL, + PRIMARY KEY (`id`), + KEY `author_id` (`author_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `Book` +-- + +LOCK TABLES `Book` WRITE; +/*!40000 ALTER TABLE `Book` DISABLE KEYS */; +/*!40000 ALTER TABLE `Book` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `Publisher` +-- + +DROP TABLE IF EXISTS `Publisher`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `Publisher` ( + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `Publisher` +-- + +LOCK TABLES `Publisher` WRITE; +/*!40000 ALTER TABLE `Publisher` DISABLE KEYS */; +/*!40000 ALTER TABLE `Publisher` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2023-03-16 10:08:41 diff --git a/John Peter/Library/Models/Author.cs b/John Peter/Library/Models/Author.cs new file mode 100644 index 0000000..28dd602 --- /dev/null +++ b/John Peter/Library/Models/Author.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace Library.Models; + +public class Author +{ + public int Id { get; set; } + + public string Name { get; set; } = null!; + + public int? PublisherId { get; set; } + + public Publisher? Publisher { get; set; } + + public virtual ICollection Books { get; set; } = new List(); +} diff --git a/John Peter/Library/Models/AuthorBook.cs b/John Peter/Library/Models/AuthorBook.cs new file mode 100644 index 0000000..c64d392 --- /dev/null +++ b/John Peter/Library/Models/AuthorBook.cs @@ -0,0 +1,11 @@ +// namespace Library.Models +// { +// public class AuthorBook +// { +// public int AuthorId { get; set; } +// public Author Author { get; set; } + +// public int BookId { get; set; } +// public Book Book { get; set; } +// } +// } diff --git a/John Peter/Library/Models/Book.cs b/John Peter/Library/Models/Book.cs new file mode 100644 index 0000000..967db64 --- /dev/null +++ b/John Peter/Library/Models/Book.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace Library.Models; + +public partial class Book +{ + public int Id { get; set; } + + public string Title { get; set; } = null!; + + public int AuthorId { get; set; } + + // public Author? Author { get; set; } + + public virtual ICollection Authors { get; set; } = new List(); +} diff --git a/John Peter/Library/Models/Publisher.cs b/John Peter/Library/Models/Publisher.cs new file mode 100644 index 0000000..817bdfa --- /dev/null +++ b/John Peter/Library/Models/Publisher.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace Library.Models; + +public partial class Publisher +{ + public int Id { get; set; } + + public string Name { get; set; } = null!; + + public virtual ICollection Authors { get; } = new List(); +} diff --git a/John Peter/Library/Program.cs b/John Peter/Library/Program.cs new file mode 100644 index 0000000..0d95be1 --- /dev/null +++ b/John Peter/Library/Program.cs @@ -0,0 +1,44 @@ +using Library.Context; +using Library.Interfaces; +using Library.Repositories; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Configuration.AddUserSecrets(); + +builder.Services.AddControllers(); + +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +//Service Registration +builder.Services.AddDbContext( + options => + options.UseMySql( + "name=ConnectionStrings:LocalSQL", + Microsoft.EntityFrameworkCore.ServerVersion.Parse("8.0.32-mysql") + ) +); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/John Peter/Library/Properties/launchSettings.json b/John Peter/Library/Properties/launchSettings.json new file mode 100644 index 0000000..2d8e86a --- /dev/null +++ b/John Peter/Library/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:24308", + "sslPort": 44329 + } + }, + "profiles": { + "Library": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7096;http://localhost:5046", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/John Peter/Library/Repositories/AuthorsRepository.cs b/John Peter/Library/Repositories/AuthorsRepository.cs new file mode 100644 index 0000000..bc4ce4b --- /dev/null +++ b/John Peter/Library/Repositories/AuthorsRepository.cs @@ -0,0 +1,44 @@ +using Library.Context; +using Library.Interfaces; +using Library.Models; +using Microsoft.EntityFrameworkCore; + +namespace Library.Repositories +{ + class AuthorsRepository : IAuthorsRepository + { + private readonly LibraryContext dbContext; + + public AuthorsRepository(LibraryContext dbContext) + { + this.dbContext = dbContext; + } + + public async Task CreateAuthorAsync(Author author) + { + await dbContext.Authors.AddAsync(author); + await dbContext.SaveChangesAsync(); + + return author; + } + + public async Task> GetAuthorsAsync() + { + return await dbContext.Authors.Include(author => author.Publisher).ToListAsync(); + } + + public async Task GetAuthorByIdAsync(int id) + { + return await dbContext.Authors.FindAsync(id); + } + + public async Task> GetBooksByAuthorIdAsync(int id) + { + var author = await dbContext.Authors + .Include(a => a.Books) + .FirstOrDefaultAsync(a => a.Id == id); + + return author.Books; + } + } +} diff --git a/John Peter/Library/Repositories/BooksRepository.cs b/John Peter/Library/Repositories/BooksRepository.cs new file mode 100644 index 0000000..3cec518 --- /dev/null +++ b/John Peter/Library/Repositories/BooksRepository.cs @@ -0,0 +1,34 @@ +using Library.Context; +using Library.Models; +using Microsoft.EntityFrameworkCore; + +namespace Library.Repositories +{ + class BooksRepository : IBooksRepository + { + private readonly LibraryContext dbContext; + + public BooksRepository(LibraryContext dbContext) + { + this.dbContext = dbContext; + } + + public async Task CreateBookAsync(Book book) + { + await dbContext.Books.AddAsync(book); + await dbContext.SaveChangesAsync(); + return book; + } + + public async Task> GetBooksAsync() + { + return await dbContext.Books.Include(b => b.Authors).ToListAsync(); + } + + public async Task GetBookAsync(int bookId) + { + var books = await dbContext.Books.FindAsync(bookId); + return books; + } + } +} diff --git a/John Peter/Library/Repositories/PublisherRepository.cs b/John Peter/Library/Repositories/PublisherRepository.cs new file mode 100644 index 0000000..68f871b --- /dev/null +++ b/John Peter/Library/Repositories/PublisherRepository.cs @@ -0,0 +1,45 @@ +using Library.Context; +using Library.DTO; +using Library.Interfaces; +using Library.Models; +using Microsoft.EntityFrameworkCore; + +namespace Library.Repositories +{ + class PublisherRepository : IPublisherRepository + { + private readonly LibraryContext dbContext; + + public PublisherRepository(LibraryContext dbContext) + { + this.dbContext = dbContext; + } + + public async Task CreatePublisherAsync(Publisher publisher) + { + await dbContext.Publishers.AddAsync(publisher); + await dbContext.SaveChangesAsync(); + return publisher; + } + + public async Task GetPublisherAsync(int id) + { + return await dbContext.Publishers.FindAsync(id); + } + + public async Task> GetPublishersAsync() + { + return await dbContext.Publishers.ToListAsync(); + } + + public async Task> GetAuthorsByPublisherIdAsync(int publisherId) + { + var publisher = await dbContext.Publishers + .Include(p => p.Authors) + .ThenInclude(r => r.Books) + .FirstOrDefaultAsync(p => p.Id == publisherId); + + return publisher.Authors; + } + } +} diff --git a/John Peter/Library/appsettings.Development.json b/John Peter/Library/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/John Peter/Library/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/John Peter/Library/appsettings.json b/John Peter/Library/appsettings.json new file mode 100644 index 0000000..39884f8 --- /dev/null +++ b/John Peter/Library/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "LocalSQL": "secrets:ConnectionStrings:LocalSQL" + } +}