Set the stage for batch processing
This commit is contained in:
parent
dd5e162c10
commit
c6ce814e1c
@ -266,30 +266,47 @@ namespace ApplicationServices
|
|||||||
/// Occurs when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/>
|
/// Occurs when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/>
|
||||||
/// changed values are successfully persisted.
|
/// changed values are successfully persisted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static event EventHandler<string> BookUserDefinedItemCommitted;
|
public static event EventHandler BookUserDefinedItemCommitted;
|
||||||
|
|
||||||
#region Update book details
|
#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<Book> books)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (books is null || !books.Any())
|
||||||
|
return 0;
|
||||||
|
|
||||||
using var context = DbContexts.GetContext();
|
using var context = DbContexts.GetContext();
|
||||||
|
|
||||||
// Attach() NoTracking entities before SaveChanges()
|
// Attach() NoTracking entities before SaveChanges()
|
||||||
|
foreach (var book in books)
|
||||||
context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
||||||
|
|
||||||
var qtyChanges = context.SaveChanges();
|
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
|
||||||
|
{
|
||||||
|
foreach (var book in books)
|
||||||
{
|
{
|
||||||
SearchEngineCommands.UpdateLiberatedStatus(book);
|
SearchEngineCommands.UpdateLiberatedStatus(book);
|
||||||
SearchEngineCommands.UpdateBookTags(book);
|
SearchEngineCommands.UpdateBookTags(book);
|
||||||
BookUserDefinedItemCommitted?.Invoke(null, book.AudibleProductId);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BookUserDefinedItemCommitted?.Invoke(null, null);
|
||||||
|
|
||||||
return qtyChanges;
|
return qtyChanges;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Logger.Error(ex, $"Error updating {nameof(book.UserDefinedItem)}");
|
Log.Logger.Error(ex, $"Error updating {nameof(Book.UserDefinedItem)}");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,9 +141,11 @@ namespace DataLayer
|
|||||||
get => _bookStatus;
|
get => _bookStatus;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_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 = value;
|
_bookStatus = displayStatus;
|
||||||
OnItemChanged(nameof(BookStatus));
|
OnItemChanged(nameof(BookStatus));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
@ -61,7 +63,7 @@ namespace LibationWinForms.BookLiberation
|
|||||||
await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync();
|
await new BackupSingle(logMe, backupBook, libraryBook).RunBackupAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task BackupAllBooksAsync()
|
public static async Task BackupAllBooksAsync(List<LibraryBook> libraryBooks = null)
|
||||||
{
|
{
|
||||||
Serilog.Log.Logger.Information("Begin " + nameof(BackupAllBooksAsync));
|
Serilog.Log.Logger.Information("Begin " + nameof(BackupAllBooksAsync));
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ namespace LibationWinForms.BookLiberation
|
|||||||
var logMe = LogMe.RegisterForm(automatedBackupsForm);
|
var logMe = LogMe.RegisterForm(automatedBackupsForm);
|
||||||
var backupBook = CreateBackupBook(logMe);
|
var backupBook = CreateBackupBook(logMe);
|
||||||
|
|
||||||
await new BackupLoop(logMe, backupBook, automatedBackupsForm).RunBackupAsync();
|
await new BackupLoop(logMe, backupBook, automatedBackupsForm, libraryBooks).RunBackupAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ConvertAllBooksAsync()
|
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 MessageBoxDefaultButton SkipDialogDefaultButton => MessageBoxDefaultButton.Button1;
|
||||||
protected override DialogResult SkipResult => DialogResult.Ignore;
|
protected override DialogResult SkipResult => DialogResult.Ignore;
|
||||||
|
|
||||||
public BackupLoop(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm)
|
private List<LibraryBook> libraryBooks { get; }
|
||||||
: base(logMe, processable, automatedBackupsForm) { }
|
|
||||||
|
public BackupLoop(LogMe logMe, Processable processable, AutomatedBackupsForm automatedBackupsForm, List<LibraryBook> libraryBooks = null)
|
||||||
|
: base(logMe, processable, automatedBackupsForm)
|
||||||
|
=> this.libraryBooks = libraryBooks ?? ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking();
|
||||||
|
|
||||||
protected override async Task RunAsync()
|
protected override async Task RunAsync()
|
||||||
{
|
{
|
||||||
// support for 'skip this time only' requires state. iterators provide this state for free. therefore: use foreach/iterator here
|
// 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);
|
var keepGoing = await ProcessOneAsync(libraryBook, validate: false);
|
||||||
if (!keepGoing)
|
if (!keepGoing)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user