diff --git a/AaxDecrypter/AaxDecrypter.csproj b/AaxDecrypter/AaxDecrypter.csproj index 6dc7ad81..903d32d3 100644 --- a/AaxDecrypter/AaxDecrypter.csproj +++ b/AaxDecrypter/AaxDecrypter.csproj @@ -6,7 +6,7 @@ - + diff --git a/AppScaffolding/AppScaffolding.csproj b/AppScaffolding/AppScaffolding.csproj index 550a1c48..5c9edfa3 100644 --- a/AppScaffolding/AppScaffolding.csproj +++ b/AppScaffolding/AppScaffolding.csproj @@ -3,7 +3,7 @@ net5.0 - 6.0.2.1 + 6.0.3.1 diff --git a/ApplicationServices/LibraryExporter.cs b/ApplicationServices/LibraryExporter.cs index ead979cd..7e93dfe1 100644 --- a/ApplicationServices/LibraryExporter.cs +++ b/ApplicationServices/LibraryExporter.cs @@ -114,7 +114,7 @@ namespace ApplicationServices Publisher = a.Book.Publisher, HasPdf = a.Book.HasPdf, SeriesNames = a.Book.SeriesNames, - SeriesOrder = a.Book.SeriesLink.Any() ? a.Book.SeriesLink?.Select(sl => $"{sl.Index} : {sl.Series.Name}").Aggregate((a, b) => $"{a}, {b}") : "", + SeriesOrder = a.Book.SeriesLink.Any() ? a.Book.SeriesLink?.Select(sl => $"{sl.Order} : {sl.Series.Name}").Aggregate((a, b) => $"{a}, {b}") : "", CommunityRatingOverall = a.Book.Rating?.OverallRating, CommunityRatingPerformance = a.Book.Rating?.PerformanceRating, CommunityRatingStory = a.Book.Rating?.StoryRating, diff --git a/DataLayer/EfClasses/Book.cs b/DataLayer/EfClasses/Book.cs index f3f02c13..7688baf4 100644 --- a/DataLayer/EfClasses/Book.cs +++ b/DataLayer/EfClasses/Book.cs @@ -203,7 +203,7 @@ namespace DataLayer } } - public void UpsertSeries(Series series, float? index = null, DbContext context = null) + public void UpsertSeries(Series series, string order, DbContext context = null) { ArgumentValidator.EnsureNotNull(series, nameof(series)); @@ -214,9 +214,9 @@ namespace DataLayer var singleSeriesBook = _seriesLink.SingleOrDefault(sb => sb.Series == series); if (singleSeriesBook == null) - _seriesLink.Add(new SeriesBook(series, this, index)); + _seriesLink.Add(new SeriesBook(series, this, order)); else - singleSeriesBook.UpdateIndex(index); + singleSeriesBook.UpdateOrder(order); } #endregion diff --git a/DataLayer/EfClasses/Series.cs b/DataLayer/EfClasses/Series.cs index 6ec79d04..f419e549 100644 --- a/DataLayer/EfClasses/Series.cs +++ b/DataLayer/EfClasses/Series.cs @@ -48,25 +48,6 @@ namespace DataLayer Name = name; } - public void AddBook(Book book, float? index = null, DbContext context = null) - { - ArgumentValidator.EnsureNotNull(book, nameof(book)); - - // our add() is conditional upon what's already included in the collection. - // therefore if not loaded, a trip is required. might as well just load it - if (_booksLink == null) - { - ArgumentValidator.EnsureNotNull(context, nameof(context)); - if (!context.Entry(this).IsKeySet) - throw new InvalidOperationException("Could not add series"); - - context.Entry(this).Collection(s => s.BooksLink).Load(); - } - - if (_booksLink.SingleOrDefault(sb => sb.Book == book) == null) - _booksLink.Add(new SeriesBook(this, book, index)); - } - public override string ToString() => Name; } } diff --git a/DataLayer/EfClasses/SeriesBook.cs b/DataLayer/EfClasses/SeriesBook.cs index 09e23703..825d2515 100644 --- a/DataLayer/EfClasses/SeriesBook.cs +++ b/DataLayer/EfClasses/SeriesBook.cs @@ -7,32 +7,27 @@ namespace DataLayer internal int SeriesId { get; private set; } internal int BookId { get; private set; } - /// - /// "index" not "order". This is both for sequence and display - /// Float allows for in-between books. eg: 2.5 - /// To show 2 editions as the same book in a series, give them the same index - /// null IS NOT the same as 0. Some series call a book "book 0" - /// - public float? Index { get; private set; } + public string Order { get; private set; } + public float Index => StringLib.ExtractFirstNumber(Order); public Series Series { get; private set; } public Book Book { get; private set; } private SeriesBook() { } - internal SeriesBook(Series series, Book book, float? index = null) + internal SeriesBook(Series series, Book book, string order) { ArgumentValidator.EnsureNotNull(series, nameof(series)); ArgumentValidator.EnsureNotNull(book, nameof(book)); Series = series; Book = book; - Index = index; + Order = order; } - public void UpdateIndex(float? index) + public void UpdateOrder(string order) { - if (index.HasValue) - Index = index.Value; + if (!string.IsNullOrWhiteSpace(order)) + Order = order; } public override string ToString() => $"Series={Series} Book={Book}"; diff --git a/DataLayer/Migrations/20210922154900_AddSeriesOrderString.Designer.cs b/DataLayer/Migrations/20210922154900_AddSeriesOrderString.Designer.cs new file mode 100644 index 00000000..c867cd31 --- /dev/null +++ b/DataLayer/Migrations/20210922154900_AddSeriesOrderString.Designer.cs @@ -0,0 +1,390 @@ +// +using System; +using DataLayer; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace DataLayer.Migrations +{ + [DbContext(typeof(LibationContext))] + [Migration("20210922154900_AddSeriesOrderString")] + partial class AddSeriesOrderString + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.10"); + + modelBuilder.Entity("DataLayer.Book", b => + { + b.Property("BookId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleProductId") + .HasColumnType("TEXT"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("DatePublished") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IsAbridged") + .HasColumnType("INTEGER"); + + b.Property("LengthInMinutes") + .HasColumnType("INTEGER"); + + b.Property("Locale") + .HasColumnType("TEXT"); + + b.Property("PictureId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("BookId"); + + b.HasIndex("AudibleProductId"); + + b.HasIndex("CategoryId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("DataLayer.BookContributor", b => + { + b.Property("BookId") + .HasColumnType("INTEGER"); + + b.Property("ContributorId") + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("Order") + .HasColumnType("INTEGER"); + + b.HasKey("BookId", "ContributorId", "Role"); + + b.HasIndex("BookId"); + + b.HasIndex("ContributorId"); + + b.ToTable("BookContributor"); + }); + + modelBuilder.Entity("DataLayer.Category", b => + { + b.Property("CategoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleCategoryId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("ParentCategoryCategoryId") + .HasColumnType("INTEGER"); + + b.HasKey("CategoryId"); + + b.HasIndex("AudibleCategoryId"); + + b.HasIndex("ParentCategoryCategoryId"); + + b.ToTable("Categories"); + + b.HasData( + new + { + CategoryId = -1, + AudibleCategoryId = "", + Name = "" + }); + }); + + modelBuilder.Entity("DataLayer.Contributor", b => + { + b.Property("ContributorId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleContributorId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("ContributorId"); + + b.HasIndex("Name"); + + b.ToTable("Contributors"); + + b.HasData( + new + { + ContributorId = -1, + Name = "" + }); + }); + + modelBuilder.Entity("DataLayer.LibraryBook", b => + { + b.Property("BookId") + .HasColumnType("INTEGER"); + + b.Property("Account") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.HasKey("BookId"); + + b.ToTable("LibraryBooks"); + }); + + modelBuilder.Entity("DataLayer.Series", b => + { + b.Property("SeriesId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleSeriesId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("SeriesId"); + + b.HasIndex("AudibleSeriesId"); + + b.ToTable("Series"); + }); + + modelBuilder.Entity("DataLayer.SeriesBook", b => + { + b.Property("SeriesId") + .HasColumnType("INTEGER"); + + b.Property("BookId") + .HasColumnType("INTEGER"); + + b.Property("Order") + .HasColumnType("TEXT"); + + b.HasKey("SeriesId", "BookId"); + + b.HasIndex("BookId"); + + b.HasIndex("SeriesId"); + + b.ToTable("SeriesBook"); + }); + + modelBuilder.Entity("DataLayer.Book", b => + { + b.HasOne("DataLayer.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("DataLayer.Rating", "Rating", b1 => + { + b1.Property("BookId") + .HasColumnType("INTEGER"); + + b1.Property("OverallRating") + .HasColumnType("REAL"); + + b1.Property("PerformanceRating") + .HasColumnType("REAL"); + + b1.Property("StoryRating") + .HasColumnType("REAL"); + + b1.HasKey("BookId"); + + b1.ToTable("Books"); + + b1.WithOwner() + .HasForeignKey("BookId"); + }); + + b.OwnsMany("DataLayer.Supplement", "Supplements", b1 => + { + b1.Property("SupplementId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b1.Property("BookId") + .HasColumnType("INTEGER"); + + b1.Property("Url") + .HasColumnType("TEXT"); + + b1.HasKey("SupplementId"); + + b1.HasIndex("BookId"); + + b1.ToTable("Supplement"); + + b1.WithOwner("Book") + .HasForeignKey("BookId"); + + b1.Navigation("Book"); + }); + + b.OwnsOne("DataLayer.UserDefinedItem", "UserDefinedItem", b1 => + { + b1.Property("BookId") + .HasColumnType("INTEGER"); + + b1.Property("BookStatus") + .HasColumnType("INTEGER"); + + b1.Property("PdfStatus") + .HasColumnType("INTEGER"); + + b1.Property("Tags") + .HasColumnType("TEXT"); + + b1.HasKey("BookId"); + + b1.ToTable("UserDefinedItem"); + + b1.WithOwner("Book") + .HasForeignKey("BookId"); + + b1.OwnsOne("DataLayer.Rating", "Rating", b2 => + { + b2.Property("UserDefinedItemBookId") + .HasColumnType("INTEGER"); + + b2.Property("OverallRating") + .HasColumnType("REAL"); + + b2.Property("PerformanceRating") + .HasColumnType("REAL"); + + b2.Property("StoryRating") + .HasColumnType("REAL"); + + b2.HasKey("UserDefinedItemBookId"); + + b2.ToTable("UserDefinedItem"); + + b2.WithOwner() + .HasForeignKey("UserDefinedItemBookId"); + }); + + b1.Navigation("Book"); + + b1.Navigation("Rating"); + }); + + b.Navigation("Category"); + + b.Navigation("Rating"); + + b.Navigation("Supplements"); + + b.Navigation("UserDefinedItem"); + }); + + modelBuilder.Entity("DataLayer.BookContributor", b => + { + b.HasOne("DataLayer.Book", "Book") + .WithMany("ContributorsLink") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DataLayer.Contributor", "Contributor") + .WithMany("BooksLink") + .HasForeignKey("ContributorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Contributor"); + }); + + modelBuilder.Entity("DataLayer.Category", b => + { + b.HasOne("DataLayer.Category", "ParentCategory") + .WithMany() + .HasForeignKey("ParentCategoryCategoryId"); + + b.Navigation("ParentCategory"); + }); + + modelBuilder.Entity("DataLayer.LibraryBook", b => + { + b.HasOne("DataLayer.Book", "Book") + .WithOne() + .HasForeignKey("DataLayer.LibraryBook", "BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + }); + + modelBuilder.Entity("DataLayer.SeriesBook", b => + { + b.HasOne("DataLayer.Book", "Book") + .WithMany("SeriesLink") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DataLayer.Series", "Series") + .WithMany("BooksLink") + .HasForeignKey("SeriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("DataLayer.Book", b => + { + b.Navigation("ContributorsLink"); + + b.Navigation("SeriesLink"); + }); + + modelBuilder.Entity("DataLayer.Contributor", b => + { + b.Navigation("BooksLink"); + }); + + modelBuilder.Entity("DataLayer.Series", b => + { + b.Navigation("BooksLink"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DataLayer/Migrations/20210922154900_AddSeriesOrderString.cs b/DataLayer/Migrations/20210922154900_AddSeriesOrderString.cs new file mode 100644 index 00000000..ad16d48b --- /dev/null +++ b/DataLayer/Migrations/20210922154900_AddSeriesOrderString.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DataLayer.Migrations +{ + public partial class AddSeriesOrderString : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Index", + table: "SeriesBook"); + + migrationBuilder.AddColumn( + name: "Order", + table: "SeriesBook", + type: "TEXT", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Order", + table: "SeriesBook"); + + migrationBuilder.AddColumn( + name: "Index", + table: "SeriesBook", + type: "REAL", + nullable: true); + } + } +} diff --git a/DataLayer/Migrations/LibationContextModelSnapshot.cs b/DataLayer/Migrations/LibationContextModelSnapshot.cs index 4fde45e5..5453c4a9 100644 --- a/DataLayer/Migrations/LibationContextModelSnapshot.cs +++ b/DataLayer/Migrations/LibationContextModelSnapshot.cs @@ -14,7 +14,7 @@ namespace DataLayer.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "5.0.9"); + .HasAnnotation("ProductVersion", "5.0.10"); modelBuilder.Entity("DataLayer.Book", b => { @@ -185,8 +185,8 @@ namespace DataLayer.Migrations b.Property("BookId") .HasColumnType("INTEGER"); - b.Property("Index") - .HasColumnType("REAL"); + b.Property("Order") + .HasColumnType("TEXT"); b.HasKey("SeriesId", "BookId"); diff --git a/DtoImporterService/BookImporter.cs b/DtoImporterService/BookImporter.cs index 28d45f5d..0b30e52b 100644 --- a/DtoImporterService/BookImporter.cs +++ b/DtoImporterService/BookImporter.cs @@ -165,18 +165,7 @@ namespace DtoImporterService foreach (var seriesEntry in item.Series) { var series = DbContext.Series.Local.Single(s => seriesEntry.SeriesId == s.AudibleSeriesId); - - var index = 0f; - try - { - index = seriesEntry.Index; - } - catch (Exception ex) - { - Serilog.Log.Logger.Error(ex, $"Error parsing series index. Title: {item.Title}. ASIN: {item.Asin}. Series index: {seriesEntry.Sequence}"); - } - - book.UpsertSeries(series, index); + book.UpsertSeries(series, seriesEntry.Sequence); } } } diff --git a/FileManager/FileManager.csproj b/FileManager/FileManager.csproj index b08b6f10..737660bd 100644 --- a/FileManager/FileManager.csproj +++ b/FileManager/FileManager.csproj @@ -5,7 +5,7 @@ - + diff --git a/InternalUtilities/InternalUtilities.csproj b/InternalUtilities/InternalUtilities.csproj index 3532686e..dcfaa588 100644 --- a/InternalUtilities/InternalUtilities.csproj +++ b/InternalUtilities/InternalUtilities.csproj @@ -5,7 +5,7 @@ - + diff --git a/LibationWinForms/LibationWinForms.csproj b/LibationWinForms/LibationWinForms.csproj index 4cfac15a..94221bf6 100644 --- a/LibationWinForms/LibationWinForms.csproj +++ b/LibationWinForms/LibationWinForms.csproj @@ -29,7 +29,7 @@ - +