aboutsummaryrefslogtreecommitdiff
path: root/src/Jellyfin.Database/Jellyfin.Database.Implementations
diff options
context:
space:
mode:
Diffstat (limited to 'src/Jellyfin.Database/Jellyfin.Database.Implementations')
-rw-r--r--src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinQueryHelperExtensions.cs28
-rw-r--r--src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs8
2 files changed, 34 insertions, 2 deletions
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinQueryHelperExtensions.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinQueryHelperExtensions.cs
index 4d5cfb8c9b..f386e882e2 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinQueryHelperExtensions.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinQueryHelperExtensions.cs
@@ -54,6 +54,34 @@ public static class JellyfinQueryHelperExtensions
}
/// <summary>
+ /// Builds a query that checks referenced ItemValues for a cross BaseItem lookup.
+ /// </summary>
+ /// <param name="baseQuery">The source query.</param>
+ /// <param name="context">The database context.</param>
+ /// <param name="itemValueTypes">The type of item value to reference.</param>
+ /// <param name="referenceIds">The list of BaseItem ids to check matches.</param>
+ /// <param name="invert">If set an exclusion check is performed instead.</param>
+ /// <returns>A Query.</returns>
+ public static IQueryable<BaseItemEntity> WhereReferencedItemMultipleTypes(
+ this IQueryable<BaseItemEntity> baseQuery,
+ JellyfinDbContext context,
+ IList<ItemValueType> itemValueTypes,
+ IList<Guid> referenceIds,
+ bool invert = false)
+ {
+ var itemFilter = OneOrManyExpressionBuilder<BaseItemEntity, Guid>(referenceIds, f => f.Id);
+ var typeFilter = OneOrManyExpressionBuilder<ItemValue, ItemValueType>(itemValueTypes, iv => iv.Type);
+
+ return baseQuery.Where(item =>
+ context.ItemValues
+ .Where(typeFilter)
+ .Join(context.ItemValuesMap, e => e.ItemValueId, e => e.ItemValueId, (itemVal, map) => new { itemVal, map })
+ .Any(val =>
+ context.BaseItems.Where(itemFilter).Any(e => e.CleanName == val.itemVal.CleanValue)
+ && val.map.ItemId == item.Id) == EF.Constant(!invert));
+ }
+
+ /// <summary>
/// Builds a query expression that checks referenced ItemValues for a cross BaseItem lookup.
/// </summary>
/// <param name="context">The database context.</param>
diff --git a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
index b90a2e056f..7bcc7eeca4 100644
--- a/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
+++ b/src/Jellyfin.Database/Jellyfin.Database.Implementations/Locking/OptimisticLockBehavior.cs
@@ -52,10 +52,14 @@ public class OptimisticLockBehavior : IEntityFrameworkCoreLockingBehavior
_logger = logger;
_writePolicy = Policy
- .HandleInner<Exception>(e => e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase))
+ .HandleInner<Exception>(e =>
+ e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase) ||
+ e.Message.Contains("database table is locked", StringComparison.InvariantCultureIgnoreCase))
.WaitAndRetry(sleepDurations.Length, backoffProvider, RetryHandle);
_writeAsyncPolicy = Policy
- .HandleInner<Exception>(e => e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase))
+ .HandleInner<Exception>(e =>
+ e.Message.Contains("database is locked", StringComparison.InvariantCultureIgnoreCase) ||
+ e.Message.Contains("database table is locked", StringComparison.InvariantCultureIgnoreCase))
.WaitAndRetryAsync(sleepDurations.Length, backoffProvider, RetryHandle);
void RetryHandle(Exception exception, TimeSpan timespan, int retryNo, Context context)