Add category ladders

This commit is contained in:
Mbucari 2023-07-17 16:50:45 -06:00
parent 90eccbf2f6
commit ea6adeb58f
23 changed files with 983 additions and 122 deletions

View file

@ -55,10 +55,6 @@ namespace DataLayer
public DateTime? DatePublished { get; private set; }
public string Language { get; private set; }
// non-null. use "empty pattern"
internal int CategoryId { get; private set; }
public Category Category { get; private set; }
// is owned, not optional 1:1
public UserDefinedItem UserDefinedItem { get; private set; }
@ -79,7 +75,6 @@ namespace DataLayer
ContentType contentType,
IEnumerable<Contributor> authors,
IEnumerable<Contributor> narrators,
Category category,
string localeName)
{
// validate
@ -96,11 +91,10 @@ namespace DataLayer
// non-ef-ctor init.s
UserDefinedItem = new UserDefinedItem(this);
_contributorsLink = new HashSet<BookContributor>();
_categoriesLink = new HashSet<BookCategory>();
_seriesLink = new HashSet<SeriesBook>();
_supplements = new HashSet<Supplement>();
Category = category;
// simple assigns
UpdateTitle(title, subtitle);
Description = description?.Trim() ?? "";
@ -182,9 +176,30 @@ namespace DataLayer
return entry;
}
#region categories
private HashSet<BookCategory> _categoriesLink;
public IEnumerable<BookCategory> CategoriesLink => _categoriesLink?.ToList();
public void UpsertCategories(CategoryLadder ladder)
{
ArgumentValidator.EnsureNotNull(ladder, nameof(ladder));
#region series
private HashSet<SeriesBook> _seriesLink;
var singleBookCategory = _categoriesLink.SingleOrDefault(bc => bc.CategoryLadder.Equals(ladder));
if (singleBookCategory is null)
_categoriesLink.Add(new BookCategory(this, ladder));
else
{
for (var i = 0; i < ladder._categories.Count; i++)
{
//Update the category name
singleBookCategory.CategoryLadder._categories[i].Name = ladder._categories[i].Name;
}
}
}
#endregion
#region series
private HashSet<SeriesBook> _seriesLink;
public IEnumerable<SeriesBook> SeriesLink => _seriesLink?.ToList();
public void UpsertSeries(Series series, string order, DbContext context = null)
@ -234,15 +249,6 @@ namespace DataLayer
Language = language?.FirstCharToUpper() ?? Language;
}
public void UpdateCategory(Category category, DbContext context = null)
{
// since category is never null, nullity means it hasn't been loaded
if (Category is null)
getEntry(context).Reference(s => s.Category).Load();
Category = category;
}
public override string ToString() => $"[{AudibleProductId}] {TitleWithSubtitle}";
}
}

View file

@ -0,0 +1,20 @@
using Dinah.Core;
namespace DataLayer
{
public class BookCategory
{
internal int BookId { get; private set; }
internal int CategoryLadderId { get; private set; }
public Book Book { get; private set; }
public CategoryLadder CategoryLadder { get; private set; }
private BookCategory() { }
internal BookCategory(Book book, CategoryLadder categoriesList)
{
Book = ArgumentValidator.EnsureNotNull(book, nameof(book));
CategoryLadder = ArgumentValidator.EnsureNotNull(categoriesList, nameof(categoriesList));
}
}
}

View file

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using Dinah.Core;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
@ -15,20 +12,20 @@ namespace DataLayer
Id = id;
}
}
public class Category
{
// Empty is a special case. use private ctor w/o validation
public static Category GetEmpty() => new() { CategoryId = -1, AudibleCategoryId = "", Name = "" };
internal int CategoryId { get; private set; }
public string AudibleCategoryId { get; private set; }
public string Name { get; private set; }
public Category ParentCategory { get; private set; }
public string Name { get; internal set; }
private Category() { }
internal List<CategoryLadder> _categoryLadders = new();
public IReadOnlyCollection<CategoryLadder> CategoryLadders => _categoryLadders.AsReadOnly();
private Category() { }
/// <summary>special id class b/c it's too easy to get string order mixed up</summary>
public Category(AudibleCategoryId audibleSeriesId, string name, Category parentCategory = null)
public Category(AudibleCategoryId audibleSeriesId, string name)
{
ArgumentValidator.EnsureNotNull(audibleSeriesId, nameof(audibleSeriesId));
var id = audibleSeriesId.Id;
@ -37,15 +34,6 @@ namespace DataLayer
AudibleCategoryId = id;
Name = name;
UpdateParentCategory(parentCategory);
}
public void UpdateParentCategory(Category parentCategory)
{
// don't overwrite with null but not an error
if (parentCategory is not null)
ParentCategory = parentCategory;
}
public override string ToString() => $"[{AudibleCategoryId}] {Name}";

View file

@ -0,0 +1,48 @@
using Dinah.Core;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace DataLayer
{
public class CategoryLadder : IEquatable<CategoryLadder>
{
internal int CategoryLadderId { get; private set; }
internal List<Category> _categories;
public ReadOnlyCollection<Category> Categories => _categories.AsReadOnly();
private HashSet<BookCategory> _booksLink;
public IEnumerable<BookCategory> BooksLink => _booksLink?.ToList();
private CategoryLadder() { _categories = new(); }
public CategoryLadder(List<Category> categories)
{
ArgumentValidator.EnsureNotNull(categories, nameof(categories));
ArgumentValidator.EnsureGreaterThan(categories.Count, nameof(categories), 0);
_booksLink = new HashSet<BookCategory>();
_categories = categories;
}
public override int GetHashCode()
{
HashCode hashCode = default;
foreach (var category in _categories)
hashCode.Add(category.AudibleCategoryId);
return hashCode.ToHashCode();
}
public bool Equals(CategoryLadder other)
{
if (other?._categories is null)
return false;
return Equals(other._categories.Select(c => c.AudibleCategoryId));
}
public bool Equals(IEnumerable<string> categoryIds)
=> _categories.Select(c => c.AudibleCategoryId).SequenceEqual(categoryIds);
public override bool Equals(object obj) => obj is CategoryLadder other && Equals(other);
public override string ToString() => string.Join(" > ", _categories.Select(c => c.Name));
}
}