using System; using System.Collections.Generic; using System.Linq; using AudibleApiDTOs; using DataLayer; using InternalUtilities; namespace DtoImporterService { public class LibraryImporter : ItemsImporterBase { public LibraryImporter(LibationContext context) : base(context) { } public override IEnumerable Validate(IEnumerable importItems) => new LibraryValidator().Validate(importItems.Select(i => i.DtoItem)); protected override int DoImport(IEnumerable importItems) { new BookImporter(DbContext).Import(importItems); var qtyNew = upsertLibraryBooks(importItems); return qtyNew; } private int upsertLibraryBooks(IEnumerable importItems) { // technically, we should be able to have duplicate books from separate accounts. // this would violate the current pk and would be difficult to deal with elsewhere: // - what to show in the grid // - which to consider liberated // // sqlite cannot alter pk. the work around is an extensive headache. it'll be fixed in pre .net5/efcore5 // // currently, inserting LibraryBook will throw error if the same book is in multiple accounts for the same region. // // CURRENT SOLUTION: don't re-insert var currentLibraryProductIds = DbContext.Library.Select(l => l.Book.AudibleProductId).ToList(); var newItems = importItems.Where(dto => !currentLibraryProductIds.Contains(dto.DtoItem.ProductId)).ToList(); foreach (var newItem in newItems) { var libraryBook = new LibraryBook( DbContext.Books.Local.Single(b => b.AudibleProductId == newItem.DtoItem.ProductId), newItem.DtoItem.DateAdded, newItem.AccountId); DbContext.Library.Add(libraryBook); } // needed for v3 => v4 upgrade var toUpdate = DbContext.Library.Where(l => l.Account == null); foreach (var u in toUpdate) { var item = importItems.FirstOrDefault(ii => ii.DtoItem.ProductId == u.Book.AudibleProductId); if (item != null) u.UpdateAccount(item.AccountId); } var qtyNew = newItems.Count; return qtyNew; } } }