From 7d576121c87f622bb7373b0edecbedf5cc2b1bd6 Mon Sep 17 00:00:00 2001 From: marcchevaldonne Date: Wed, 13 Sep 2023 00:08:04 +0200 Subject: [PATCH] more stuff for TP2, including database --- Sources/JsonReader/AuthorJsonReader.cs | 31 ++++- Sources/JsonReader/BookJsonReader.cs | 29 +++- Sources/JsonReader/WorkJsonReader.cs | 20 ++- Sources/MyLibraryDB/MyLibraryContext.cs | 89 +++++++++++++ Sources/MyLibraryDB/MyLibraryDB.csproj | 21 +++ Sources/MyLibraryEntities/AuthorEntity.cs | 38 ++++++ Sources/MyLibraryEntities/BookEntity.cs | 23 ++++ .../MyLibraryEntities/ContributorEntity.cs | 16 +++ Sources/MyLibraryEntities/Languages.cs | 11 ++ Sources/MyLibraryEntities/LinkEntity.cs | 18 +++ .../MyLibraryEntities.csproj | 17 +++ Sources/MyLibraryEntities/StringEntity.cs | 17 +++ Sources/MyLibraryEntities/WorkEntity.cs | 23 ++++ .../MyLibraryManager/Entity2DtoExtensions.cs | 84 ++++++++++++ .../MyLibraryManager/MyLibraryManager.csproj | 16 +++ Sources/MyLibraryManager/MyLibraryMgr.cs | 124 +++++++++++++++++ Sources/OpenLibraryClient/OpenLibClientAPI.cs | 2 +- Sources/OpenLibraryWS_Wrapper.sln | 45 ++++++- .../OpenLibraryWrapper.csproj | 3 + Sources/OpenLibraryWrapper/Program.cs | 6 +- .../Properties/launchSettings.json | 8 ++ Sources/StubbedDB/Json2Data.cs | 115 ++++++++++++++++ Sources/StubbedDB/MyLibraryStubbedContext.cs | 37 ++++++ Sources/StubbedDB/StubbedDB.csproj | 14 ++ Sources/StubbedDTO/Stub.cs | 13 +- Sources/StubbedDTO/StubbedDTO.csproj | 10 +- Sources/StubbedDTO/authors/OL1846639A.json | 13 +- Sources/StubbedDTO/authors/OL274606A.json | 35 ++++- Sources/StubbedDTO/authors/OL3113900A.json | 1 + Sources/StubbedDTO/authors/OL3113922A.json | 12 +- Sources/StubbedDTO/authors/OL3980331A.json | 18 ++- Sources/StubbedDTO/authors/OL6982995A.json | 37 +++++- Sources/StubbedDTO/authors/OL7475792A.json | 16 ++- Sources/StubbedDTO/authors/OL7876839A.json | 1 + Sources/StubbedDTO/authors/OL79034A.json | 42 ++++++ Sources/StubbedDTO/authors/OL9956442A.json | 17 ++- Sources/StubbedDTO/books/OL25910297M.json | 25 +++- Sources/StubbedDTO/books/OL27258011M.json | 23 ++++ Sources/StubbedDTO/books/OL27989051M.json | 38 ++++++ Sources/StubbedDTO/books/OL28294024M.json | 1 + Sources/StubbedDTO/books/OL28639494M.json | 32 +++++ Sources/StubbedDTO/books/OL35698073M.json | 31 +++++ Sources/StubbedDTO/books/OL35698083M.json | 33 ++++- Sources/StubbedDTO/books/OL35699439M.json | 27 +++- Sources/StubbedDTO/books/OL38218739M.json | 32 ++++- Sources/StubbedDTO/books/OL38586212M.json | 29 +++- .../ratings/OL17334140W.ratings.json | 14 +- .../ratings/OL19213555W.ratings.json | 1 + .../ratings/OL19635836W.ratings.json | 15 ++- .../ratings/OL19800093W.ratings.json | 1 + .../ratings/OL19960903W.ratings.json | 15 ++- .../ratings/OL20078005W.ratings.json | 1 + .../ratings/OL20889233W.ratings.json | 1 + .../ratings/OL27962193W.ratings.json | 15 ++- .../ratings/OL28185064W.ratings.json | 14 +- .../StubbedDTO/ratings/OL893526W.ratings.json | 1 + Sources/StubbedDTO/works/OL17334140W.json | 23 +++- Sources/StubbedDTO/works/OL19213555W.json | 1 + Sources/StubbedDTO/works/OL19635836W.json | 25 +++- Sources/StubbedDTO/works/OL19800093W.json | 1 + Sources/StubbedDTO/works/OL19960903W.json | 23 +++- Sources/StubbedDTO/works/OL20078005W.json | 16 +++ Sources/StubbedDTO/works/OL20889233W.json | 1 + Sources/StubbedDTO/works/OL27962193W.json | 27 +++- Sources/StubbedDTO/works/OL28185064W.json | 27 +++- Sources/StubbedDTO/works/OL893526W.json | 1 + .../MyLibraryDB_Tests.csproj | 125 ++++++++++++++++++ Sources/Tests/MyLibraryDB_Tests/Program.cs | 19 +++ .../BookController_UT.cs | 2 +- .../OpenLibraryWrapper_UT.csproj | 10 +- .../OpenLibraryWrapper_UT/Usings.cs | 0 71 files changed, 1612 insertions(+), 60 deletions(-) create mode 100644 Sources/MyLibraryDB/MyLibraryContext.cs create mode 100644 Sources/MyLibraryDB/MyLibraryDB.csproj create mode 100644 Sources/MyLibraryEntities/AuthorEntity.cs create mode 100644 Sources/MyLibraryEntities/BookEntity.cs create mode 100644 Sources/MyLibraryEntities/ContributorEntity.cs create mode 100644 Sources/MyLibraryEntities/Languages.cs create mode 100644 Sources/MyLibraryEntities/LinkEntity.cs create mode 100644 Sources/MyLibraryEntities/MyLibraryEntities.csproj create mode 100644 Sources/MyLibraryEntities/StringEntity.cs create mode 100644 Sources/MyLibraryEntities/WorkEntity.cs create mode 100644 Sources/MyLibraryManager/Entity2DtoExtensions.cs create mode 100644 Sources/MyLibraryManager/MyLibraryManager.csproj create mode 100644 Sources/MyLibraryManager/MyLibraryMgr.cs create mode 100644 Sources/StubbedDB/Json2Data.cs create mode 100644 Sources/StubbedDB/MyLibraryStubbedContext.cs create mode 100644 Sources/StubbedDB/StubbedDB.csproj create mode 100644 Sources/StubbedDTO/authors/OL3113900A.json create mode 100644 Sources/StubbedDTO/authors/OL7876839A.json create mode 100644 Sources/StubbedDTO/authors/OL79034A.json create mode 100644 Sources/StubbedDTO/books/OL27258011M.json create mode 100644 Sources/StubbedDTO/books/OL27989051M.json create mode 100644 Sources/StubbedDTO/books/OL28294024M.json create mode 100644 Sources/StubbedDTO/books/OL28639494M.json create mode 100644 Sources/StubbedDTO/books/OL35698073M.json create mode 100644 Sources/StubbedDTO/ratings/OL19213555W.ratings.json create mode 100644 Sources/StubbedDTO/ratings/OL19800093W.ratings.json create mode 100644 Sources/StubbedDTO/ratings/OL20078005W.ratings.json create mode 100644 Sources/StubbedDTO/ratings/OL20889233W.ratings.json create mode 100644 Sources/StubbedDTO/ratings/OL893526W.ratings.json create mode 100644 Sources/StubbedDTO/works/OL19213555W.json create mode 100644 Sources/StubbedDTO/works/OL19800093W.json create mode 100644 Sources/StubbedDTO/works/OL20078005W.json create mode 100644 Sources/StubbedDTO/works/OL20889233W.json create mode 100644 Sources/StubbedDTO/works/OL893526W.json create mode 100644 Sources/Tests/MyLibraryDB_Tests/MyLibraryDB_Tests.csproj create mode 100644 Sources/Tests/MyLibraryDB_Tests/Program.cs rename Sources/{ => Tests}/OpenLibraryWrapper_UT/BookController_UT.cs (98%) rename Sources/{ => Tests}/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj (71%) rename Sources/{ => Tests}/OpenLibraryWrapper_UT/Usings.cs (100%) diff --git a/Sources/JsonReader/AuthorJsonReader.cs b/Sources/JsonReader/AuthorJsonReader.cs index 39de3ec..0ae07db 100644 --- a/Sources/JsonReader/AuthorJsonReader.cs +++ b/Sources/JsonReader/AuthorJsonReader.cs @@ -29,14 +29,41 @@ namespace JsonReader Id = (string)o["key"], Name = (string)o["name"], Bio = bioTokenAsString, - BirthDate = o.TryGetValue("birth_date", out JToken? bd) ? DateTime.ParseExact((string)bd, "d MMMM yyyy", CultureInfo.InvariantCulture) : null, - DeathDate = o.TryGetValue("death_date", out JToken? dd) ? DateTime.ParseExact((string)dd, "d MMMM yyyy", CultureInfo.InvariantCulture) : null, + BirthDate = o.TryGetValue("birth_date", out JToken? bd) ? ReadDate((string)o["birth_date"]) : null, + DeathDate = o.TryGetValue("death_date", out JToken? dd) ? ReadDate((string)o["death_date"]) : null, Links = o.TryGetValue("links", out JToken? links) ? links.Select(l => new LinkDTO { Title = (string)l["title"], Url = (string)l["url"] }).ToList() : new List(), AlternateNames = o.TryGetValue("alternate_names", out JToken? altNames) ? altNames.Select(alt => (string)alt).ToList() : new List() }; return author; } + public static DateTime? ReadDate(string dateInJson) + { + if(dateInJson == null) return null; + + List> pubDateFormat =new List>() + { + Tuple.Create("d MMMM yyyy", CultureInfo.GetCultureInfo("fr-FR")), + Tuple.Create("d MMMM yyyy", CultureInfo.InvariantCulture), + Tuple.Create("MMM dd, yyyy", CultureInfo.InvariantCulture) + }; + + DateTime? publishDate = null; + foreach(var format in pubDateFormat) + { + if(DateTime.TryParseExact(dateInJson, format.Item1, format.Item2, DateTimeStyles.None, out DateTime readDate)) + { + publishDate = readDate; + break; + } + } + if(!publishDate.HasValue && int.TryParse(dateInJson, out int year)) + { + publishDate = new DateTime(year, 12, 31); + } + return publishDate; + } + public static Tuple> GetAuthorsByName(string json) { JObject o = JObject.Parse(json); diff --git a/Sources/JsonReader/BookJsonReader.cs b/Sources/JsonReader/BookJsonReader.cs index a752e5a..ab2a87e 100644 --- a/Sources/JsonReader/BookJsonReader.cs +++ b/Sources/JsonReader/BookJsonReader.cs @@ -20,20 +20,35 @@ public static class BookJsonReader JObject o = JObject.Parse(json); var l = o["languages"]?.FirstOrDefault(""); Languages lang = l != null ? languages[(string)l["key"]] : Languages.Unknown; - Tuple pubDateFormat = lang switch - { - Languages.French => Tuple.Create("d MMMM yyyy", CultureInfo.GetCultureInfo("fr-FR")), - Languages.Unknown => Tuple.Create("MMM dd, yyyy", CultureInfo.InvariantCulture) - }; + //List> pubDateFormat =new List>() + //{ + // Tuple.Create("d MMMM yyyy", CultureInfo.GetCultureInfo("fr-FR")), + // Tuple.Create("MMM dd, yyyy", CultureInfo.InvariantCulture) + //}; + + //DateTime? publishDate = null; + //foreach(var format in pubDateFormat) + //{ + // if(DateTime.TryParseExact((string)o["publish_date"], format.Item1, format.Item2, DateTimeStyles.None, out DateTime readDate)) + // { + // publishDate = readDate; + // break; + // } + //} + //if(!publishDate.HasValue) + //{ + // publishDate = new DateTime((int)o["publish_date"], 12, 31); + //} + DateTime? publishDate = AuthorJsonReader.ReadDate((string)o["publish_date"]); BookDTO book = new BookDTO { Id = (string)o["key"], Title = (string)o["title"], Publishers = o["publishers"].Select(p => (string)p).ToList(), - PublishDate = DateTime.TryParseExact((string)o["publish_date"], pubDateFormat.Item1, pubDateFormat.Item2, DateTimeStyles.None, out DateTime date) ? date : new DateTime((int)o["publish_date"], 12, 31), + PublishDate = publishDate.GetValueOrDefault(DateTime.Now), ISBN13 = (string)o["isbn_13"][0], - NbPages = (int)o["number_of_pages"], + NbPages = o["number_of_pages"] != null ? (int)o["number_of_pages"] : -1, Language = lang, Format = o.TryGetValue("physical_format", out JToken? f) ? (string)f : null, Works = o["works"].Select(w => new WorkDTO { Id = (string)w["key"] }).ToList(), diff --git a/Sources/JsonReader/WorkJsonReader.cs b/Sources/JsonReader/WorkJsonReader.cs index 86cbbd6..387dbbd 100644 --- a/Sources/JsonReader/WorkJsonReader.cs +++ b/Sources/JsonReader/WorkJsonReader.cs @@ -23,12 +23,28 @@ namespace JsonReader ratingsDto.Count = (int)r["summary"]["count"]; } + string description = null; + if(o.TryGetValue("description", out JToken? descr)) + { + if(descr.Type == JTokenType.String) + { + description = (string)descr; + } + else + { + if (descr["value"].Type == JTokenType.String) + { + description = (string)descr["value"]; + } + } + } + WorkDTO work = new WorkDTO { Id = (string)o["key"], Title = (string)o["title"], - Authors = o["authors"].Select(a => new AuthorDTO { Id = (string)a["author"]["key"] }).ToList(), - Description = o.TryGetValue("description", out JToken? descr) ? (string)descr : null, + Authors = o.TryGetValue("authors", out JToken? authors) ? authors.Select(a => new AuthorDTO { Id = (string)a["author"]["key"] }).ToList() : new List(), + Description = description, Subjects = o.TryGetValue("subjects", out JToken? subjects) ? subjects.Select(s => (string)s).ToList() : new List(), Ratings = ratingsDto }; diff --git a/Sources/MyLibraryDB/MyLibraryContext.cs b/Sources/MyLibraryDB/MyLibraryContext.cs new file mode 100644 index 0000000..177c2ff --- /dev/null +++ b/Sources/MyLibraryDB/MyLibraryContext.cs @@ -0,0 +1,89 @@ +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.Extensions.Options; +using MyLibraryEntities; + +namespace MyLibraryDB; + +public class MyLibraryContext : DbContext +{ + public DbSet Authors { get; set; } + public DbSet Books { get; set; } + public DbSet Works { get; set; } + + public MyLibraryContext() + { } + + public MyLibraryContext(DbContextOptions options) + : base(options) + { } + + private static DbContextOptions InitPlaftormDB(string dbPlatformPath) + { + var options = new DbContextOptionsBuilder() + .UseMySql($"{dbPlatformPath}", new MySqlServerVersion(new Version(10, 11, 1))) + .Options; + + return options; + } + + public MyLibraryContext(string dbPlatformPath) + : this(InitPlaftormDB(dbPlatformPath)) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseSqlite($"Data Source=MylibraryDB.db"); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .Property(e => e.AlternateNames) + .HasConversion( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null), + new ValueComparer>( + (c1, c2) => c1.SequenceEqual(c2), + c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), + c => (ICollection)c.ToList())); + + modelBuilder.Entity() + .Property(e => e.Subjects) + .HasConversion( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null), + new ValueComparer>( + (c1, c2) => c1.SequenceEqual(c2), + c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), + c => (ICollection)c.ToList())); + + modelBuilder.Entity() + .Property(e => e.Publishers) + .HasConversion( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null), + new ValueComparer>( + (c1, c2) => c1.SequenceEqual(c2), + c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), + c => (ICollection)c.ToList())); + + modelBuilder.Entity() + .Property(e => e.Series) + .HasConversion( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null), + new ValueComparer>( + (c1, c2) => c1.SequenceEqual(c2), + c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), + c => (ICollection)c.ToList())); + } +} + diff --git a/Sources/MyLibraryDB/MyLibraryDB.csproj b/Sources/MyLibraryDB/MyLibraryDB.csproj new file mode 100644 index 0000000..1c7f9a0 --- /dev/null +++ b/Sources/MyLibraryDB/MyLibraryDB.csproj @@ -0,0 +1,21 @@ + + + + net7.0 + enable + enable + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/Sources/MyLibraryEntities/AuthorEntity.cs b/Sources/MyLibraryEntities/AuthorEntity.cs new file mode 100644 index 0000000..d368927 --- /dev/null +++ b/Sources/MyLibraryEntities/AuthorEntity.cs @@ -0,0 +1,38 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace MyLibraryEntities +{ + [Table("Authors")] + public class AuthorEntity + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public string Id { get; set; } + + [Required] + public string Name { get; set; } + + public string? Bio { get; set; } + + public ICollection? AlternateNames { get; set; } = new List(); + + public string SmallImage { get; set; } + public string MediumImage { get; set; } + public string LargeImage { get; set; } + + public List Links { get; set; } + + [Column("BirthDate", TypeName = "date")] + public DateTime? BirthDate { get; set; } + + [Column("DeathDate", TypeName = "date")] + public DateTime? DeathDate { get; set; } + + public List Works { get; } = new (); + public List Books { get; } = new (); + + } +} \ No newline at end of file diff --git a/Sources/MyLibraryEntities/BookEntity.cs b/Sources/MyLibraryEntities/BookEntity.cs new file mode 100644 index 0000000..7467f59 --- /dev/null +++ b/Sources/MyLibraryEntities/BookEntity.cs @@ -0,0 +1,23 @@ +using System; +namespace MyLibraryEntities +{ + public class BookEntity + { + public string Id { get; set; } + public string Title { get; set; } + public ICollection Publishers { get; set; } = new List(); + public DateTime PublishDate { get; set; } + public string ISBN13 { get; set; } + public ICollection Series { get; set; } = new List(); + public int NbPages { get; set; } + public string? Format { get; set; } + public Languages Language { get; set; } + public List Contributors { get; set; } + public List Works { get; } = new (); + public List Authors { get; } = new (); + public string SmallImage { get; set; } + public string MediumImage { get; set; } + public string LargeImage { get; set; } + } +} + diff --git a/Sources/MyLibraryEntities/ContributorEntity.cs b/Sources/MyLibraryEntities/ContributorEntity.cs new file mode 100644 index 0000000..49a26e5 --- /dev/null +++ b/Sources/MyLibraryEntities/ContributorEntity.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace MyLibraryEntities; + +public class ContributorEntity +{ + public string Id { get; set; } + public string Name { get; set; } + public string Role { get; set; } + + [ForeignKey("BookId")] + public BookEntity Book { get; set; } + + public string BookId { get; set; } +} + diff --git a/Sources/MyLibraryEntities/Languages.cs b/Sources/MyLibraryEntities/Languages.cs new file mode 100644 index 0000000..31eadf0 --- /dev/null +++ b/Sources/MyLibraryEntities/Languages.cs @@ -0,0 +1,11 @@ +using System; +namespace MyLibraryEntities +{ + public enum Languages + { + Unknown, + French, + English + } +} + diff --git a/Sources/MyLibraryEntities/LinkEntity.cs b/Sources/MyLibraryEntities/LinkEntity.cs new file mode 100644 index 0000000..01728b5 --- /dev/null +++ b/Sources/MyLibraryEntities/LinkEntity.cs @@ -0,0 +1,18 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; + +namespace MyLibraryEntities +{ + public class LinkEntity + { + public string Id { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + [ForeignKey("AuthorId")] + public AuthorEntity Author { get; set; } + + public string AuthorId { get; set; } + } +} + diff --git a/Sources/MyLibraryEntities/MyLibraryEntities.csproj b/Sources/MyLibraryEntities/MyLibraryEntities.csproj new file mode 100644 index 0000000..1c94fa4 --- /dev/null +++ b/Sources/MyLibraryEntities/MyLibraryEntities.csproj @@ -0,0 +1,17 @@ + + + + net7.0 + enable + enable + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + diff --git a/Sources/MyLibraryEntities/StringEntity.cs b/Sources/MyLibraryEntities/StringEntity.cs new file mode 100644 index 0000000..76f04df --- /dev/null +++ b/Sources/MyLibraryEntities/StringEntity.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; + +namespace MyLibraryEntities +{ + public class StringEntity + { + public string Id { get; set; } + public string Value { get; set; } + + [ForeignKey("AuthorId")] + public AuthorEntity Author { get; set; } + + public string AuthorId { get; set; } + } +} + diff --git a/Sources/MyLibraryEntities/WorkEntity.cs b/Sources/MyLibraryEntities/WorkEntity.cs new file mode 100644 index 0000000..569b196 --- /dev/null +++ b/Sources/MyLibraryEntities/WorkEntity.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace MyLibraryEntities +{ + public class WorkEntity + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public string Id { get; set; } + public string? Description { get; set; } + [Required] + public string Title { get; set; } + public ICollection? Subjects { get; set; } = new List(); + public List Authors { get; } = new (); + public List Books { get; } = new (); + //public RatingsEntity Ratings { get; set; } + public float? RatingsAverage { get; set; } + public int? RatingsCount { get; set; } + } +} + diff --git a/Sources/MyLibraryManager/Entity2DtoExtensions.cs b/Sources/MyLibraryManager/Entity2DtoExtensions.cs new file mode 100644 index 0000000..65fc08a --- /dev/null +++ b/Sources/MyLibraryManager/Entity2DtoExtensions.cs @@ -0,0 +1,84 @@ +using System; +using LibraryDTO; +using MyLibraryEntities; + +namespace MyLibraryManager +{ + public static class Entity2DtoExtensions + { + public static LibraryDTO.Languages ToDto(this MyLibraryEntities.Languages lang) + { + return Enum.GetValues().SingleOrDefault(v => + Enum.GetName(v) == Enum.GetName(lang)); + } + + public static AuthorDTO ToDto(this AuthorEntity entity) + { + return new AuthorDTO + { + Id = entity.Id, + AlternateNames = entity.AlternateNames != null ? new List(entity.AlternateNames.Where(an => an != null)) : new List(), + Bio = entity.Bio, + BirthDate = entity.BirthDate, + DeathDate = entity.DeathDate, + Name = entity.Name, + Links = entity.Links != null ? new List(entity.Links.Where(l => l != null).ToDtos()) : new List(), + }; + } + + public static IEnumerable ToDtos(this IEnumerable entities) + => entities.Select(a => a.ToDto()); + + public static LinkDTO ToDto(this LinkEntity entity) + => new LinkDTO { Title = entity.Title, Url = entity.Url }; + + public static IEnumerable ToDtos(this IEnumerable entities) + => entities.Select(l => l.ToDto()); + + public static WorkDTO ToDto(this WorkEntity entity) + { + return new WorkDTO + { + Id = entity.Id, + Description = entity.Description, + Ratings = entity.RatingsAverage != null ? + new RatingsDTO { Average = entity.RatingsAverage.Value, Count = entity.RatingsCount.Value } : null, + Subjects = new List(entity.Subjects), + Title = entity.Title, + Authors = new List(entity.Authors.ToDtos()), + }; + } + + public static IEnumerable ToDtos(this IEnumerable entities) + => entities.Select(w => w.ToDto()); + + public static ContributorDTO ToDto(this ContributorEntity entity) + => new ContributorDTO { Name = entity.Name, Role = entity.Role }; + + public static IEnumerable ToDtos(this IEnumerable entities) + => entities.Select(l => l.ToDto()); + + public static BookDTO ToDto(this BookEntity entity) + { + return new BookDTO + { + Id = entity.Id, + Authors = entity.Authors != null ? new List(entity.Authors.ToDtos()) : null, + Contributors = entity.Contributors != null ? new List(entity.Contributors.ToDtos()) : null, + Format = entity.Format, + ISBN13 = entity.ISBN13, + Language = entity.Language.ToDto(), + NbPages = entity.NbPages, + PublishDate = entity.PublishDate, + Publishers = new List(entity.Publishers), + Series = new List(entity.Series), + Title = entity.Title, + Works = new List(entity.Works.ToDtos()), + }; + } + + public static IEnumerable ToDtos(this IEnumerable entities) + => entities.Select(b => b.ToDto()); + } +} + diff --git a/Sources/MyLibraryManager/MyLibraryManager.csproj b/Sources/MyLibraryManager/MyLibraryManager.csproj new file mode 100644 index 0000000..1fc4251 --- /dev/null +++ b/Sources/MyLibraryManager/MyLibraryManager.csproj @@ -0,0 +1,16 @@ + + + + net7.0 + enable + enable + + + + + + + + + + diff --git a/Sources/MyLibraryManager/MyLibraryMgr.cs b/Sources/MyLibraryManager/MyLibraryMgr.cs new file mode 100644 index 0000000..cd0aee6 --- /dev/null +++ b/Sources/MyLibraryManager/MyLibraryMgr.cs @@ -0,0 +1,124 @@ +using System.Data.SqlTypes; +using DtoAbstractLayer; +using LibraryDTO; +using Microsoft.EntityFrameworkCore; +using MyLibraryDB; +using MyLibraryEntities; +using StubbedDB; + +namespace MyLibraryManager; + +public class MyLibraryMgr : IDtoManager +{ + protected MyLibraryContext Context => _dbContext; + private readonly MyLibraryContext _dbContext; + + public MyLibraryMgr() : this(new MyLibraryStubbedContext()) + { + } + + public MyLibraryMgr(string dbPlatformPath) + : this(new MyLibraryStubbedContext(dbPlatformPath)) + { + Context.Database.EnsureCreated(); + } + + internal MyLibraryMgr(MyLibraryStubbedContext context) + { + _dbContext = context; + } + + public async Task GetAuthorById(string id) + { + var author = await Context.Authors.SingleOrDefaultAsync(a => a.Id.ToUpper().Contains(id.ToUpper())); + return author.ToDto(); + } + + public async Task>> GetAuthorsByName(string substring, int index, int count, string sort = "") + { + var authors = Context.Authors.Where(a => a.Name.ToUpper().Contains(substring.ToUpper())); + switch(sort) + { + case "name": + authors = authors.OrderBy(a => a.Name); + break; + case "name_reverse": + authors = authors.OrderByDescending(a => a.Name); + break; + default: + break; + } + + long nb = await authors.CountAsync(); + + return await Task.FromResult(Tuple.Create(nb, authors.Skip(index*count).Take(count).ToDtos())); + } + + public async Task GetBookById(string id) + { + var book = await Context.Books.SingleOrDefaultAsync(b => b.Id.ToUpper().Contains(id.ToUpper())); + return book.ToDto(); + } + + public async Task GetBookByISBN(string isbn) + { + var book = await Context.Books.SingleOrDefaultAsync(b => b.ISBN13 == isbn); + return book?.ToDto(); + } + + Func predicateAuthorName =(a, s) => a.Name.ToUpper().Contains(s.ToUpper()); + //|| a.AlternateNames.Count(an => an.ToUpper().Contains(s.ToUpper())) > 0; + + public async Task>> GetBooksByAuthor(string author, int index, int count, string sort = "") + { + var books2 = Context.Books.SelectMany(b => b.Authors, (b, a) => new {Book = b, AuthorName = a.Name }); + var books3 = books2.Where(ba => ba.AuthorName.ToUpper().Contains(author.ToUpper())); + var books4 = books3.Select(ba => ba.Book).Distinct(); +// var books = Context.Books.Where(b => b.Authors.Where(a => a.Name.ToUpper().Contains(author.ToUpper())).Count() > 0);// Exists(a => predicateAuthorName(a, author))); + + return await SortAndFilterBooks(books4, index, count, sort); + } + + private async Task>> SortAndFilterBooks(IQueryable? books, int index, int count, string sort = "") + { + switch(sort) + { + case "title": + books = books.OrderBy(a => a.Title); + break; + case "title_reverse": + books = books.OrderByDescending(a => a.Title); + break; + case "new": + books = books.OrderByDescending(a => a.PublishDate); + break; + case "old": + books = books.OrderBy(a => a.PublishDate); + break; + default: + break; + } + + long nb = await books.CountAsync(); + + return await Task.FromResult(Tuple.Create(nb, books.Skip(index*count).Take(count).ToDtos())); + } + + public async Task>> GetBooksByAuthorId(string authorId, int index, int count, string sort = "") + { + //var books = Context.Books.Where(b => b.Authors.Count(a => a.Id == authorId) > 0); + var books2 = Context.Books.SelectMany(b => b.Authors, (b, a) => new {Book = b, AuthorId = a.Id }); + var books3 = books2.Where(ba => ba.AuthorId.ToUpper().Contains(authorId.ToUpper())); + var books4 = books3.Select(ba => ba.Book).Distinct(); + + return await SortAndFilterBooks(books4, index, count, sort); + } + + public async Task>> GetBooksByTitle(string title, int index, int count, string sort = "") + { + var books = Context.Books.Where(b => b.Title.ToUpper().Contains(title.ToUpper())); + + return await SortAndFilterBooks(books, index, count, sort); + } +} + diff --git a/Sources/OpenLibraryClient/OpenLibClientAPI.cs b/Sources/OpenLibraryClient/OpenLibClientAPI.cs index eb4a493..2d58a94 100644 --- a/Sources/OpenLibraryClient/OpenLibClientAPI.cs +++ b/Sources/OpenLibraryClient/OpenLibClientAPI.cs @@ -86,7 +86,7 @@ public class OpenLibClientAPI : IDtoManager public async Task>> GetBooksByAuthorId(string authorId, int index, int count, string sort = "") { string searchedString = authorId.Trim().Replace(" ", "+"); - string route = $"{BasePath}{SearchAuthorPrefix}{searchedString}" + string route = $"{BasePath}{SearchBookByAuthorPrefix}{searchedString}" .AddPagination(index, count) .AddSort(sort); return await GetElement>>(route, json => BookJsonReader.GetBooksByAuthor(json)); diff --git a/Sources/OpenLibraryWS_Wrapper.sln b/Sources/OpenLibraryWS_Wrapper.sln index cc2c738..bce44b7 100644 --- a/Sources/OpenLibraryWS_Wrapper.sln +++ b/Sources/OpenLibraryWS_Wrapper.sln @@ -7,8 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenLibraryWrapper", "OpenL EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{0D260EDC-4F17-4BA4-9306-B6FEC6E5E394}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenLibraryWrapper_UT", "OpenLibraryWrapper_UT\OpenLibraryWrapper_UT.csproj", "{B12BEDA7-EC41-417B-9C28-113A8ED87F35}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryDTO", "LibraryDTO\LibraryDTO.csproj", "{F59D46BA-6734-464E-8AC4-759BEFB87973}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StubbedDTO", "StubbedDTO\StubbedDTO.csproj", "{3CB3D741-DF5C-4C4A-82C2-5BFC212211AD}" @@ -21,6 +19,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenLibraryClient", "OpenLibraryClient\OpenLibraryClient.csproj", "{3A429457-D882-44E3-B65E-107554C2E91F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLibraryEntities", "MyLibraryEntities\MyLibraryEntities.csproj", "{4E54987D-1790-49F9-9027-700A894B2BD9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLibraryDB", "MyLibraryDB\MyLibraryDB.csproj", "{0ED941B5-E5C9-4A54-BAC8-4F7FB44F2947}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StubbedDB", "StubbedDB\StubbedDB.csproj", "{951F7FDA-FA71-46CA-9DDE-4DF0AAAC9DA9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenLibraryWrapper_UT", "Tests\OpenLibraryWrapper_UT\OpenLibraryWrapper_UT.csproj", "{7FA060D6-3490-4FE3-808F-06370DF8A3B9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLibraryDB_Tests", "Tests\MyLibraryDB_Tests\MyLibraryDB_Tests.csproj", "{A3137A3B-7BA6-4AC8-80C6-653F50079D55}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyLibraryManager", "MyLibraryManager\MyLibraryManager.csproj", "{DA2B0562-31DA-4059-B402-404EC31874B6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,10 +41,6 @@ Global {EF0DED5C-7559-4D43-A30B-AE916FCDA078}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF0DED5C-7559-4D43-A30B-AE916FCDA078}.Release|Any CPU.ActiveCfg = Release|Any CPU {EF0DED5C-7559-4D43-A30B-AE916FCDA078}.Release|Any CPU.Build.0 = Release|Any CPU - {B12BEDA7-EC41-417B-9C28-113A8ED87F35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B12BEDA7-EC41-417B-9C28-113A8ED87F35}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B12BEDA7-EC41-417B-9C28-113A8ED87F35}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B12BEDA7-EC41-417B-9C28-113A8ED87F35}.Release|Any CPU.Build.0 = Release|Any CPU {F59D46BA-6734-464E-8AC4-759BEFB87973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F59D46BA-6734-464E-8AC4-759BEFB87973}.Debug|Any CPU.Build.0 = Debug|Any CPU {F59D46BA-6734-464E-8AC4-759BEFB87973}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -55,6 +61,30 @@ Global {3A429457-D882-44E3-B65E-107554C2E91F}.Debug|Any CPU.Build.0 = Debug|Any CPU {3A429457-D882-44E3-B65E-107554C2E91F}.Release|Any CPU.ActiveCfg = Release|Any CPU {3A429457-D882-44E3-B65E-107554C2E91F}.Release|Any CPU.Build.0 = Release|Any CPU + {4E54987D-1790-49F9-9027-700A894B2BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E54987D-1790-49F9-9027-700A894B2BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E54987D-1790-49F9-9027-700A894B2BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E54987D-1790-49F9-9027-700A894B2BD9}.Release|Any CPU.Build.0 = Release|Any CPU + {0ED941B5-E5C9-4A54-BAC8-4F7FB44F2947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0ED941B5-E5C9-4A54-BAC8-4F7FB44F2947}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0ED941B5-E5C9-4A54-BAC8-4F7FB44F2947}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0ED941B5-E5C9-4A54-BAC8-4F7FB44F2947}.Release|Any CPU.Build.0 = Release|Any CPU + {951F7FDA-FA71-46CA-9DDE-4DF0AAAC9DA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {951F7FDA-FA71-46CA-9DDE-4DF0AAAC9DA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {951F7FDA-FA71-46CA-9DDE-4DF0AAAC9DA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {951F7FDA-FA71-46CA-9DDE-4DF0AAAC9DA9}.Release|Any CPU.Build.0 = Release|Any CPU + {7FA060D6-3490-4FE3-808F-06370DF8A3B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FA060D6-3490-4FE3-808F-06370DF8A3B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FA060D6-3490-4FE3-808F-06370DF8A3B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FA060D6-3490-4FE3-808F-06370DF8A3B9}.Release|Any CPU.Build.0 = Release|Any CPU + {A3137A3B-7BA6-4AC8-80C6-653F50079D55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3137A3B-7BA6-4AC8-80C6-653F50079D55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3137A3B-7BA6-4AC8-80C6-653F50079D55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3137A3B-7BA6-4AC8-80C6-653F50079D55}.Release|Any CPU.Build.0 = Release|Any CPU + {DA2B0562-31DA-4059-B402-404EC31874B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA2B0562-31DA-4059-B402-404EC31874B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA2B0562-31DA-4059-B402-404EC31874B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA2B0562-31DA-4059-B402-404EC31874B6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -63,6 +93,7 @@ Global SolutionGuid = {2E40DC1C-BE57-48E8-B7C2-B9CFF589DB5B} EndGlobalSection GlobalSection(NestedProjects) = preSolution - {B12BEDA7-EC41-417B-9C28-113A8ED87F35} = {0D260EDC-4F17-4BA4-9306-B6FEC6E5E394} + {7FA060D6-3490-4FE3-808F-06370DF8A3B9} = {0D260EDC-4F17-4BA4-9306-B6FEC6E5E394} + {A3137A3B-7BA6-4AC8-80C6-653F50079D55} = {0D260EDC-4F17-4BA4-9306-B6FEC6E5E394} EndGlobalSection EndGlobal diff --git a/Sources/OpenLibraryWrapper/OpenLibraryWrapper.csproj b/Sources/OpenLibraryWrapper/OpenLibraryWrapper.csproj index 897f6c5..a235a9d 100644 --- a/Sources/OpenLibraryWrapper/OpenLibraryWrapper.csproj +++ b/Sources/OpenLibraryWrapper/OpenLibraryWrapper.csproj @@ -31,6 +31,9 @@ + + + diff --git a/Sources/OpenLibraryWrapper/Program.cs b/Sources/OpenLibraryWrapper/Program.cs index ce0df32..bdc5ebe 100644 --- a/Sources/OpenLibraryWrapper/Program.cs +++ b/Sources/OpenLibraryWrapper/Program.cs @@ -2,6 +2,7 @@ using DtoAbstractLayer; using LibraryDTO; using Microsoft.OpenApi.Models; +using MyLibraryManager; using OpenLibraryClient; using StubbedDTO; @@ -9,7 +10,7 @@ var builder = WebApplication.CreateBuilder(args); // Add services to the container. -builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); @@ -22,5 +23,4 @@ app.UseAuthorization(); app.MapControllers(); -app.Run(); - +app.Run(); \ No newline at end of file diff --git a/Sources/OpenLibraryWrapper/Properties/launchSettings.json b/Sources/OpenLibraryWrapper/Properties/launchSettings.json index 576d3d7..e4b2966 100644 --- a/Sources/OpenLibraryWrapper/Properties/launchSettings.json +++ b/Sources/OpenLibraryWrapper/Properties/launchSettings.json @@ -36,6 +36,14 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "OpenLibraryWrapper": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:34198;http://localhost:46179", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } } } } \ No newline at end of file diff --git a/Sources/StubbedDB/Json2Data.cs b/Sources/StubbedDB/Json2Data.cs new file mode 100644 index 0000000..adecba0 --- /dev/null +++ b/Sources/StubbedDB/Json2Data.cs @@ -0,0 +1,115 @@ +using System; +using StubbedDTO; +using System.Linq; +using LibraryDTO; +using MyLibraryEntities; + +namespace StubbedDB +{ + public static class Json2Data + { + public static MyLibraryEntities.Languages ToEntity(this LibraryDTO.Languages lang) + { + return Enum.GetValues().SingleOrDefault(v => + Enum.GetName(v) == Enum.GetName(lang)); + } + + public static IEnumerable ToAuthorsData() + { + var temp = Stub.Authors.Select(a => + new AuthorEntity + { + Id = a.Id, + Name = a.Name, + Bio = a.Bio, + BirthDate = a.BirthDate, + DeathDate = a.DeathDate, + SmallImage = $"https://covers.openlibrary.org/a/olid/{a.Id.Substring(a.Id.LastIndexOf("/"))}-S.jpg", + MediumImage = $"https://covers.openlibrary.org/a/olid/{a.Id.Substring(a.Id.LastIndexOf("/"))}-M.jpg", + LargeImage = $"https://covers.openlibrary.org/a/olid/{a.Id.Substring(a.Id.LastIndexOf("/"))}-L.jpg", + AlternateNames = a.AlternateNames + }); + return temp; + } + + public static IEnumerable ToLinksData() + { + return Stub.Authors.Where(a => a.Links != null && a.Links.Count > 0) + .SelectMany(a => a.Links, (author,link) => + new + { + Id = $"{author.Id.Substring(author.Id.LastIndexOf("/"))}-{author.Links.IndexOf(link)}", + Title = link.Title, + Url = link.Url, + AuthorId = author.Id + }); + } + + public static IEnumerable ToWorksData() + { + return Stub.Works.Select(w => + new + { + Id = w.Id, + Description = w.Description, + RatingsAverage = w.Ratings?.Average, + RatingsCount = w.Ratings?.Count, + Title = w.Title, + Subjects = w.Subjects + }); + } + + public static IEnumerable ToAuthorsWorksData() + { + return Stub.Works.SelectMany(w => w.Authors, + (w, a) => new { AuthorsId = a.Id, WorksId = w.Id }); + } + + public static IEnumerable ToBooksData() + { + return Stub.Books.Select(b => + new + { + Publishers = b.Publishers, + Title = b.Title, + NbPages = b.NbPages, + ISBN13 = b.ISBN13, + Language = b.Language.ToEntity(), + PublishDate = b.PublishDate, + Id = b.Id, + Series = b.Series, + Format = b.Format, + SmallImage = $"https://covers.openlibrary.org/b/isbn/{b.ISBN13}-S.jpg", + MediumImage = $"https://covers.openlibrary.org/b/isbn/{b.ISBN13}-M.jpg", + LargeImage = $"https://covers.openlibrary.org/b/isbn/{b.ISBN13}-l.jpg" + }); + } + + public static IEnumerable ToBooksWorksData() + { + return Stub.Books.SelectMany(b => b.Works, + (b, w) => new {BooksId = b.Id, WorksId = w.Id}); + } + + public static IEnumerable ToContributorsData() + { + return Stub.Books.SelectMany( b => b.Contributors, + (b, c) => new + { + Id = $"{b.Id}-c{b.Contributors.IndexOf(c)}", + BookId = b.Id, + Name = c.Name, + Role = c.Role + }); + } + + public static IEnumerable ToAuthorsBooksData() + { + var proj = (BookDTO b, AuthorDTO a) => new { AuthorsId = a.Id, BooksId = b.Id}; + var collec1 = Stub.Books.SelectMany(b => b.Authors, proj); + var collec2 = Stub.Books.SelectMany(b => b.Works.SelectMany(w => w.Authors), proj); + return collec1.Union(collec2); + } + } +} + diff --git a/Sources/StubbedDB/MyLibraryStubbedContext.cs b/Sources/StubbedDB/MyLibraryStubbedContext.cs new file mode 100644 index 0000000..acac1bc --- /dev/null +++ b/Sources/StubbedDB/MyLibraryStubbedContext.cs @@ -0,0 +1,37 @@ +using Microsoft.EntityFrameworkCore; +using MyLibraryDB; +using MyLibraryEntities; +using static System.Reflection.Metadata.BlobBuilder; + +namespace StubbedDB; + +public class MyLibraryStubbedContext : MyLibraryContext +{ + public MyLibraryStubbedContext() : base() { } + + public MyLibraryStubbedContext(string dbPlatformPath) + :base(dbPlatformPath) + { } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.Entity().HasData( + Json2Data.ToAuthorsData()); + modelBuilder.Entity().HasData( + Json2Data.ToLinksData()); + modelBuilder.Entity().HasData( + Json2Data.ToWorksData()); + modelBuilder.Entity("AuthorEntityWorkEntity").HasData( + Json2Data.ToAuthorsWorksData()); + modelBuilder.Entity().HasData( + Json2Data.ToBooksData()); + modelBuilder.Entity("BookEntityWorkEntity").HasData( + Json2Data.ToBooksWorksData()); + modelBuilder.Entity().HasData( + Json2Data.ToContributorsData()); + modelBuilder.Entity("AuthorEntityBookEntity").HasData( + Json2Data.ToAuthorsBooksData()); + } +} + diff --git a/Sources/StubbedDB/StubbedDB.csproj b/Sources/StubbedDB/StubbedDB.csproj new file mode 100644 index 0000000..d62d5fe --- /dev/null +++ b/Sources/StubbedDB/StubbedDB.csproj @@ -0,0 +1,14 @@ + + + + net7.0 + enable + enable + + + + + + + + diff --git a/Sources/StubbedDTO/Stub.cs b/Sources/StubbedDTO/Stub.cs index a23762c..2eebcb2 100644 --- a/Sources/StubbedDTO/Stub.cs +++ b/Sources/StubbedDTO/Stub.cs @@ -33,6 +33,7 @@ public class Stub : IDtoManager using(StreamReader readerRatings = File.OpenText(ratingsFile)) { var work = WorkJsonReader.ReadWork(reader.ReadToEnd(), readerRatings.ReadToEnd()); + if(work.Authors != null) foreach(var author in work.Authors.ToList()) { var newAuthor = Authors.SingleOrDefault(a => a.Id == author.Id); @@ -68,7 +69,7 @@ public class Stub : IDtoManager public Task GetAuthorById(string id) { - var author = Stub.Authors.SingleOrDefault(a => a.Id == id); + var author = Stub.Authors.SingleOrDefault(a => a.Id.Contains(id)); return Task.FromResult(author); } @@ -147,8 +148,8 @@ public class Stub : IDtoManager public async Task>> GetBooksByAuthorId(string authorId, int index, int count, string sort = "") { - var books = Stub.Books.Where(b => b.Authors.Exists(a => a.Id == authorId) - || b.Works.Exists(w => w.Authors.Exists(a => a.Id == authorId))); + var books = Stub.Books.Where(b => b.Authors.Exists(a => a.Id.Contains(authorId)) + || b.Works.Exists(w => w.Authors.Exists(a => a.Id.Contains(authorId)))); return await OrderBooks(books, index, count, sort); } @@ -162,13 +163,15 @@ public class Stub : IDtoManager { IEnumerable authors = new List(); - if(book.Authors != null) + if(book.Authors != null && book.Authors.Count > 0) { authors = authors.Union(book.Authors); } if(book.Works != null) { - authors = authors.Union(book.Works.SelectMany(w => w.Authors)); + var worksAuthors = book.Works.SelectMany(w => w.Authors).ToList(); + if(worksAuthors.Count > 0) + authors = authors.Union(worksAuthors); } foreach(var author in authors) { diff --git a/Sources/StubbedDTO/StubbedDTO.csproj b/Sources/StubbedDTO/StubbedDTO.csproj index d57911e..b14d52d 100644 --- a/Sources/StubbedDTO/StubbedDTO.csproj +++ b/Sources/StubbedDTO/StubbedDTO.csproj @@ -6,11 +6,6 @@ enable - - - - - @@ -29,4 +24,9 @@ PreserveNewest + + + + + diff --git a/Sources/StubbedDTO/authors/OL1846639A.json b/Sources/StubbedDTO/authors/OL1846639A.json index 5bcb598..4b82846 100644 --- a/Sources/StubbedDTO/authors/OL1846639A.json +++ b/Sources/StubbedDTO/authors/OL1846639A.json @@ -1 +1,12 @@ -{"name": "Michel Demuth", "personal_name": "Michel Demuth", "last_modified": {"type": "/type/datetime", "value": "2008-08-26 02:41:15.604911"}, "key": "/authors/OL1846639A", "type": {"key": "/type/author"}, "id": 6527877, "revision": 2} \ No newline at end of file +{ + "name": "Michel Demuth", + "personal_name": "Michel Demuth", + "last_modified": { + "type": "/type/datetime", + "value": "2008-08-26 02:41:15.604911" + }, + "key": "/authors/OL1846639A", + "type": { "key": "/type/author" }, + "id": 6527877, + "revision": 2 +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL274606A.json b/Sources/StubbedDTO/authors/OL274606A.json index 6c8da79..0718f7b 100644 --- a/Sources/StubbedDTO/authors/OL274606A.json +++ b/Sources/StubbedDTO/authors/OL274606A.json @@ -1 +1,34 @@ -{"personal_name": "Dick, Philip K.", "source_records": ["amazon:8445007327", "bwb:9780722129562", "amazon:0792776232", "ia:pacificpark0000dick", "amazon:2277213799", "amazon:2266163019", "bwb:9798599263227", "amazon:1433276712", "ia:ejonescreoilmond0000dick", "amazon:6051719164", "amazon:6254493632", "amazon:2277117749", "amazon:1987781619", "amazon:1433248239", "amazon:1480594407"], "alternate_names": ["Philip Kindred Dick", "Philip Dick", "Philip Kendred Dick", "Philip K Dick"], "bio": "Philip Kindred Dick was an American novelist, short story writer, and essayist whose published work during his lifetime was almost entirely in the science fiction genre. Dick explored sociological, political and metaphysical themes in novels dominated by monopolistic corporations, authoritarian governments, and altered states. In his later works, Dick's thematic focus strongly reflected his personal interest in metaphysics and theology. He often drew upon his own life experiences and addressed the nature of drug abuse, paranoia and schizophrenia, and transcendental experiences in novels such as A Scanner Darkly and VALIS.\r\n\r\nSource and more information: [Wikipedia (EN)](http://en.wikipedia.org/wiki/Philip_K._Dick)", "type": {"key": "/type/author"}, "death_date": "2 March 1982", "remote_ids": {"isni": "0000000121251093", "wikidata": "Q171091", "viaf": "27063583"}, "name": "Philip K. Dick", "links": [{"title": "Wikipedia link to Philip K Dick", "url": "http://en.wikipedia.org/wiki/Philip_K._Dick", "type": {"key": "/type/link"}}], "photos": [6295259], "birth_date": "16 December 1928", "key": "/authors/OL274606A", "latest_revision": 23, "revision": 23, "created": {"type": "/type/datetime", "value": "2008-04-01T03:28:50.625462"}, "last_modified": {"type": "/type/datetime", "value": "2022-11-29T21:21:41.951561"}} \ No newline at end of file +{ + "personal_name": "Dick, Philip K.", + "source_records": [ "amazon:8445007327", "bwb:9780722129562", "amazon:0792776232", "ia:pacificpark0000dick", "amazon:2277213799", "amazon:2266163019", "bwb:9798599263227", "amazon:1433276712", "ia:ejonescreoilmond0000dick", "amazon:6051719164", "amazon:6254493632", "amazon:2277117749", "amazon:1987781619", "amazon:1433248239", "amazon:1480594407" ], + "alternate_names": [ "Philip Kindred Dick", "Philip Dick", "Philip Kendred Dick", "Philip K Dick" ], + "bio": "Philip Kindred Dick was an American novelist, short story writer, and essayist whose published work during his lifetime was almost entirely in the science fiction genre. Dick explored sociological, political and metaphysical themes in novels dominated by monopolistic corporations, authoritarian governments, and altered states. In his later works, Dick's thematic focus strongly reflected his personal interest in metaphysics and theology. He often drew upon his own life experiences and addressed the nature of drug abuse, paranoia and schizophrenia, and transcendental experiences in novels such as A Scanner Darkly and VALIS.\r\n\r\nSource and more information: [Wikipedia (EN)](http://en.wikipedia.org/wiki/Philip_K._Dick)", + "type": { "key": "/type/author" }, + "death_date": "2 March 1982", + "remote_ids": { + "isni": "0000000121251093", + "wikidata": "Q171091", + "viaf": "27063583" + }, + "name": "Philip K. Dick", + "links": [ + { + "title": "Wikipedia link to Philip K Dick", + "url": "http://en.wikipedia.org/wiki/Philip_K._Dick", + "type": { "key": "/type/link" } + } + ], + "photos": [ 6295259 ], + "birth_date": "16 December 1928", + "key": "/authors/OL274606A", + "latest_revision": 23, + "revision": 23, + "created": { + "type": "/type/datetime", + "value": "2008-04-01T03:28:50.625462" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2022-11-29T21:21:41.951561" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL3113900A.json b/Sources/StubbedDTO/authors/OL3113900A.json new file mode 100644 index 0000000..1aa9add --- /dev/null +++ b/Sources/StubbedDTO/authors/OL3113900A.json @@ -0,0 +1 @@ +{"name": "Gilles Goullet", "last_modified": {"type": "/type/datetime", "value": "2008-04-30 08:14:56.482104"}, "key": "/authors/OL3113900A", "type": {"key": "/type/author"}, "id": 11970651, "revision": 1} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL3113922A.json b/Sources/StubbedDTO/authors/OL3113922A.json index 56f0fbd..63fe25b 100644 --- a/Sources/StubbedDTO/authors/OL3113922A.json +++ b/Sources/StubbedDTO/authors/OL3113922A.json @@ -1 +1,11 @@ -{"name": "H\u00e9l\u00e8ne Collon", "last_modified": {"type": "/type/datetime", "value": "2008-04-30 08:14:56.482104"}, "key": "/authors/OL3113922A", "type": {"key": "/type/author"}, "id": 11970257, "revision": 1} \ No newline at end of file +{ + "name": "H\u00e9l\u00e8ne Collon", + "last_modified": { + "type": "/type/datetime", + "value": "2008-04-30 08:14:56.482104" + }, + "key": "/authors/OL3113922A", + "type": { "key": "/type/author" }, + "id": 11970257, + "revision": 1 +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL3980331A.json b/Sources/StubbedDTO/authors/OL3980331A.json index 66382b5..17a6d32 100644 --- a/Sources/StubbedDTO/authors/OL3980331A.json +++ b/Sources/StubbedDTO/authors/OL3980331A.json @@ -1 +1,17 @@ -{"name": "Alain Damasio", "key": "/authors/OL3980331A", "type": {"key": "/type/author"}, "remote_ids": {"wikidata": "Q2829704"}, "birth_date": "1 August 1969", "latest_revision": 2, "revision": 2, "created": {"type": "/type/datetime", "value": "2008-04-30T20:50:18.033121"}, "last_modified": {"type": "/type/datetime", "value": "2022-12-19T19:05:32.693708"}} \ No newline at end of file +{ + "name": "Alain Damasio", + "key": "/authors/OL3980331A", + "type": { "key": "/type/author" }, + "remote_ids": { "wikidata": "Q2829704" }, + "birth_date": "1 August 1969", + "latest_revision": 2, + "revision": 2, + "created": { + "type": "/type/datetime", + "value": "2008-04-30T20:50:18.033121" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2022-12-19T19:05:32.693708" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL6982995A.json b/Sources/StubbedDTO/authors/OL6982995A.json index 271a70c..51ccd1e 100644 --- a/Sources/StubbedDTO/authors/OL6982995A.json +++ b/Sources/StubbedDTO/authors/OL6982995A.json @@ -1 +1,36 @@ -{"personal_name": "James S. A. Corey", "remote_ids": {"isni": "0000000382626033", "viaf": "266413968", "wikidata": "Q6142591"}, "source_records": ["amazon:1478933771", "amazon:1528822218", "amazon:1456121650", "bwb:9780356510385", "amazon:0678452547", "bwb:9780356517773"], "alternate_names": ["Daniel Abraham", "Ty Franck", "James S.A. Corey", "James James S. A. Corey"], "type": {"key": "/type/author"}, "key": "/authors/OL6982995A", "entity_type": "org", "links": [{"title": "Source", "url": "http://www.danielabraham.com/james-s-a-corey/", "type": {"key": "/type/link"}}], "bio": {"type": "/type/text", "value": "James S.A. Corey is the pen name used by collaborators [Daniel Abraham](https://openlibrary.org/authors/OL1427729A/Daniel_Abraham) and [Ty Franck](https://openlibrary.org/authors/OL7523472A/Ty_Franck).\r\n\r\nThe first and last name are taken from Abraham's and Franck's middle names, respectively, and S.A. are the initials of Abraham's daughter."}, "photos": [11112303], "name": "James S. A. Corey", "latest_revision": 13, "revision": 13, "created": {"type": "/type/datetime", "value": "2011-10-20T08:06:05.906616"}, "last_modified": {"type": "/type/datetime", "value": "2023-05-18T18:14:26.659278"}} \ No newline at end of file +{ + "personal_name": "James S. A. Corey", + "remote_ids": { + "isni": "0000000382626033", + "viaf": "266413968", + "wikidata": "Q6142591" + }, + "source_records": [ "amazon:1478933771", "amazon:1528822218", "amazon:1456121650", "bwb:9780356510385", "amazon:0678452547", "bwb:9780356517773" ], + "alternate_names": [ "Daniel Abraham", "Ty Franck", "James S.A. Corey", "James James S. A. Corey" ], + "type": { "key": "/type/author" }, + "key": "/authors/OL6982995A", + "entity_type": "org", + "links": [ + { + "title": "Source", + "url": "http://www.danielabraham.com/james-s-a-corey/", + "type": { "key": "/type/link" } + } + ], + "bio": { + "type": "/type/text", + "value": "James S.A. Corey is the pen name used by collaborators [Daniel Abraham](https://openlibrary.org/authors/OL1427729A/Daniel_Abraham) and [Ty Franck](https://openlibrary.org/authors/OL7523472A/Ty_Franck).\r\n\r\nThe first and last name are taken from Abraham's and Franck's middle names, respectively, and S.A. are the initials of Abraham's daughter." + }, + "photos": [ 11112303 ], + "name": "James S. A. Corey", + "latest_revision": 13, + "revision": 13, + "created": { + "type": "/type/datetime", + "value": "2011-10-20T08:06:05.906616" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-05-18T18:14:26.659278" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL7475792A.json b/Sources/StubbedDTO/authors/OL7475792A.json index 5ff57b9..777b623 100644 --- a/Sources/StubbedDTO/authors/OL7475792A.json +++ b/Sources/StubbedDTO/authors/OL7475792A.json @@ -1 +1,15 @@ -{"key": "/authors/OL7475792A", "name": "Ada Palmer", "type": {"key": "/type/author"}, "latest_revision": 4, "revision": 4, "created": {"type": "/type/datetime", "value": "2019-03-11T19:38:25.579004"}, "last_modified": {"type": "/type/datetime", "value": "2021-12-07T07:11:29.213401"}} \ No newline at end of file +{ + "key": "/authors/OL7475792A", + "name": "Ada Palmer", + "type": { "key": "/type/author" }, + "latest_revision": 4, + "revision": 4, + "created": { + "type": "/type/datetime", + "value": "2019-03-11T19:38:25.579004" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-12-07T07:11:29.213401" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL7876839A.json b/Sources/StubbedDTO/authors/OL7876839A.json new file mode 100644 index 0000000..15d1ff6 --- /dev/null +++ b/Sources/StubbedDTO/authors/OL7876839A.json @@ -0,0 +1 @@ +{"name": "Robert Charles Wilson", "created": {"type": "/type/datetime", "value": "2020-05-08T21:00:30.785249"}, "last_modified": {"type": "/type/datetime", "value": "2020-05-08T21:00:30.785249"}, "latest_revision": 1, "key": "/authors/OL7876839A", "type": {"key": "/type/author"}, "revision": 1} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL79034A.json b/Sources/StubbedDTO/authors/OL79034A.json new file mode 100644 index 0000000..ce17b23 --- /dev/null +++ b/Sources/StubbedDTO/authors/OL79034A.json @@ -0,0 +1,42 @@ +{ + "remote_ids": { + "viaf": "59083797", + "wikidata": "Q7934", + "isni": "0000000121347853" + }, + "name": "Frank Herbert", + "source_records": [ "amazon:3870703903", "amazon:2253113190", "amazon:1427228493" ], + "alternate_names": [ "Herbert, Frank", "FRANK HERBERT", "Frank HERBERT", "herbert-frank", "frank herbert", "Herbert Frank", "Frank Herbert Dost Korpe", "HERBERT FRANK", "Franck Herbert", "F Herbert" ], + "photos": [ 12194537, 7277115, 10643754 ], + "links": [ + { + "url": "http://en.wikipedia.org/wiki/Frank_Herbert", + "type": { "key": "/type/link" }, + "title": "Wikipedia English" + }, + { + "url": "http://fr.wikipedia.org/wiki/Frank_Herbert", + "type": { "key": "/type/link" }, + "title": "Wikipedia France" + } + ], + "key": "/authors/OL79034A", + "birth_date": "8 October 1920", + "death_date": "11 February 1986", + "type": { "key": "/type/author" }, + "personal_name": "Herbert, Frank.", + "bio": { + "type": "/type/text", + "value": "Real name: Franklin Patrick Herbert Jr." + }, + "latest_revision": 15, + "revision": 15, + "created": { + "type": "/type/datetime", + "value": "2008-04-01T03:28:50.625462" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-11-12T11:41:55.357817" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/authors/OL9956442A.json b/Sources/StubbedDTO/authors/OL9956442A.json index 9e515a7..3b660a9 100644 --- a/Sources/StubbedDTO/authors/OL9956442A.json +++ b/Sources/StubbedDTO/authors/OL9956442A.json @@ -1 +1,16 @@ -{"type": {"key": "/type/author"}, "name": "Frank Herbert", "key": "/authors/OL9956442A", "source_records": ["amazon:2221252306"], "latest_revision": 1, "revision": 1, "created": {"type": "/type/datetime", "value": "2021-11-14T17:07:35.515652"}, "last_modified": {"type": "/type/datetime", "value": "2021-11-14T17:07:35.515652"}} \ No newline at end of file +{ + "type": { "key": "/type/author" }, + "name": "Frank Herbert", + "key": "/authors/OL9956442A", + "source_records": [ "amazon:2221252306" ], + "latest_revision": 1, + "revision": 1, + "created": { + "type": "/type/datetime", + "value": "2021-11-14T17:07:35.515652" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-11-14T17:07:35.515652" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL25910297M.json b/Sources/StubbedDTO/books/OL25910297M.json index 249fb9e..b94543f 100644 --- a/Sources/StubbedDTO/books/OL25910297M.json +++ b/Sources/StubbedDTO/books/OL25910297M.json @@ -1 +1,24 @@ -{"publishers": ["Actes Sud"], "title": "L'\u00c9veil du L\u00e9viathan", "number_of_pages": 624, "isbn_13": ["9782330033118"], "covers": [7412481], "languages": [{"key": "/languages/fre"}], "publish_date": "4 juin 2014", "key": "/books/OL25910297M", "publish_places": ["France"], "works": [{"key": "/works/OL17334140W"}], "type": {"key": "/type/edition"}, "source_records": ["amazon:2330033117"], "latest_revision": 5, "revision": 5, "created": {"type": "/type/datetime", "value": "2016-04-22T11:47:01.838591"}, "last_modified": {"type": "/type/datetime", "value": "2023-02-02T01:19:11.921173"}} \ No newline at end of file +{ + "publishers": [ "Actes Sud" ], + "title": "L'\u00c9veil du L\u00e9viathan", + "number_of_pages": 624, + "isbn_13": [ "9782330033118" ], + "covers": [ 7412481 ], + "languages": [ { "key": "/languages/fre" } ], + "publish_date": "4 juin 2014", + "key": "/books/OL25910297M", + "publish_places": [ "France" ], + "works": [ { "key": "/works/OL17334140W" } ], + "type": { "key": "/type/edition" }, + "source_records": [ "amazon:2330033117" ], + "latest_revision": 5, + "revision": 5, + "created": { + "type": "/type/datetime", + "value": "2016-04-22T11:47:01.838591" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-02-02T01:19:11.921173" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL27258011M.json b/Sources/StubbedDTO/books/OL27258011M.json new file mode 100644 index 0000000..384aa86 --- /dev/null +++ b/Sources/StubbedDTO/books/OL27258011M.json @@ -0,0 +1,23 @@ +{ + "publishers": [ "Editions Gallimard" ], + "source_records": [ "amazon:2070793109" ], + "title": "La m\u00e9nagerie de papier", + "identifiers": { "amazon": [ "2070793109" ] }, + "isbn_13": [ "9782070793105" ], + "covers": [ 8750266 ], + "created": { + "type": "/type/datetime", + "value": "2019-08-05T10:36:44.503432" + }, + "physical_format": "mass market paperback", + "isbn_10": [ "2070793109" ], + "latest_revision": 1, + "key": "/books/OL27258011M", + "last_modified": { + "type": "/type/datetime", + "value": "2019-08-05T10:36:44.503432" + }, + "works": [ { "key": "/works/OL20078005W" } ], + "type": { "key": "/type/edition" }, + "revision": 1 +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL27989051M.json b/Sources/StubbedDTO/books/OL27989051M.json new file mode 100644 index 0000000..878d598 --- /dev/null +++ b/Sources/StubbedDTO/books/OL27989051M.json @@ -0,0 +1,38 @@ +{ + "publishers": [ "Le B\u00e9lial'" ], + "subtitle": "Terra Ignota volume 2", + "covers": [ 9376451 ], + "physical_format": "paperback", + "full_title": "Sept redditions : Terra Ignota volume 2", + "key": "/books/OL27989051M", + "authors": [ { "key": "/authors/OL7475792A" } ], + "source_records": [ "amazon:2843449626" ], + "title": "Sept redditions", + "notes": "Source title: Sept redditions: Terra Ignota volume 2 (Roman)", + "number_of_pages": 544, + "publish_date": "May 28, 2020", + "works": [ { "key": "/works/OL19213555W" } ], + "type": { "key": "/type/edition" }, + "identifiers": {}, + "isbn_10": [ "2843449626" ], + "isbn_13": [ "9782843449628" ], + "classifications": {}, + "languages": [ { "key": "/languages/fre" } ], + "contributors": [ + { + "name": "Michelle Charrier", + "role": "Translator" + } + ], + "series": [ "Terra Ignota #2" ], + "latest_revision": 4, + "revision": 4, + "created": { + "type": "/type/datetime", + "value": "2020-05-02T22:25:18.922926" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-12-07T07:10:56.070304" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL28294024M.json b/Sources/StubbedDTO/books/OL28294024M.json new file mode 100644 index 0000000..e5c5dcf --- /dev/null +++ b/Sources/StubbedDTO/books/OL28294024M.json @@ -0,0 +1 @@ +{"publishers": ["GALLIMARD"], "last_modified": {"type": "/type/datetime", "value": "2020-06-28T05:17:49.626242"}, "source_records": ["amazon:2070469875"], "title": "La trilogie Spin", "notes": {"type": "/type/text", "value": "Source title: La trilogie Spin (Folio SF - XL) (French Edition)"}, "number_of_pages": 1120, "isbn_13": ["9782070469871"], "covers": [10218906], "created": {"type": "/type/datetime", "value": "2020-06-28T05:17:49.626242"}, "physical_format": "paperback", "isbn_10": ["2070469875"], "publish_date": "Jun 02, 2016", "key": "/books/OL28294024M", "authors": [{"key": "/authors/OL7876839A"}, {"key": "/authors/OL3113900A"}], "latest_revision": 1, "works": [{"key": "/works/OL20889233W"}], "type": {"key": "/type/edition"}, "revision": 1} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL28639494M.json b/Sources/StubbedDTO/books/OL28639494M.json new file mode 100644 index 0000000..f5d7575 --- /dev/null +++ b/Sources/StubbedDTO/books/OL28639494M.json @@ -0,0 +1,32 @@ +{ + "publishers": [ "Pocket", "POCKET" ], + "source_records": [ "amazon:2266235818" ], + "title": "Le Cycle de Dune Tome 2/Le Messie de Dune", + "notes": { + "type": "/type/text", + "value": "Source title: Le Cycle de Dune Tome 2/Le Messie de Dune (Science-fiction) (French Edition)" + }, + "number_of_pages": 336, + "isbn_13": [ "9782266235815" ], + "covers": [ 10328275 ], + "physical_format": "mass market paperback", + "isbn_10": [ "2266235818" ], + "publish_date": "Nov 22, 2012", + "key": "/books/OL28639494M", + "authors": [ + { "key": "/authors/OL79034A" }, + { "key": "/authors/OL1846639A" } + ], + "works": [ { "key": "/works/OL893526W" } ], + "type": { "key": "/type/edition" }, + "latest_revision": 3, + "revision": 3, + "created": { + "type": "/type/datetime", + "value": "2020-08-05T18:59:33.402965" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-10-24T22:27:33.839388" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL35698073M.json b/Sources/StubbedDTO/books/OL35698073M.json new file mode 100644 index 0000000..b6a949a --- /dev/null +++ b/Sources/StubbedDTO/books/OL35698073M.json @@ -0,0 +1,31 @@ +{ + "identifiers": { "wikidata": [ "Q81118625" ] }, + "title": "Trop semblable \u00e0 l'\u00e9clair", + "publish_date": "2019", + "publishers": [ "Le B\u00e9lial'" ], + "type": { "key": "/type/edition" }, + "isbn_13": [ "9782843449581" ], + "series": [ "Terra Ignota #1" ], + "physical_format": "paperback", + "contributors": [ + { + "name": "Michelle Charrier", + "role": "Translator" + } + ], + "languages": [ { "key": "/languages/fre" } ], + "key": "/books/OL35698073M", + "number_of_pages": 672, + "works": [ { "key": "/works/OL19800093W" } ], + "source_records": [ "amazon:2843449588" ], + "latest_revision": 4, + "revision": 4, + "created": { + "type": "/type/datetime", + "value": "2021-12-07T02:12:00.907076" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2022-11-15T15:47:17.497202" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL35698083M.json b/Sources/StubbedDTO/books/OL35698083M.json index 2310127..006a950 100644 --- a/Sources/StubbedDTO/books/OL35698083M.json +++ b/Sources/StubbedDTO/books/OL35698083M.json @@ -1 +1,32 @@ -{"works": [{"key": "/works/OL19635836W"}], "title": "La Volont\u00e9 de se battre", "publishers": ["Le B\u00e9lial'"], "publish_date": "2020", "key": "/books/OL35698083M", "type": {"key": "/type/edition"}, "identifiers": {}, "covers": [12392970], "isbn_13": ["9782843449758"], "classifications": {}, "languages": [{"key": "/languages/fre"}], "contributors": [{"name": "Michelle Charrier", "role": "Translator"}], "number_of_pages": 526, "series": ["Terra Ignota #3"], "physical_format": "paperback", "latest_revision": 3, "revision": 3, "created": {"type": "/type/datetime", "value": "2021-12-07T02:23:07.593997"}, "last_modified": {"type": "/type/datetime", "value": "2021-12-07T02:24:57.135563"}} \ No newline at end of file +{ + "works": [ { "key": "/works/OL19635836W" } ], + "title": "La Volont\u00e9 de se battre", + "publishers": [ "Le B\u00e9lial'" ], + "publish_date": "2020", + "key": "/books/OL35698083M", + "type": { "key": "/type/edition" }, + "identifiers": {}, + "covers": [ 12392970 ], + "isbn_13": [ "9782843449758" ], + "classifications": {}, + "languages": [ { "key": "/languages/fre" } ], + "contributors": [ + { + "name": "Michelle Charrier", + "role": "Translator" + } + ], + "number_of_pages": 526, + "series": [ "Terra Ignota #3" ], + "physical_format": "paperback", + "latest_revision": 3, + "revision": 3, + "created": { + "type": "/type/datetime", + "value": "2021-12-07T02:23:07.593997" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-12-07T02:24:57.135563" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL35699439M.json b/Sources/StubbedDTO/books/OL35699439M.json index cf469d9..62610a7 100644 --- a/Sources/StubbedDTO/books/OL35699439M.json +++ b/Sources/StubbedDTO/books/OL35699439M.json @@ -1 +1,26 @@ -{"type": {"key": "/type/edition"}, "title": "La Zone du Dehors", "authors": [{"key": "/authors/OL3980331A"}], "publish_date": "Feb 04, 2021", "source_records": ["amazon:2072927528"], "number_of_pages": 656, "publishers": ["FOLIO", "GALLIMARD"], "isbn_10": ["2072927528"], "isbn_13": ["9782072927522"], "physical_format": "pocket book", "full_title": "La Zone du Dehors", "covers": [12393645], "works": [{"key": "/works/OL19960903W"}], "key": "/books/OL35699439M", "latest_revision": 1, "revision": 1, "created": {"type": "/type/datetime", "value": "2021-12-07T22:26:13.534930"}, "last_modified": {"type": "/type/datetime", "value": "2021-12-07T22:26:13.534930"}} \ No newline at end of file +{ + "type": { "key": "/type/edition" }, + "title": "La Zone du Dehors", + "authors": [ { "key": "/authors/OL3980331A" } ], + "publish_date": "Feb 04, 2021", + "source_records": [ "amazon:2072927528" ], + "number_of_pages": 656, + "publishers": [ "FOLIO", "GALLIMARD" ], + "isbn_10": [ "2072927528" ], + "isbn_13": [ "9782072927522" ], + "physical_format": "pocket book", + "full_title": "La Zone du Dehors", + "covers": [ 12393645 ], + "works": [ { "key": "/works/OL19960903W" } ], + "key": "/books/OL35699439M", + "latest_revision": 1, + "revision": 1, + "created": { + "type": "/type/datetime", + "value": "2021-12-07T22:26:13.534930" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-12-07T22:26:13.534930" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL38218739M.json b/Sources/StubbedDTO/books/OL38218739M.json index 942bbec..43e3f46 100644 --- a/Sources/StubbedDTO/books/OL38218739M.json +++ b/Sources/StubbedDTO/books/OL38218739M.json @@ -1 +1,31 @@ -{"type": {"key": "/type/edition"}, "title": "Dune - tome 1", "authors": [{"key": "/authors/OL9956442A"}, {"key": "/authors/OL1846639A"}], "publish_date": "Nov 22, 2012", "source_records": ["amazon:2266233203"], "number_of_pages": 832, "publishers": ["POCKET", "Pocket"], "isbn_10": ["2266233203"], "isbn_13": ["9782266233200"], "physical_format": "pocket book", "notes": {"type": "/type/text", "value": "Source title: Dune - tome 1 (1)"}, "works": [{"key": "/works/OL27962193W"}], "key": "/books/OL38218739M", "latest_revision": 1, "revision": 1, "created": {"type": "/type/datetime", "value": "2022-05-30T17:18:00.228322"}, "last_modified": {"type": "/type/datetime", "value": "2022-05-30T17:18:00.228322"}} \ No newline at end of file +{ + "type": { "key": "/type/edition" }, + "title": "Dune - tome 1", + "authors": [ + { "key": "/authors/OL9956442A" }, + { "key": "/authors/OL1846639A" } + ], + "publish_date": "Nov 22, 2012", + "source_records": [ "amazon:2266233203" ], + "number_of_pages": 832, + "publishers": [ "POCKET", "Pocket" ], + "isbn_10": [ "2266233203" ], + "isbn_13": [ "9782266233200" ], + "physical_format": "pocket book", + "notes": { + "type": "/type/text", + "value": "Source title: Dune - tome 1 (1)" + }, + "works": [ { "key": "/works/OL27962193W" } ], + "key": "/books/OL38218739M", + "latest_revision": 1, + "revision": 1, + "created": { + "type": "/type/datetime", + "value": "2022-05-30T17:18:00.228322" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2022-05-30T17:18:00.228322" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/books/OL38586212M.json b/Sources/StubbedDTO/books/OL38586212M.json index 5be49c0..1ab8986 100644 --- a/Sources/StubbedDTO/books/OL38586212M.json +++ b/Sources/StubbedDTO/books/OL38586212M.json @@ -1 +1,28 @@ -{"type": {"key": "/type/edition"}, "title": "Total Recall et autres r\u00e9cits", "authors": [{"key": "/authors/OL274606A"}, {"key": "/authors/OL3113922A"}], "publish_date": "Jul 12, 2012", "source_records": ["amazon:2070448908"], "number_of_pages": 448, "publishers": ["FOLIO", "GALLIMARD"], "isbn_10": ["2070448908"], "isbn_13": ["9782070448906"], "physical_format": "pocket book", "works": [{"key": "/works/OL28185064W"}], "key": "/books/OL38586212M", "covers": [13858141], "latest_revision": 3, "revision": 3, "created": {"type": "/type/datetime", "value": "2022-07-10T01:29:29.296699"}, "last_modified": {"type": "/type/datetime", "value": "2023-04-07T22:44:13.567567"}} \ No newline at end of file +{ + "type": { "key": "/type/edition" }, + "title": "Total Recall et autres r\u00e9cits", + "authors": [ + { "key": "/authors/OL274606A" }, + { "key": "/authors/OL3113922A" } + ], + "publish_date": "Jul 12, 2012", + "source_records": [ "amazon:2070448908" ], + "number_of_pages": 448, + "publishers": [ "FOLIO", "GALLIMARD" ], + "isbn_10": [ "2070448908" ], + "isbn_13": [ "9782070448906" ], + "physical_format": "pocket book", + "works": [ { "key": "/works/OL28185064W" } ], + "key": "/books/OL38586212M", + "covers": [ 13858141 ], + "latest_revision": 3, + "revision": 3, + "created": { + "type": "/type/datetime", + "value": "2022-07-10T01:29:29.296699" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-04-07T22:44:13.567567" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL17334140W.ratings.json b/Sources/StubbedDTO/ratings/OL17334140W.ratings.json index 85e13a6..536dae4 100644 --- a/Sources/StubbedDTO/ratings/OL17334140W.ratings.json +++ b/Sources/StubbedDTO/ratings/OL17334140W.ratings.json @@ -1 +1,13 @@ -{"summary": {"average": null, "count": 0}, "counts": {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0}} \ No newline at end of file +{ + "summary": { + "average": null, + "count": 0 + }, + "counts": { + "1": 0, + "2": 0, + "3": 0, + "4": 0, + "5": 0 + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL19213555W.ratings.json b/Sources/StubbedDTO/ratings/OL19213555W.ratings.json new file mode 100644 index 0000000..3cc42e0 --- /dev/null +++ b/Sources/StubbedDTO/ratings/OL19213555W.ratings.json @@ -0,0 +1 @@ +{"summary": {"average": 4.333333333333333, "count": 6, "sortable": 3.114900291576932}, "counts": {"1": 0, "2": 0, "3": 1, "4": 2, "5": 3}} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL19635836W.ratings.json b/Sources/StubbedDTO/ratings/OL19635836W.ratings.json index 373d6c8..202f4ac 100644 --- a/Sources/StubbedDTO/ratings/OL19635836W.ratings.json +++ b/Sources/StubbedDTO/ratings/OL19635836W.ratings.json @@ -1 +1,14 @@ -{"summary": {"average": 4.8, "count": 5, "sortable": 3.216059213089321}, "counts": {"1": 0, "2": 0, "3": 0, "4": 1, "5": 4}} \ No newline at end of file +{ + "summary": { + "average": 4.8, + "count": 5, + "sortable": 3.216059213089321 + }, + "counts": { + "1": 0, + "2": 0, + "3": 0, + "4": 1, + "5": 4 + } +} diff --git a/Sources/StubbedDTO/ratings/OL19800093W.ratings.json b/Sources/StubbedDTO/ratings/OL19800093W.ratings.json new file mode 100644 index 0000000..0f30a8c --- /dev/null +++ b/Sources/StubbedDTO/ratings/OL19800093W.ratings.json @@ -0,0 +1 @@ +{"summary": {"average": 3.6923076923076925, "count": 13, "sortable": 2.9048164811987554}, "counts": {"1": 2, "2": 2, "3": 1, "4": 1, "5": 7}} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL19960903W.ratings.json b/Sources/StubbedDTO/ratings/OL19960903W.ratings.json index 4cbb213..14c4ff0 100644 --- a/Sources/StubbedDTO/ratings/OL19960903W.ratings.json +++ b/Sources/StubbedDTO/ratings/OL19960903W.ratings.json @@ -1 +1,14 @@ -{"summary": {"average": 4.0, "count": 1, "sortable": 2.3286737413641063}, "counts": {"1": 0, "2": 0, "3": 0, "4": 1, "5": 0}} \ No newline at end of file +{ + "summary": { + "average": 4.0, + "count": 1, + "sortable": 2.3286737413641063 + }, + "counts": { + "1": 0, + "2": 0, + "3": 0, + "4": 1, + "5": 0 + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL20078005W.ratings.json b/Sources/StubbedDTO/ratings/OL20078005W.ratings.json new file mode 100644 index 0000000..85e13a6 --- /dev/null +++ b/Sources/StubbedDTO/ratings/OL20078005W.ratings.json @@ -0,0 +1 @@ +{"summary": {"average": null, "count": 0}, "counts": {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0}} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL20889233W.ratings.json b/Sources/StubbedDTO/ratings/OL20889233W.ratings.json new file mode 100644 index 0000000..85e13a6 --- /dev/null +++ b/Sources/StubbedDTO/ratings/OL20889233W.ratings.json @@ -0,0 +1 @@ +{"summary": {"average": null, "count": 0}, "counts": {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0}} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL27962193W.ratings.json b/Sources/StubbedDTO/ratings/OL27962193W.ratings.json index c2901fe..9accbc5 100644 --- a/Sources/StubbedDTO/ratings/OL27962193W.ratings.json +++ b/Sources/StubbedDTO/ratings/OL27962193W.ratings.json @@ -1 +1,14 @@ -{"summary": {"average": 3.0, "count": 1, "sortable": 2.19488243981746}, "counts": {"1": 0, "2": 0, "3": 1, "4": 0, "5": 0}} \ No newline at end of file +{ + "summary": { + "average": 3.0, + "count": 1, + "sortable": 2.19488243981746 + }, + "counts": { + "1": 0, + "2": 0, + "3": 1, + "4": 0, + "5": 0 + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL28185064W.ratings.json b/Sources/StubbedDTO/ratings/OL28185064W.ratings.json index 85e13a6..536dae4 100644 --- a/Sources/StubbedDTO/ratings/OL28185064W.ratings.json +++ b/Sources/StubbedDTO/ratings/OL28185064W.ratings.json @@ -1 +1,13 @@ -{"summary": {"average": null, "count": 0}, "counts": {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0}} \ No newline at end of file +{ + "summary": { + "average": null, + "count": 0 + }, + "counts": { + "1": 0, + "2": 0, + "3": 0, + "4": 0, + "5": 0 + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/ratings/OL893526W.ratings.json b/Sources/StubbedDTO/ratings/OL893526W.ratings.json new file mode 100644 index 0000000..8b4cddd --- /dev/null +++ b/Sources/StubbedDTO/ratings/OL893526W.ratings.json @@ -0,0 +1 @@ +{"summary": {"average": 3.9368421052631577, "count": 95, "sortable": 3.721132697535656}, "counts": {"1": 3, "2": 4, "3": 19, "4": 39, "5": 30}} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL17334140W.json b/Sources/StubbedDTO/works/OL17334140W.json index 637e78d..839a824 100644 --- a/Sources/StubbedDTO/works/OL17334140W.json +++ b/Sources/StubbedDTO/works/OL17334140W.json @@ -1 +1,22 @@ -{"title": "L'\u00c9veil du L\u00e9viathan", "key": "/works/OL17334140W", "authors": [{"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL6982995A"}}], "type": {"key": "/type/work"}, "covers": [7412481], "latest_revision": 3, "revision": 3, "created": {"type": "/type/datetime", "value": "2016-04-22T11:47:01.838591"}, "last_modified": {"type": "/type/datetime", "value": "2023-02-02T01:19:11.921173"}} \ No newline at end of file +{ + "title": "L'\u00c9veil du L\u00e9viathan", + "key": "/works/OL17334140W", + "authors": [ + { + "type": { "key": "/type/author_role" }, + "author": { "key": "/authors/OL6982995A" } + } + ], + "type": { "key": "/type/work" }, + "covers": [ 7412481 ], + "latest_revision": 3, + "revision": 3, + "created": { + "type": "/type/datetime", + "value": "2016-04-22T11:47:01.838591" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-02-02T01:19:11.921173" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL19213555W.json b/Sources/StubbedDTO/works/OL19213555W.json new file mode 100644 index 0000000..a758427 --- /dev/null +++ b/Sources/StubbedDTO/works/OL19213555W.json @@ -0,0 +1 @@ +{"description": "\"It is a world in which near-instantaneous travel from continent to continent is free to all. In which automation now provides for everybody's basic needs. In which nobody living can remember an actual war. In which it is illegal for three or more people to gather for the practice of religion--but ecumenical \"sensayers\" minister in private, one-on-one. In which gendered language is archaic, and to dress as strongly male or female is, if not exactly illegal, deeply taboo. In which nationality is a fading memory, and most people identify instead with their choice of the seven global Hives, distinguished from one another by their different approaches to the big questions of life. And it is a world in which, unknown to most, the entire social order is teetering on the edge of collapse. Because even in utopia, humans will conspire. And also because something new has arisen: Bridger, the child who can bring inanimate objects to conscious life\"--", "covers": [8429595, 8772829, 9338105, 9376451], "key": "/works/OL19213555W", "authors": [{"author": {"key": "/authors/OL7475792A"}, "type": {"key": "/type/author_role"}}], "title": "Seven Surrenders", "subjects": ["Utopias", "Fiction", "Fiction, science fiction, general", "series:terra_ignota"], "type": {"key": "/type/work"}, "latest_revision": 6, "revision": 6, "created": {"type": "/type/datetime", "value": "2019-03-11T19:38:25.579004"}, "last_modified": {"type": "/type/datetime", "value": "2021-12-07T07:10:56.070304"}} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL19635836W.json b/Sources/StubbedDTO/works/OL19635836W.json index 47d4eea..6d7f024 100644 --- a/Sources/StubbedDTO/works/OL19635836W.json +++ b/Sources/StubbedDTO/works/OL19635836W.json @@ -1 +1,24 @@ -{"description": "\"The long years of near-utopia have come to an abrupt end. Peace and order are now figments of the past. Corruption, deception, and insurgency hum within the once steadfast leadership of the Hives, nations without fixed location. The heartbreaking truth is that for decades, even centuries, the leaders of the great Hives bought the world's stability with a trickle of secret murders, mathematically planned. So that no faction could ever dominate. So that the balance held. The Hives' fa\u00e7ade of solidity is the only hope they have for maintaining a semblance of order, for preventing the public from succumbing to the savagery and bloodlust of wars past. But as the great secret becomes more and more widely known, that fa\u00e7ade is slipping away. Just days earlier, the world was a pinnacle of human civilization. Now everyone--Hives and hiveless, Utopians and sensayers, emperors and the downtrodden, warriors and saints--scrambles to prepare for the seemingly inevitable war\"--", "covers": [8544084, 8619055, 10180814], "key": "/works/OL19635836W", "authors": [{"author": {"key": "/authors/OL7475792A"}, "type": {"key": "/type/author_role"}}], "title": "The Will to Battle", "subjects": ["Utopias", "Fiction", "Fiction, science fiction, general", "series:terra_ignota"], "type": {"key": "/type/work"}, "latest_revision": 7, "revision": 7, "created": {"type": "/type/datetime", "value": "2019-04-21T08:07:12.674468"}, "last_modified": {"type": "/type/datetime", "value": "2021-12-07T07:08:28.885088"}} \ No newline at end of file +{ + "description": "\"The long years of near-utopia have come to an abrupt end. Peace and order are now figments of the past. Corruption, deception, and insurgency hum within the once steadfast leadership of the Hives, nations without fixed location. The heartbreaking truth is that for decades, even centuries, the leaders of the great Hives bought the world's stability with a trickle of secret murders, mathematically planned. So that no faction could ever dominate. So that the balance held. The Hives' fa\u00e7ade of solidity is the only hope they have for maintaining a semblance of order, for preventing the public from succumbing to the savagery and bloodlust of wars past. But as the great secret becomes more and more widely known, that fa\u00e7ade is slipping away. Just days earlier, the world was a pinnacle of human civilization. Now everyone--Hives and hiveless, Utopians and sensayers, emperors and the downtrodden, warriors and saints--scrambles to prepare for the seemingly inevitable war\"--", + "covers": [ 8544084, 8619055, 10180814 ], + "key": "/works/OL19635836W", + "authors": [ + { + "author": { "key": "/authors/OL7475792A" }, + "type": { "key": "/type/author_role" } + } + ], + "title": "The Will to Battle", + "subjects": [ "Utopias", "Fiction", "Fiction, science fiction, general", "series:terra_ignota" ], + "type": { "key": "/type/work" }, + "latest_revision": 7, + "revision": 7, + "created": { + "type": "/type/datetime", + "value": "2019-04-21T08:07:12.674468" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2021-12-07T07:08:28.885088" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL19800093W.json b/Sources/StubbedDTO/works/OL19800093W.json new file mode 100644 index 0000000..8d9df69 --- /dev/null +++ b/Sources/StubbedDTO/works/OL19800093W.json @@ -0,0 +1 @@ +{"description": "\"The world into which Mycroft and Carlyle have been born is as strange to our 21st-century eyes as ours would be to a native of the 1500s. It is a hard-won utopia built on technologically-generated abundance, and also on complex and mandatory systems of labeling all public writing and speech... And in this world, Mycroft and Carlyle have stumbled on the wild card that may destabilize the system: the boy Bridger, who can effortlessly make his wishes come true. Who can, it would seem, bring inanimate objects to life...\"--Book jacket.", "covers": [8600692, 8673756], "key": "/works/OL19800093W", "authors": [{"author": {"key": "/authors/OL7475792A"}, "type": {"key": "/type/author_role"}}], "title": "Too Like the Lightning", "subjects": ["Utopias", "Prisoners", "Twenty-fifth century", "Fiction", "Third millennium", "Fiction, science fiction, general", "series:terra_ignota", "Spirituality", "Magic", "FICTION", "Science Fiction"], "type": {"key": "/type/work"}, "latest_revision": 6, "revision": 6, "created": {"type": "/type/datetime", "value": "2019-06-23T20:50:30.749828"}, "last_modified": {"type": "/type/datetime", "value": "2022-03-12T06:35:56.153258"}} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL19960903W.json b/Sources/StubbedDTO/works/OL19960903W.json index 4c399ab..ba6654e 100644 --- a/Sources/StubbedDTO/works/OL19960903W.json +++ b/Sources/StubbedDTO/works/OL19960903W.json @@ -1 +1,22 @@ -{"title": "La zone du dehors", "key": "/works/OL19960903W", "authors": [{"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL3980331A"}}], "type": {"key": "/type/work"}, "covers": [13472433], "latest_revision": 2, "revision": 2, "created": {"type": "/type/datetime", "value": "2019-07-17T23:01:16.580404"}, "last_modified": {"type": "/type/datetime", "value": "2023-03-15T21:59:10.897047"}} \ No newline at end of file +{ + "title": "La zone du dehors", + "key": "/works/OL19960903W", + "authors": [ + { + "type": { "key": "/type/author_role" }, + "author": { "key": "/authors/OL3980331A" } + } + ], + "type": { "key": "/type/work" }, + "covers": [ 13472433 ], + "latest_revision": 2, + "revision": 2, + "created": { + "type": "/type/datetime", + "value": "2019-07-17T23:01:16.580404" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-03-15T21:59:10.897047" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL20078005W.json b/Sources/StubbedDTO/works/OL20078005W.json new file mode 100644 index 0000000..bb2c7ec --- /dev/null +++ b/Sources/StubbedDTO/works/OL20078005W.json @@ -0,0 +1,16 @@ +{ + "title": "La m\u00e9nagerie de papier", + "created": { + "type": "/type/datetime", + "value": "2019-08-05T10:36:44.503432" + }, + "covers": [ 8750266 ], + "last_modified": { + "type": "/type/datetime", + "value": "2019-08-05T10:36:44.503432" + }, + "latest_revision": 1, + "key": "/works/OL20078005W", + "type": { "key": "/type/work" }, + "revision": 1 +} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL20889233W.json b/Sources/StubbedDTO/works/OL20889233W.json new file mode 100644 index 0000000..11b0d93 --- /dev/null +++ b/Sources/StubbedDTO/works/OL20889233W.json @@ -0,0 +1 @@ +{"title": "La trilogie Spin", "created": {"type": "/type/datetime", "value": "2020-06-28T05:17:49.626242"}, "covers": [10218906], "last_modified": {"type": "/type/datetime", "value": "2020-06-28T05:17:49.626242"}, "latest_revision": 1, "key": "/works/OL20889233W", "authors": [{"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL7876839A"}}, {"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL3113900A"}}], "type": {"key": "/type/work"}, "revision": 1} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL27962193W.json b/Sources/StubbedDTO/works/OL27962193W.json index f373418..4eefdac 100644 --- a/Sources/StubbedDTO/works/OL27962193W.json +++ b/Sources/StubbedDTO/works/OL27962193W.json @@ -1 +1,26 @@ -{"type": {"key": "/type/work"}, "title": "Dune - tome 1", "authors": [{"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL9956442A"}}, {"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL1846639A"}}], "key": "/works/OL27962193W", "covers": [13823878], "latest_revision": 2, "revision": 2, "created": {"type": "/type/datetime", "value": "2022-05-30T17:18:00.228322"}, "last_modified": {"type": "/type/datetime", "value": "2023-04-04T09:05:11.531979"}} \ No newline at end of file +{ + "type": { "key": "/type/work" }, + "title": "Dune - tome 1", + "authors": [ + { + "type": { "key": "/type/author_role" }, + "author": { "key": "/authors/OL9956442A" } + }, + { + "type": { "key": "/type/author_role" }, + "author": { "key": "/authors/OL1846639A" } + } + ], + "key": "/works/OL27962193W", + "covers": [ 13823878 ], + "latest_revision": 2, + "revision": 2, + "created": { + "type": "/type/datetime", + "value": "2022-05-30T17:18:00.228322" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-04-04T09:05:11.531979" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL28185064W.json b/Sources/StubbedDTO/works/OL28185064W.json index 00f1ace..9a83844 100644 --- a/Sources/StubbedDTO/works/OL28185064W.json +++ b/Sources/StubbedDTO/works/OL28185064W.json @@ -1 +1,26 @@ -{"type": {"key": "/type/work"}, "title": "Total Recall et autres r\u00e9cits", "authors": [{"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL274606A"}}, {"type": {"key": "/type/author_role"}, "author": {"key": "/authors/OL3113922A"}}], "key": "/works/OL28185064W", "covers": [13858141], "latest_revision": 3, "revision": 3, "created": {"type": "/type/datetime", "value": "2022-07-10T01:29:29.296699"}, "last_modified": {"type": "/type/datetime", "value": "2023-04-07T22:44:13.567567"}} \ No newline at end of file +{ + "type": { "key": "/type/work" }, + "title": "Total Recall et autres r\u00e9cits", + "authors": [ + { + "type": { "key": "/type/author_role" }, + "author": { "key": "/authors/OL274606A" } + }, + { + "type": { "key": "/type/author_role" }, + "author": { "key": "/authors/OL3113922A" } + } + ], + "key": "/works/OL28185064W", + "covers": [ 13858141 ], + "latest_revision": 3, + "revision": 3, + "created": { + "type": "/type/datetime", + "value": "2022-07-10T01:29:29.296699" + }, + "last_modified": { + "type": "/type/datetime", + "value": "2023-04-07T22:44:13.567567" + } +} \ No newline at end of file diff --git a/Sources/StubbedDTO/works/OL893526W.json b/Sources/StubbedDTO/works/OL893526W.json new file mode 100644 index 0000000..835d810 --- /dev/null +++ b/Sources/StubbedDTO/works/OL893526W.json @@ -0,0 +1 @@ +{"subjects": ["American Science fiction", "Dune (Imaginary place)", "Fiction", "Fiction in English", "Imaginary places", "Science Fiction", "Translations into Russian", "Novela", "Dune (Lugar imaginario)", "Lectures et morceaux choisis", "Anglais (langue)", "Roman ame ricain", "Science-fiction ame ricaine", "Long Now Manual for Civilization", "Roman ame\u0301ricain", "Science-fiction ame\u0301ricaine", "Dune (imaginary place), fiction", "Fiction, science fiction, general"], "key": "/works/OL893526W", "title": "Dune Messiah", "authors": [{"author": {"key": "/authors/OL79034A"}, "type": {"key": "/type/author_role"}}, {"author": {"key": "/authors/OL1846639A"}, "type": {"key": "/type/author_role"}}], "type": {"key": "/type/work"}, "covers": [2421405, 1009421, 5277575, 284503, 8450071, 8771464, 10328275, 11422534, 11290920, 10849793, 979507, 8376882], "description": {"type": "/type/text", "value": "Bearbeitete Neuausgabe"}, "latest_revision": 18, "revision": 18, "created": {"type": "/type/datetime", "value": "2009-12-09T06:52:50.872607"}, "last_modified": {"type": "/type/datetime", "value": "2023-01-31T17:11:49.536060"}} \ No newline at end of file diff --git a/Sources/Tests/MyLibraryDB_Tests/MyLibraryDB_Tests.csproj b/Sources/Tests/MyLibraryDB_Tests/MyLibraryDB_Tests.csproj new file mode 100644 index 0000000..2761bb3 --- /dev/null +++ b/Sources/Tests/MyLibraryDB_Tests/MyLibraryDB_Tests.csproj @@ -0,0 +1,125 @@ + + + + Exe + net7.0 + enable + enable + $(MSBuildProjectDirectory) + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + PreserveNewest + PreserveNewest + + + + + + + + + diff --git a/Sources/Tests/MyLibraryDB_Tests/Program.cs b/Sources/Tests/MyLibraryDB_Tests/Program.cs new file mode 100644 index 0000000..5be8e40 --- /dev/null +++ b/Sources/Tests/MyLibraryDB_Tests/Program.cs @@ -0,0 +1,19 @@ +// See https://aka.ms/new-console-template for more information + +using Microsoft.EntityFrameworkCore; +using MyLibraryDB; +using StubbedDB; + +//StubbedDTO.Stub.BasePath = Directory.GetCurrentDirectory(); + +using (var context = new MyLibraryStubbedContext()) +{ + foreach(var a in context.Authors.Include(auth => auth.Works)) + { + Console.WriteLine($"{a.Id} - {a.Name} (Works count: {a.Works.Count})"); + } + foreach(var b in context.Books.Include(book => book.Authors)) + { + Console.WriteLine($"{b.Id} - {b.Title} (Authors count: {b.Authors.Count})"); + } +} diff --git a/Sources/OpenLibraryWrapper_UT/BookController_UT.cs b/Sources/Tests/OpenLibraryWrapper_UT/BookController_UT.cs similarity index 98% rename from Sources/OpenLibraryWrapper_UT/BookController_UT.cs rename to Sources/Tests/OpenLibraryWrapper_UT/BookController_UT.cs index 80cf947..6d1a58f 100644 --- a/Sources/OpenLibraryWrapper_UT/BookController_UT.cs +++ b/Sources/Tests/OpenLibraryWrapper_UT/BookController_UT.cs @@ -75,6 +75,6 @@ public class BookController_UT long nbBooks = booksTupple.Item1; var books = booksTupple.Item2; - Assert.Equal(2, books.Count()); + Assert.Equal(4, books.Count()); } } diff --git a/Sources/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj b/Sources/Tests/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj similarity index 71% rename from Sources/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj rename to Sources/Tests/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj index ba2174d..9aa0b20 100644 --- a/Sources/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj +++ b/Sources/Tests/OpenLibraryWrapper_UT/OpenLibraryWrapper_UT.csproj @@ -26,10 +26,10 @@ - - - - - + + + + + diff --git a/Sources/OpenLibraryWrapper_UT/Usings.cs b/Sources/Tests/OpenLibraryWrapper_UT/Usings.cs similarity index 100% rename from Sources/OpenLibraryWrapper_UT/Usings.cs rename to Sources/Tests/OpenLibraryWrapper_UT/Usings.cs