diff --git a/Source/ApplicationServices/LibraryCommands.cs b/Source/ApplicationServices/LibraryCommands.cs
index 3ceab15b..027ae536 100644
--- a/Source/ApplicationServices/LibraryCommands.cs
+++ b/Source/ApplicationServices/LibraryCommands.cs
@@ -266,30 +266,47 @@ namespace ApplicationServices
/// Occurs when , , or
/// changed values are successfully persisted.
///
- public static event EventHandler BookUserDefinedItemCommitted;
+ public static event EventHandler BookUserDefinedItemCommitted;
#region Update book details
- public static int UpdateUserDefinedItem(Book book)
+ public static int UpdateUserDefinedItem(params Book[] books) => UpdateUserDefinedItem(books.ToList());
+ public static int UpdateUserDefinedItem(IEnumerable books)
{
try
{
+ if (books is null || !books.Any())
+ return 0;
+
using var context = DbContexts.GetContext();
// Attach() NoTracking entities before SaveChanges()
- context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
+ foreach (var book in books)
+ context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
+
var qtyChanges = context.SaveChanges();
- if (qtyChanges > 0)
+ if (qtyChanges == 0)
+ return 0;
+
+ // semi-arbitrary. At some point it's more worth it to do a full re-index than to do one offs.
+ // I did not benchmark before choosing the number here
+ if (qtyChanges > 15)
+ SearchEngineCommands.FullReIndex();
+ else
{
- SearchEngineCommands.UpdateLiberatedStatus(book);
- SearchEngineCommands.UpdateBookTags(book);
- BookUserDefinedItemCommitted?.Invoke(null, book.AudibleProductId);
+ foreach (var book in books)
+ {
+ SearchEngineCommands.UpdateLiberatedStatus(book);
+ SearchEngineCommands.UpdateBookTags(book);
+ }
}
+ BookUserDefinedItemCommitted?.Invoke(null, null);
+
return qtyChanges;
}
catch (Exception ex)
{
- Log.Logger.Error(ex, $"Error updating {nameof(book.UserDefinedItem)}");
+ Log.Logger.Error(ex, $"Error updating {nameof(Book.UserDefinedItem)}");
throw;
}
}
diff --git a/Source/DataLayer/EfClasses/UserDefinedItem.cs b/Source/DataLayer/EfClasses/UserDefinedItem.cs
index f5da2cf8..28267a31 100644
--- a/Source/DataLayer/EfClasses/UserDefinedItem.cs
+++ b/Source/DataLayer/EfClasses/UserDefinedItem.cs
@@ -141,9 +141,11 @@ namespace DataLayer
get => _bookStatus;
set
{
- if (_bookStatus != value)
- {
- _bookStatus = value;
+ // PartialDownload is a live/ephemeral status, not a persistent one. Do not store
+ var displayStatus = value == LiberatedStatus.PartialDownload ? LiberatedStatus.NotLiberated : value;
+ if (_bookStatus != displayStatus)
+ {
+ _bookStatus = displayStatus;
OnItemChanged(nameof(BookStatus));
}
}
diff --git a/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs
index dca83b84..2433ac39 100644
--- a/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs
+++ b/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DataLayer;
@@ -61,7 +63,7 @@ namespace LibationWinForms.BookLiberation
await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync();
}
- public static async Task BackupAllBooksAsync()
+ public static async Task BackupAllBooksAsync(List libraryBooks = null)
{
Serilog.Log.Logger.Information("Begin " + nameof(BackupAllBooksAsync));
@@ -69,7 +71,7 @@ namespace LibationWinForms.BookLiberation
var logMe = LogMe.RegisterForm(automatedBackupsForm);
var backupBook = CreateBackupBook(logMe);
- await new BackupLoop(logMe, backupBook, automatedBackupsForm).RunBackupAsync();
+ await new BackupLoop(logMe, backupBook, automatedBackupsForm, libraryBooks).RunBackupAsync();
}
public static async Task ConvertAllBooksAsync()
@@ -307,13 +309,16 @@ An error occurred while trying to process this book.
protected override MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button1;
protected override DialogResult SkipResult => DialogResult.Ignore;
- public BackupLoop(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm)
- : base(logMe, processable, automatedBackupsForm) { }
+ private List libraryBooks { get; }
+
+ public BackupLoop(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm, List libraryBooks = null)
+ : base(logMe, processable, automatedBackupsForm)
+ => this.libraryBooks = libraryBooks ?? ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking();
protected override async Task RunAsync()
{
// support for 'skip this time only' requires state. iterators provide this state for free. therefore: use foreach/iterator here
- foreach (var libraryBook in Processable.GetValidLibraryBooks(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()))
+ foreach (var libraryBook in Processable.GetValidLibraryBooks(libraryBooks))
{
var keepGoing = await ProcessOneAsync(libraryBook, validate: false);
if (!keepGoing)