db optimizations around names and case-sensitivity (#2749)
* generate (case-insensitive) unique names for fields that should be unique * move name case-insensitivity down to schema level * update changelog
This commit is contained in:
@@ -72,6 +72,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
- Sequential schedules: fix `count` instruction validation to accept integer (constant) or string (expression)
|
||||
- Fix multi-part episode grouping logic so that it does NOT require release date metadata for episodes within a single show
|
||||
- When **Treat Collections As Shows** is enabled (i.e. for crossover episodes) release date metadata is required for proper grouping
|
||||
- Fix *many* cases of duplicate names; enforce case-insensitive unique names at the schema level
|
||||
|
||||
### Changed
|
||||
- No longer round framerate to nearest integer when normalizing framerate
|
||||
|
||||
@@ -1,57 +1,67 @@
|
||||
using Bugsnag;
|
||||
using ErsatzTV.Core;
|
||||
using ErsatzTV.Core;
|
||||
using ErsatzTV.Core.Domain.Filler;
|
||||
using ErsatzTV.Infrastructure.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ErsatzTV.Application.Filler;
|
||||
|
||||
public class CreateFillerPresetHandler : IRequestHandler<CreateFillerPreset, Either<BaseError, Unit>>
|
||||
public class CreateFillerPresetHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
: IRequestHandler<CreateFillerPreset, Either<BaseError, Unit>>
|
||||
{
|
||||
private readonly IClient _client;
|
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||
|
||||
public CreateFillerPresetHandler(IClient client, IDbContextFactory<TvContext> dbContextFactory)
|
||||
{
|
||||
_client = client;
|
||||
_dbContextFactory = dbContextFactory;
|
||||
}
|
||||
|
||||
public async Task<Either<BaseError, Unit>> Handle(CreateFillerPreset request, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Validation<BaseError, FillerPreset> validation = await Validate(dbContext, request);
|
||||
return await validation.Apply(fp => Persist(dbContext, fp, cancellationToken));
|
||||
}
|
||||
|
||||
private static async Task<Unit> Persist(
|
||||
TvContext dbContext,
|
||||
FillerPreset fillerPreset,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await dbContext.FillerPresets.AddAsync(fillerPreset, cancellationToken);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
return Unit.Default;
|
||||
}
|
||||
|
||||
private static Task<Validation<BaseError, FillerPreset>> Validate(
|
||||
TvContext dbContext,
|
||||
CreateFillerPreset request) =>
|
||||
ValidateName(dbContext, request).MapT(name => new FillerPreset
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Name = name,
|
||||
FillerKind = request.FillerKind,
|
||||
FillerMode = request.FillerMode,
|
||||
Duration = request.Duration,
|
||||
Count = request.Count,
|
||||
PadToNearestMinute = request.PadToNearestMinute,
|
||||
AllowWatermarks = request.AllowWatermarks,
|
||||
CollectionType = request.CollectionType,
|
||||
CollectionId = request.CollectionId,
|
||||
MediaItemId = request.MediaItemId,
|
||||
MultiCollectionId = request.MultiCollectionId,
|
||||
SmartCollectionId = request.SmartCollectionId,
|
||||
PlaylistId = request.PlaylistId,
|
||||
Expression = request.FillerKind is FillerKind.MidRoll ? request.Expression : null,
|
||||
UseChaptersAsMediaItems =
|
||||
request.FillerKind is not FillerKind.Fallback && request.UseChaptersAsMediaItems
|
||||
});
|
||||
|
||||
var fillerPreset = new FillerPreset
|
||||
{
|
||||
Name = request.Name,
|
||||
FillerKind = request.FillerKind,
|
||||
FillerMode = request.FillerMode,
|
||||
Duration = request.Duration,
|
||||
Count = request.Count,
|
||||
PadToNearestMinute = request.PadToNearestMinute,
|
||||
AllowWatermarks = request.AllowWatermarks,
|
||||
CollectionType = request.CollectionType,
|
||||
CollectionId = request.CollectionId,
|
||||
MediaItemId = request.MediaItemId,
|
||||
MultiCollectionId = request.MultiCollectionId,
|
||||
SmartCollectionId = request.SmartCollectionId,
|
||||
PlaylistId = request.PlaylistId,
|
||||
Expression = request.FillerKind is FillerKind.MidRoll ? request.Expression : null,
|
||||
UseChaptersAsMediaItems =
|
||||
request.FillerKind is not FillerKind.Fallback && request.UseChaptersAsMediaItems
|
||||
};
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(
|
||||
TvContext dbContext,
|
||||
CreateFillerPreset request)
|
||||
{
|
||||
Validation<BaseError, string> result1 = request.NotEmpty(fp => fp.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(fp => fp.Name));
|
||||
|
||||
await dbContext.FillerPresets.AddAsync(fillerPreset, cancellationToken);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
bool duplicateName = await dbContext.FillerPresets
|
||||
.AnyAsync(fp => fp.Name == request.Name);
|
||||
|
||||
return Unit.Default;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_client.Notify(ex);
|
||||
return BaseError.New(ex.Message);
|
||||
}
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Filler preset name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => request.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,27 +6,21 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ErsatzTV.Application.Filler;
|
||||
|
||||
public class UpdateFillerPresetHandler : IRequestHandler<UpdateFillerPreset, Either<BaseError, Unit>>
|
||||
public class UpdateFillerPresetHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
: IRequestHandler<UpdateFillerPreset, Either<BaseError, Unit>>
|
||||
{
|
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||
|
||||
public UpdateFillerPresetHandler(IDbContextFactory<TvContext> dbContextFactory) =>
|
||||
_dbContextFactory = dbContextFactory;
|
||||
|
||||
public async Task<Either<BaseError, Unit>> Handle(UpdateFillerPreset request, CancellationToken cancellationToken)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Validation<BaseError, FillerPreset> validation = await FillerPresetMustExist(
|
||||
dbContext,
|
||||
request,
|
||||
cancellationToken);
|
||||
return await validation.Apply(ps => ApplyUpdateRequest(dbContext, ps, request));
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Validation<BaseError, FillerPreset> validation = await Validate(dbContext, request, cancellationToken);
|
||||
return await validation.Apply(ps => ApplyUpdateRequest(dbContext, ps, request, cancellationToken));
|
||||
}
|
||||
|
||||
private static async Task<Unit> ApplyUpdateRequest(
|
||||
TvContext dbContext,
|
||||
FillerPreset existing,
|
||||
UpdateFillerPreset request)
|
||||
UpdateFillerPreset request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
existing.Name = request.Name;
|
||||
existing.FillerKind = request.FillerKind;
|
||||
@@ -45,16 +39,40 @@ public class UpdateFillerPresetHandler : IRequestHandler<UpdateFillerPreset, Eit
|
||||
existing.UseChaptersAsMediaItems =
|
||||
request.FillerKind is not FillerKind.Fallback && request.UseChaptersAsMediaItems;
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return Unit.Default;
|
||||
}
|
||||
|
||||
private static async Task<Validation<BaseError, FillerPreset>> Validate(
|
||||
TvContext dbContext,
|
||||
UpdateFillerPreset request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(await FillerPresetMustExist(dbContext, request, cancellationToken), await ValidateName(dbContext, request))
|
||||
.Apply((collectionToUpdate, _) => collectionToUpdate);
|
||||
|
||||
private static Task<Validation<BaseError, FillerPreset>> FillerPresetMustExist(
|
||||
TvContext dbContext,
|
||||
UpdateFillerPreset request,
|
||||
CancellationToken cancellationToken) =>
|
||||
dbContext.FillerPresets
|
||||
.SelectOneAsync(ps => ps.Id, ps => ps.Id == request.Id, cancellationToken)
|
||||
.Map(o => o.ToValidation<BaseError>("FillerPreset does not exist"));
|
||||
.Map(o => o.ToValidation<BaseError>("Filler preset does not exist"));
|
||||
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(
|
||||
TvContext dbContext,
|
||||
UpdateFillerPreset request)
|
||||
{
|
||||
Validation<BaseError, string> result1 = request.NotEmpty(fp => fp.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(fp => fp.Name));
|
||||
|
||||
bool duplicateName = await dbContext.FillerPresets
|
||||
.AnyAsync(c => c.Id != request.Id && c.Name == request.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Filler preset name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => request.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,22 +4,18 @@ using static ErsatzTV.Application.Filler.Mapper;
|
||||
|
||||
namespace ErsatzTV.Application.Filler;
|
||||
|
||||
public class GetPagedFillerPresetsHandler : IRequestHandler<GetPagedFillerPresets, PagedFillerPresetsViewModel>
|
||||
public class GetPagedFillerPresetsHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
: IRequestHandler<GetPagedFillerPresets, PagedFillerPresetsViewModel>
|
||||
{
|
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||
|
||||
public GetPagedFillerPresetsHandler(IDbContextFactory<TvContext> dbContextFactory) =>
|
||||
_dbContextFactory = dbContextFactory;
|
||||
|
||||
public async Task<PagedFillerPresetsViewModel> Handle(
|
||||
GetPagedFillerPresets request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
int count = await dbContext.FillerPresets.CountAsync(cancellationToken);
|
||||
List<FillerPresetViewModel> page = await dbContext.FillerPresets
|
||||
.AsNoTracking()
|
||||
.OrderBy(f => EF.Functions.Collate(f.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(f => f.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -49,16 +49,15 @@ public class CreateCollectionHandler :
|
||||
TvContext dbContext,
|
||||
CreateCollection createCollection)
|
||||
{
|
||||
List<string> allNames = await dbContext.Collections
|
||||
.Map(c => c.Name)
|
||||
.ToListAsync();
|
||||
|
||||
Validation<BaseError, string> result1 = createCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
var result2 = Optional(createCollection.Name)
|
||||
.Where(name => !allNames.Contains(name))
|
||||
.ToValidation<BaseError>("Collection name must be unique");
|
||||
bool duplicateName = await dbContext.Collections
|
||||
.AnyAsync(c => c.Name == createCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Collection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createCollection.Name);
|
||||
}
|
||||
|
||||
@@ -92,16 +92,15 @@ public class CreateMultiCollectionHandler :
|
||||
TvContext dbContext,
|
||||
CreateMultiCollection createMultiCollection)
|
||||
{
|
||||
List<string> allNames = await dbContext.MultiCollections
|
||||
.Map(c => c.Name)
|
||||
.ToListAsync();
|
||||
|
||||
Validation<BaseError, string> result1 = createMultiCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createMultiCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
var result2 = Optional(createMultiCollection.Name)
|
||||
.Where(name => !allNames.Contains(name))
|
||||
.ToValidation<BaseError>("MultiCollection name must be unique");
|
||||
bool duplicateName = await dbContext.MultiCollections
|
||||
.AnyAsync(c => c.Name == createMultiCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("MultiCollection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createMultiCollection.Name);
|
||||
}
|
||||
|
||||
@@ -40,11 +40,10 @@ public class CreatePlaylistHandler(IDbContextFactory<TvContext> dbContextFactory
|
||||
return BaseError.New($"Playlist name \"{request.Name}\" is invalid");
|
||||
}
|
||||
|
||||
Option<Playlist> maybeExisting = await dbContext.Playlists
|
||||
.FirstOrDefaultAsync(r => r.PlaylistGroupId == request.PlaylistGroupId && r.Name == request.Name)
|
||||
.Map(Optional);
|
||||
bool duplicate = await dbContext.Playlists
|
||||
.AnyAsync(r => r.PlaylistGroupId == request.PlaylistGroupId && r.Name == request.Name);
|
||||
|
||||
return maybeExisting.IsSome
|
||||
return duplicate
|
||||
? BaseError.New($"A playlist named \"{request.Name}\" already exists in that playlist group")
|
||||
: Success<BaseError, string>(request.Name);
|
||||
}
|
||||
|
||||
@@ -46,16 +46,15 @@ public class CreateRerunCollectionHandler(IDbContextFactory<TvContext> dbContext
|
||||
TvContext dbContext,
|
||||
CreateRerunCollection createCollection)
|
||||
{
|
||||
List<string> allNames = await dbContext.RerunCollections
|
||||
.Map(c => c.Name)
|
||||
.ToListAsync();
|
||||
|
||||
Validation<BaseError, string> result1 = createCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
var result2 = Optional(createCollection.Name)
|
||||
.Where(name => !allNames.Contains(name))
|
||||
.ToValidation<BaseError>("Rerun collection name must be unique");
|
||||
bool duplicateName = await dbContext.RerunCollections
|
||||
.AnyAsync(c => c.Name == createCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Rerun collection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createCollection.Name);
|
||||
}
|
||||
|
||||
@@ -59,17 +59,16 @@ public class CreateSmartCollectionHandler :
|
||||
TvContext dbContext,
|
||||
CreateSmartCollection createSmartCollection)
|
||||
{
|
||||
List<string> allNames = await dbContext.SmartCollections
|
||||
.Map(c => c.Name)
|
||||
.ToListAsync();
|
||||
bool duplicateName = await dbContext.SmartCollections
|
||||
.AnyAsync(c => c.Name == createSmartCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("SmartCollection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
Validation<BaseError, string> result1 = createSmartCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createSmartCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
var result2 = Optional(createSmartCollection.Name)
|
||||
.Where(name => !allNames.Contains(name, StringComparer.OrdinalIgnoreCase))
|
||||
.ToValidation<BaseError>("SmartCollection name must be unique");
|
||||
|
||||
return (result1, result2).Apply((_, _) => createSmartCollection.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class UpdateCollectionHandler : IRequestHandler<UpdateCollection, Either<
|
||||
TvContext dbContext,
|
||||
UpdateCollection request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(await CollectionMustExist(dbContext, request, cancellationToken), ValidateName(request))
|
||||
(await CollectionMustExist(dbContext, request, cancellationToken), await ValidateName(dbContext, request))
|
||||
.Apply((collectionToUpdate, _) => collectionToUpdate);
|
||||
|
||||
private static Task<Validation<BaseError, Collection>> CollectionMustExist(
|
||||
@@ -81,7 +81,20 @@ public class UpdateCollectionHandler : IRequestHandler<UpdateCollection, Either<
|
||||
.SelectOneAsync(c => c.Id, c => c.Id == updateCollection.CollectionId, cancellationToken)
|
||||
.Map(o => o.ToValidation<BaseError>("Collection does not exist."));
|
||||
|
||||
private static Validation<BaseError, string> ValidateName(UpdateCollection updateSimpleMediaCollection) =>
|
||||
updateSimpleMediaCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => updateSimpleMediaCollection.NotLongerThan(50)(c => c.Name));
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(
|
||||
TvContext dbContext,
|
||||
UpdateCollection updateCollection)
|
||||
{
|
||||
Validation<BaseError, string> result1 = updateCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => updateCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
bool duplicateName = await dbContext.Collections
|
||||
.AnyAsync(c => c.Id != updateCollection.CollectionId && c.Name == updateCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Collection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => updateCollection.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,17 +155,15 @@ public class UpdateMultiCollectionHandler : IRequestHandler<UpdateMultiCollectio
|
||||
TvContext dbContext,
|
||||
UpdateMultiCollection updateMultiCollection)
|
||||
{
|
||||
List<string> allNames = await dbContext.MultiCollections
|
||||
.Filter(mc => mc.Id != updateMultiCollection.MultiCollectionId)
|
||||
.Map(c => c.Name)
|
||||
.ToListAsync();
|
||||
|
||||
Validation<BaseError, string> result1 = updateMultiCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => updateMultiCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
var result2 = Optional(updateMultiCollection.Name)
|
||||
.Where(name => !allNames.Contains(name))
|
||||
.ToValidation<BaseError>("MultiCollection name must be unique");
|
||||
bool duplicateName = await dbContext.MultiCollections
|
||||
.AnyAsync(c => c.Id != updateMultiCollection.MultiCollectionId && c.Name == updateMultiCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("MultiCollection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => updateMultiCollection.Name);
|
||||
}
|
||||
|
||||
@@ -54,10 +54,12 @@ public class UpdateRerunCollectionHandler(
|
||||
return Unit.Default;
|
||||
}
|
||||
|
||||
private static Task<Validation<BaseError, RerunCollection>> Validate(
|
||||
private static async Task<Validation<BaseError, RerunCollection>> Validate(
|
||||
TvContext dbContext,
|
||||
UpdateRerunCollection request,
|
||||
CancellationToken cancellationToken) => RerunCollectionMustExist(dbContext, request, cancellationToken);
|
||||
CancellationToken cancellationToken) =>
|
||||
(await RerunCollectionMustExist(dbContext, request, cancellationToken), await ValidateName(dbContext, request))
|
||||
.Apply((collectionToUpdate, _) => collectionToUpdate);
|
||||
|
||||
private static Task<Validation<BaseError, RerunCollection>> RerunCollectionMustExist(
|
||||
TvContext dbContext,
|
||||
@@ -66,4 +68,21 @@ public class UpdateRerunCollectionHandler(
|
||||
dbContext.RerunCollections
|
||||
.SelectOneAsync(c => c.Id, c => c.Id == updateCollection.RerunCollectionId, cancellationToken)
|
||||
.Map(o => o.ToValidation<BaseError>("Rerun collection does not exist."));
|
||||
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(
|
||||
TvContext dbContext,
|
||||
UpdateRerunCollection updateCollection)
|
||||
{
|
||||
Validation<BaseError, string> result1 = updateCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => updateCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
bool duplicateName = await dbContext.RerunCollections
|
||||
.AnyAsync(c => c.Id != updateCollection.RerunCollectionId && c.Name == updateCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Rerun collection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => updateCollection.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,17 +88,15 @@ public class
|
||||
TvContext dbContext,
|
||||
UpdateSmartCollection updateCollection)
|
||||
{
|
||||
List<string> allNames = await dbContext.SmartCollections
|
||||
.Where(c => c.Id != updateCollection.Id)
|
||||
.Map(c => c.Name)
|
||||
.ToListAsync();
|
||||
|
||||
Validation<BaseError, string> result1 = updateCollection.NotEmpty(c => c.Name)
|
||||
.Bind(_ => updateCollection.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
var result2 = Optional(updateCollection.Name)
|
||||
.Where(name => !allNames.Contains(name, StringComparer.OrdinalIgnoreCase))
|
||||
.ToValidation<BaseError>("SmartCollection name must be unique");
|
||||
bool duplicateName = await dbContext.SmartCollections
|
||||
.AnyAsync(c => c.Id != updateCollection.Id && c.Name == updateCollection.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("SmartCollection name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => updateCollection.Name);
|
||||
}
|
||||
|
||||
@@ -19,13 +19,11 @@ public class GetPagedCollectionsHandler(IDbContextFactory<TvContext> dbContextFa
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Query))
|
||||
{
|
||||
query = query.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"));
|
||||
query = query.Where(c => EF.Functions.Like(c.Name, $"%{request.Query}%"));
|
||||
}
|
||||
|
||||
List<MediaCollectionViewModel> page = await query
|
||||
.OrderBy(c => EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(c => c.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -19,13 +19,11 @@ public class GetPagedMultiCollectionsHandler(IDbContextFactory<TvContext> dbCont
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Query))
|
||||
{
|
||||
query = query.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"));
|
||||
query = query.Where(mc => EF.Functions.Like(mc.Name, $"%{request.Query}%"));
|
||||
}
|
||||
|
||||
List<MultiCollectionViewModel> page = await query
|
||||
.OrderBy(f => EF.Functions.Collate(f.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(mc => mc.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.Include(mc => mc.MultiCollectionItems)
|
||||
|
||||
@@ -19,13 +19,11 @@ public class GetPagedRerunCollectionsHandler(IDbContextFactory<TvContext> dbCont
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Query))
|
||||
{
|
||||
query = query.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"));
|
||||
query = query.Where(rc => EF.Functions.Like(rc.Name, $"%{request.Query}%"));
|
||||
}
|
||||
|
||||
List<RerunCollectionViewModel> page = await query
|
||||
.OrderBy(f => EF.Functions.Collate(f.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(rc => rc.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -19,13 +19,11 @@ public class GetPagedSmartCollectionsHandler(IDbContextFactory<TvContext> dbCont
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Query))
|
||||
{
|
||||
query = query.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"));
|
||||
query = query.Where(sc => EF.Functions.Like(sc.Name, $"%{request.Query}%"));
|
||||
}
|
||||
|
||||
List<SmartCollectionViewModel> page = await query
|
||||
.OrderBy(s => EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(s => s.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -4,22 +4,18 @@ using static ErsatzTV.Application.MediaCollections.Mapper;
|
||||
|
||||
namespace ErsatzTV.Application.MediaCollections;
|
||||
|
||||
public class GetPagedTraktListsHandler : IRequestHandler<GetPagedTraktLists, PagedTraktListsViewModel>
|
||||
public class GetPagedTraktListsHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
: IRequestHandler<GetPagedTraktLists, PagedTraktListsViewModel>
|
||||
{
|
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||
|
||||
public GetPagedTraktListsHandler(IDbContextFactory<TvContext> dbContextFactory) =>
|
||||
_dbContextFactory = dbContextFactory;
|
||||
|
||||
public async Task<PagedTraktListsViewModel> Handle(
|
||||
GetPagedTraktLists request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
int count = await dbContext.TraktLists.CountAsync(cancellationToken);
|
||||
List<TraktListViewModel> page = await dbContext.TraktLists
|
||||
.AsNoTracking()
|
||||
.OrderBy(f => EF.Functions.Collate(f.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(l => l.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.Include(l => l.Items)
|
||||
|
||||
@@ -24,9 +24,7 @@ public class GetPagedPlayoutsHandler(IDbContextFactory<TvContext> dbContextFacto
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Query))
|
||||
{
|
||||
query = query.Where(p => EF.Functions.Like(
|
||||
EF.Functions.Collate(p.Channel.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"));
|
||||
query = query.Where(p => EF.Functions.Like(p.Channel.Name, $"%{request.Query}%"));
|
||||
}
|
||||
|
||||
List<PlayoutNameViewModel> page = await query
|
||||
|
||||
@@ -51,12 +51,12 @@ public class CreateProgramScheduleHandler(IDbContextFactory<TvContext> dbContext
|
||||
Validation<BaseError, string> result1 = createProgramSchedule.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createProgramSchedule.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
int duplicateNameCount = await dbContext.ProgramSchedules
|
||||
.CountAsync(ps => ps.Name == createProgramSchedule.Name);
|
||||
bool duplicateName = await dbContext.ProgramSchedules
|
||||
.AnyAsync(ps => ps.Name == createProgramSchedule.Name);
|
||||
|
||||
var result2 = Optional(duplicateNameCount)
|
||||
.Where(count => count == 0)
|
||||
.ToValidation<BaseError>("Schedule name must be unique");
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Schedule name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createProgramSchedule.Name);
|
||||
}
|
||||
|
||||
@@ -9,25 +9,17 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules;
|
||||
|
||||
public class UpdateProgramScheduleHandler :
|
||||
IRequestHandler<UpdateProgramSchedule, Either<BaseError, UpdateProgramScheduleResult>>
|
||||
public class UpdateProgramScheduleHandler(
|
||||
IDbContextFactory<TvContext> dbContextFactory,
|
||||
ChannelWriter<IBackgroundServiceRequest> channel)
|
||||
:
|
||||
IRequestHandler<UpdateProgramSchedule, Either<BaseError, UpdateProgramScheduleResult>>
|
||||
{
|
||||
private readonly ChannelWriter<IBackgroundServiceRequest> _channel;
|
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||
|
||||
public UpdateProgramScheduleHandler(
|
||||
IDbContextFactory<TvContext> dbContextFactory,
|
||||
ChannelWriter<IBackgroundServiceRequest> channel)
|
||||
{
|
||||
_dbContextFactory = dbContextFactory;
|
||||
_channel = channel;
|
||||
}
|
||||
|
||||
public async Task<Either<BaseError, UpdateProgramScheduleResult>> Handle(
|
||||
UpdateProgramSchedule request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Validation<BaseError, ProgramSchedule> validation = await Validate(dbContext, request, cancellationToken);
|
||||
return await validation.Apply(ps => ApplyUpdateRequest(dbContext, ps, request));
|
||||
}
|
||||
@@ -64,7 +56,7 @@ public class UpdateProgramScheduleHandler :
|
||||
|
||||
foreach (int playoutId in playoutIds)
|
||||
{
|
||||
await _channel.WriteAsync(new BuildPlayout(playoutId, PlayoutBuildMode.Refresh));
|
||||
await channel.WriteAsync(new BuildPlayout(playoutId, PlayoutBuildMode.Refresh));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +67,7 @@ public class UpdateProgramScheduleHandler :
|
||||
TvContext dbContext,
|
||||
UpdateProgramSchedule request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(await ProgramScheduleMustExist(dbContext, request, cancellationToken), ValidateName(request))
|
||||
(await ProgramScheduleMustExist(dbContext, request, cancellationToken), await ValidateName(dbContext, request, cancellationToken))
|
||||
.Apply((programSchedule, _) => programSchedule);
|
||||
|
||||
private static Task<Validation<BaseError, ProgramSchedule>> ProgramScheduleMustExist(
|
||||
@@ -84,9 +76,23 @@ public class UpdateProgramScheduleHandler :
|
||||
CancellationToken cancellationToken) =>
|
||||
dbContext.ProgramSchedules
|
||||
.SelectOneAsync(ps => ps.Id, ps => ps.Id == request.ProgramScheduleId, cancellationToken)
|
||||
.Map(o => o.ToValidation<BaseError>("ProgramSchedule does not exist"));
|
||||
.Map(o => o.ToValidation<BaseError>("Schedule does not exist"));
|
||||
|
||||
private static Validation<BaseError, string> ValidateName(UpdateProgramSchedule request) =>
|
||||
request.NotEmpty(c => c.Name)
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(
|
||||
TvContext dbContext,
|
||||
UpdateProgramSchedule request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Validation<BaseError, string> result1 = request.NotEmpty(c => c.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
bool duplicateName = await dbContext.ProgramSchedules
|
||||
.AnyAsync(c => c.Id != request.ProgramScheduleId && c.Name == request.Name, cancellationToken);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Schedule name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => request.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,11 @@ public class GetPagedProgramSchedulesHandler(IDbContextFactory<TvContext> dbCont
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Query))
|
||||
{
|
||||
query = query.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"));
|
||||
query = query.Where(ps => EF.Functions.Like(ps.Name, $"%{request.Query}%"));
|
||||
}
|
||||
|
||||
List<ProgramScheduleViewModel> page = await query
|
||||
.OrderBy(s => EF.Functions.Collate(s.Name, TvContext.CaseInsensitiveCollation))
|
||||
.OrderBy(ps => ps.Name)
|
||||
.Skip(request.PageNum * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -92,17 +92,15 @@ public class CopyBlockHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(TvContext dbContext, CopyBlock request)
|
||||
{
|
||||
List<string> allNames = await dbContext.Blocks
|
||||
.Where(b => b.BlockGroupId == request.NewBlockGroupId)
|
||||
.Map(ps => ps.Name)
|
||||
.ToListAsync();
|
||||
|
||||
Validation<BaseError, string> result1 = request.NotEmpty(c => c.NewBlockName)
|
||||
.Bind(_ => request.NotLongerThan(50)(c => c.NewBlockName));
|
||||
|
||||
var result2 = Optional(request.NewBlockName)
|
||||
.Where(name => !allNames.Contains(name))
|
||||
.ToValidation<BaseError>("Block name must be unique within the block group.");
|
||||
bool duplicateName = await dbContext.Blocks
|
||||
.AnyAsync(b => b.BlockGroupId == request.NewBlockGroupId && b.Name == request.NewBlockName);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Block name must be unique within the block group")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => request.NewBlockName);
|
||||
}
|
||||
|
||||
@@ -34,12 +34,12 @@ public class CreateBlockGroupHandler(IDbContextFactory<TvContext> dbContextFacto
|
||||
Validation<BaseError, string> result1 = createBlockGroup.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createBlockGroup.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
int duplicateNameCount = await dbContext.BlockGroups
|
||||
.CountAsync(ps => ps.Name == createBlockGroup.Name);
|
||||
bool duplicateName = await dbContext.BlockGroups
|
||||
.AnyAsync(bg => bg.Name == createBlockGroup.Name);
|
||||
|
||||
var result2 = Optional(duplicateNameCount)
|
||||
.Where(count => count == 0)
|
||||
.ToValidation<BaseError>("Block group name must be unique");
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Block group name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createBlockGroup.Name);
|
||||
}
|
||||
|
||||
@@ -42,11 +42,10 @@ public class CreateBlockHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
return BaseError.New($"Block name \"{request.Name}\" is invalid");
|
||||
}
|
||||
|
||||
Option<Block> maybeExisting = await dbContext.Blocks
|
||||
.FirstOrDefaultAsync(r => r.BlockGroupId == request.BlockGroupId && r.Name == request.Name)
|
||||
.Map(Optional);
|
||||
bool duplicate = await dbContext.Blocks
|
||||
.AnyAsync(r => r.BlockGroupId == request.BlockGroupId && r.Name == request.Name);
|
||||
|
||||
return maybeExisting.IsSome
|
||||
return duplicate
|
||||
? BaseError.New($"A block named \"{request.Name}\" already exists in that block group")
|
||||
: Success<BaseError, string>(request.Name);
|
||||
}
|
||||
|
||||
@@ -34,12 +34,12 @@ public class CreateDecoGroupHandler(IDbContextFactory<TvContext> dbContextFactor
|
||||
Validation<BaseError, string> result1 = createDecoGroup.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createDecoGroup.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
int duplicateNameCount = await dbContext.DecoGroups
|
||||
.CountAsync(ps => ps.Name == createDecoGroup.Name);
|
||||
bool duplicateName = await dbContext.DecoGroups
|
||||
.AnyAsync(ps => ps.Name == createDecoGroup.Name);
|
||||
|
||||
var result2 = Optional(duplicateNameCount)
|
||||
.Where(count => count == 0)
|
||||
.ToValidation<BaseError>("Deco group name must be unique");
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Deco group name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createDecoGroup.Name);
|
||||
}
|
||||
|
||||
@@ -44,11 +44,10 @@ public class CreateDecoHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
return BaseError.New($"Deco name \"{request.Name}\" is invalid");
|
||||
}
|
||||
|
||||
Option<Deco> maybeExisting = await dbContext.Decos
|
||||
.FirstOrDefaultAsync(r => r.DecoGroupId == request.DecoGroupId && r.Name == request.Name)
|
||||
.Map(Optional);
|
||||
bool duplicateName = await dbContext.Decos
|
||||
.AnyAsync(r => r.DecoGroupId == request.DecoGroupId && r.Name == request.Name);
|
||||
|
||||
return maybeExisting.IsSome
|
||||
return duplicateName
|
||||
? BaseError.New($"A deco named \"{request.Name}\" already exists in that deco group")
|
||||
: Success<BaseError, string>(request.Name);
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ public class CreateDecoTemplateGroupHandler(IDbContextFactory<TvContext> dbConte
|
||||
Validation<BaseError, string> result1 = createDecoTemplateGroup.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createDecoTemplateGroup.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
int duplicateNameCount = await dbContext.DecoTemplateGroups
|
||||
.CountAsync(ps => ps.Name == createDecoTemplateGroup.Name);
|
||||
bool duplicateName = await dbContext.DecoTemplateGroups
|
||||
.AnyAsync(ps => ps.Name == createDecoTemplateGroup.Name);
|
||||
|
||||
var result2 = Optional(duplicateNameCount)
|
||||
.Where(count => count == 0)
|
||||
.ToValidation<BaseError>("Deco template group name must be unique");
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Deco template group name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createDecoTemplateGroup.Name);
|
||||
}
|
||||
|
||||
@@ -43,11 +43,10 @@ public class CreateDecoTemplateHandler(IDbContextFactory<TvContext> dbContextFac
|
||||
return BaseError.New($"Deco template name \"{request.Name}\" is invalid");
|
||||
}
|
||||
|
||||
Option<DecoTemplate> maybeExisting = await dbContext.DecoTemplates
|
||||
.FirstOrDefaultAsync(r => r.DecoTemplateGroupId == request.DecoTemplateGroupId && r.Name == request.Name)
|
||||
.Map(Optional);
|
||||
bool duplicateName = await dbContext.DecoTemplates
|
||||
.AnyAsync(r => r.DecoTemplateGroupId == request.DecoTemplateGroupId && r.Name == request.Name);
|
||||
|
||||
return maybeExisting.IsSome
|
||||
return duplicateName
|
||||
? BaseError.New($"A deco template named \"{request.Name}\" already exists in that deco template group")
|
||||
: Success<BaseError, string>(request.Name);
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ public class CreateTemplateGroupHandler(IDbContextFactory<TvContext> dbContextFa
|
||||
Validation<BaseError, string> result1 = createTemplateGroup.NotEmpty(c => c.Name)
|
||||
.Bind(_ => createTemplateGroup.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
int duplicateNameCount = await dbContext.TemplateGroups
|
||||
.CountAsync(ps => ps.Name == createTemplateGroup.Name);
|
||||
bool duplicateName = await dbContext.TemplateGroups
|
||||
.AnyAsync(ps => ps.Name == createTemplateGroup.Name);
|
||||
|
||||
var result2 = Optional(duplicateNameCount)
|
||||
.Where(count => count == 0)
|
||||
.ToValidation<BaseError>("Template group name must be unique");
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("Template group name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => createTemplateGroup.Name);
|
||||
}
|
||||
|
||||
@@ -41,11 +41,10 @@ public class CreateTemplateHandler(IDbContextFactory<TvContext> dbContextFactory
|
||||
return BaseError.New($"Template name \"{request.Name}\" is invalid");
|
||||
}
|
||||
|
||||
Option<Template> maybeExisting = await dbContext.Templates
|
||||
.FirstOrDefaultAsync(r => r.TemplateGroupId == request.TemplateGroupId && r.Name == request.Name)
|
||||
.Map(Optional);
|
||||
bool duplicateName = await dbContext.Templates
|
||||
.AnyAsync(r => r.TemplateGroupId == request.TemplateGroupId && r.Name == request.Name);
|
||||
|
||||
return maybeExisting.IsSome
|
||||
return duplicateName
|
||||
? BaseError.New($"A template named \"{request.Name}\" already exists in that template group")
|
||||
: Success<BaseError, string>(request.Name);
|
||||
}
|
||||
|
||||
@@ -206,13 +206,10 @@ public class UpdateDecoHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
return BaseError.New($"Deco name \"{request.Name}\" is invalid");
|
||||
}
|
||||
|
||||
Option<Deco> maybeExisting = await dbContext.Decos
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(d =>
|
||||
d.Id != request.DecoId && d.DecoGroupId == request.DecoGroupId && d.Name == request.Name)
|
||||
.Map(Optional);
|
||||
bool duplicateName = await dbContext.Decos
|
||||
.AnyAsync(d => d.Id != request.DecoId && d.DecoGroupId == request.DecoGroupId && d.Name == request.Name);
|
||||
|
||||
return maybeExisting.IsSome
|
||||
return duplicateName
|
||||
? BaseError.New($"A deco named \"{request.Name}\" already exists in that deco group")
|
||||
: Success<BaseError, string>(request.Name);
|
||||
}
|
||||
|
||||
@@ -13,10 +13,8 @@ public class SearchArtistsHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.ArtistMetadata
|
||||
.AsNoTracking()
|
||||
.Where(a => EF.Functions.Like(
|
||||
EF.Functions.Collate(a.Title, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(a => EF.Functions.Collate(a.Title, TvContext.CaseInsensitiveCollation))
|
||||
.Where(a => EF.Functions.Like(a.Title, $"%{request.Query}%"))
|
||||
.OrderBy(a => a.Title)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
.Map(list => list.Bind(a => ToNamedMediaItem(a)).ToList());
|
||||
|
||||
@@ -15,10 +15,8 @@ public class SearchCollectionsHandler(IDbContextFactory<TvContext> dbContextFact
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.Collections
|
||||
.AsNoTracking()
|
||||
.Where(c => EF.Functions.Like(
|
||||
EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(c => EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation))
|
||||
.Where(c => EF.Functions.Like(c.Name, $"%{request.Query}%"))
|
||||
.OrderBy(c => c.Name)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
.Map(list => list.Map(ProjectToViewModel).ToList());
|
||||
|
||||
@@ -14,11 +14,9 @@ public class SearchMoviesHandler(IDbContextFactory<TvContext> dbContextFactory)
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.MovieMetadata
|
||||
.AsNoTracking()
|
||||
.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Title + " " + s.Year, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(a => EF.Functions.Collate(a.Title, TvContext.CaseInsensitiveCollation))
|
||||
.ThenBy(s => s.Year)
|
||||
.Where(m => EF.Functions.Like(m.Title + " " + m.Year, $"%{request.Query}%"))
|
||||
.OrderBy(m => m.Title)
|
||||
.ThenBy(m => m.Year)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
.Map(list => list.Map(ToNamedMediaItem).ToList());
|
||||
|
||||
@@ -15,10 +15,8 @@ public class SearchMultiCollectionsHandler(IDbContextFactory<TvContext> dbContex
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.MultiCollections
|
||||
.AsNoTracking()
|
||||
.Where(c => EF.Functions.Like(
|
||||
EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(c => EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation))
|
||||
.Where(mc => EF.Functions.Like(mc.Name, $"%{request.Query}%"))
|
||||
.OrderBy(mc => mc.Name)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
.Map(list => list.Map(ProjectToViewModel).ToList());
|
||||
|
||||
@@ -15,10 +15,8 @@ public class SearchRerunCollectionsHandler(IDbContextFactory<TvContext> dbContex
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.RerunCollections
|
||||
.AsNoTracking()
|
||||
.Where(c => EF.Functions.Like(
|
||||
EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(c => EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation))
|
||||
.Where(rc => EF.Functions.Like(rc.Name, $"%{request.Query}%"))
|
||||
.OrderBy(rc => rc.Name)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
.Map(list => list.Map(ProjectToViewModel).ToList());
|
||||
|
||||
@@ -15,10 +15,8 @@ public class SearchSmartCollectionsHandler(IDbContextFactory<TvContext> dbContex
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.SmartCollections
|
||||
.AsNoTracking()
|
||||
.Where(c => EF.Functions.Like(
|
||||
EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(c => EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation))
|
||||
.Where(sc => EF.Functions.Like(sc.Name, $"%{request.Query}%"))
|
||||
.OrderBy(sc => sc.Name)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
.Map(list => list.Map(ProjectToViewModel).ToList());
|
||||
|
||||
@@ -20,8 +20,7 @@ public class SearchTelevisionSeasonsHandler(IDbContextFactory<TvContext> dbConte
|
||||
join showMetadata in dbContext.Set<ShowMetadata>()
|
||||
on season.ShowId equals showMetadata.ShowId
|
||||
where EF.Functions.Like(showMetadata.Title + " " + seasonMetadata.Title, $"%{request.Query}%")
|
||||
orderby EF.Functions.Collate(showMetadata.Title, TvContext.CaseInsensitiveCollation), season
|
||||
.SeasonNumber
|
||||
orderby showMetadata.Title, season.SeasonNumber
|
||||
select new TelevisionSeason(season.Id, showMetadata.Title, showMetadata.Year, season.SeasonNumber))
|
||||
.Take(20)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -16,10 +16,8 @@ public class SearchTelevisionShowsHandler(IDbContextFactory<TvContext> dbContext
|
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
return await dbContext.ShowMetadata
|
||||
.AsNoTracking()
|
||||
.Where(s => EF.Functions.Like(
|
||||
EF.Functions.Collate(s.Title + " " + s.Year, TvContext.CaseInsensitiveCollation),
|
||||
$"%{request.Query}%"))
|
||||
.OrderBy(s => EF.Functions.Collate(s.Title, TvContext.CaseInsensitiveCollation))
|
||||
.Where(s => EF.Functions.Like(s.Title + " " + s.Year, $"%{request.Query}%"))
|
||||
.OrderBy(s => s.Title)
|
||||
.ThenBy(s => s.Year)
|
||||
.Take(10)
|
||||
.ToListAsync(cancellationToken)
|
||||
|
||||
@@ -45,12 +45,23 @@ public class CopyWatermarkHandler(IDbContextFactory<TvContext> dbContextFactory,
|
||||
TvContext dbContext,
|
||||
CopyWatermark request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(ValidateName(request), await WatermarkMustExist(dbContext, request, cancellationToken))
|
||||
(await ValidateName(dbContext, request), await WatermarkMustExist(dbContext, request, cancellationToken))
|
||||
.Apply((name, watermark) => new CopyWatermarkParameters(name, watermark));
|
||||
|
||||
private static Validation<BaseError, string> ValidateName(CopyWatermark request) =>
|
||||
request.NotEmpty(x => x.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(x => x.Name));
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(TvContext dbContext, CopyWatermark request)
|
||||
{
|
||||
Validation<BaseError, string> result1 = request.NotEmpty(c => c.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
bool duplicateName = await dbContext.ChannelWatermarks
|
||||
.AnyAsync(wm => wm.Name == request.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("ChannelWatermark name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => request.Name);
|
||||
}
|
||||
|
||||
private static Task<Validation<BaseError, ChannelWatermark>> WatermarkMustExist(
|
||||
TvContext dbContext,
|
||||
|
||||
@@ -22,7 +22,7 @@ public class CreateWatermarkHandler : IRequestHandler<CreateWatermark, Either<Ba
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||
Validation<BaseError, ChannelWatermark> validation = Validate(request);
|
||||
Validation<BaseError, ChannelWatermark> validation = await Validate(dbContext, request);
|
||||
return await validation.Apply(profile => PersistChannelWatermark(dbContext, profile));
|
||||
}
|
||||
|
||||
@@ -36,8 +36,10 @@ public class CreateWatermarkHandler : IRequestHandler<CreateWatermark, Either<Ba
|
||||
return new CreateWatermarkResult(watermark.Id);
|
||||
}
|
||||
|
||||
private static Validation<BaseError, ChannelWatermark> Validate(CreateWatermark request) =>
|
||||
ValidateName(request)
|
||||
private static async Task<Validation<BaseError, ChannelWatermark>> Validate(
|
||||
TvContext dbContext,
|
||||
CreateWatermark request) =>
|
||||
await ValidateName(dbContext, request)
|
||||
.Map(_ =>
|
||||
{
|
||||
var watermark = new ChannelWatermark
|
||||
@@ -69,7 +71,18 @@ public class CreateWatermarkHandler : IRequestHandler<CreateWatermark, Either<Ba
|
||||
return watermark;
|
||||
});
|
||||
|
||||
private static Validation<BaseError, string> ValidateName(CreateWatermark request) =>
|
||||
request.NotEmpty(x => x.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(x => x.Name));
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(TvContext dbContext, CreateWatermark request)
|
||||
{
|
||||
Validation<BaseError, string> result1 = request.NotEmpty(c => c.Name)
|
||||
.Bind(_ => request.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
bool duplicateName = await dbContext.ChannelWatermarks
|
||||
.AnyAsync(wm => wm.Name == request.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("ChannelWatermark name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
return (result1, result2).Apply((_, _) => request.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class UpdateWatermarkHandler : IRequestHandler<UpdateWatermark, Either<Ba
|
||||
TvContext dbContext,
|
||||
UpdateWatermark request,
|
||||
CancellationToken cancellationToken) =>
|
||||
(await WatermarkMustExist(dbContext, request, cancellationToken), ValidateName(request))
|
||||
(await WatermarkMustExist(dbContext, request, cancellationToken), await ValidateName(dbContext, request))
|
||||
.Apply((watermark, _) => watermark);
|
||||
|
||||
private static Task<Validation<BaseError, ChannelWatermark>> WatermarkMustExist(
|
||||
@@ -76,7 +76,20 @@ public class UpdateWatermarkHandler : IRequestHandler<UpdateWatermark, Either<Ba
|
||||
.SelectOneAsync(p => p.Id, p => p.Id == updateWatermark.Id, cancellationToken)
|
||||
.Map(o => o.ToValidation<BaseError>("Watermark does not exist."));
|
||||
|
||||
private static Validation<BaseError, string> ValidateName(UpdateWatermark updateWatermark) =>
|
||||
updateWatermark.NotEmpty(x => x.Name)
|
||||
.Bind(_ => updateWatermark.NotLongerThan(50)(x => x.Name));
|
||||
private static async Task<Validation<BaseError, string>> ValidateName(
|
||||
TvContext dbContext,
|
||||
UpdateWatermark updateWatermark)
|
||||
{
|
||||
bool duplicateName = await dbContext.ChannelWatermarks
|
||||
.AnyAsync(wm => wm.Id != updateWatermark.Id && wm.Name == updateWatermark.Name);
|
||||
|
||||
Validation<BaseError, Unit> result2 = duplicateName
|
||||
? Fail<BaseError, Unit>("ChannelWatermark name must be unique")
|
||||
: Success<BaseError, Unit>(Unit.Default);
|
||||
|
||||
Validation<BaseError, string> result1 = updateWatermark.NotEmpty(c => c.Name)
|
||||
.Bind(_ => updateWatermark.NotLongerThan(50)(c => c.Name));
|
||||
|
||||
return (result1, result2).Apply((_, _) => updateWatermark.Name);
|
||||
}
|
||||
}
|
||||
|
||||
+6923
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,227 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Fix_DuplicateNames : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE Block a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM Block
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE BlockGroup a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM BlockGroup
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE ChannelWatermark a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM ChannelWatermark
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE Collection a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM Collection
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE Deco a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM Deco
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE DecoGroup a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM DecoGroup
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE DecoTemplate a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM DecoTemplate
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE DecoTemplateGroup a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM DecoTemplateGroup
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE FillerPreset a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM FillerPreset
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE MultiCollection a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM MultiCollection
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE Playlist a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM Playlist
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE ProgramSchedule a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM ProgramSchedule
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE RerunCollection a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM RerunCollection
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE SmartCollection a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM SmartCollection
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE Template a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM Template
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
UPDATE TemplateGroup a
|
||||
JOIN (
|
||||
SELECT
|
||||
Id,
|
||||
ROW_NUMBER() OVER (PARTITION BY LOWER(Name) ORDER BY Id) as RowNum
|
||||
FROM TemplateGroup
|
||||
) n ON a.Id = n.Id
|
||||
SET a.Name = CONCAT(a.Name, ' (', n.RowNum - 1, ')')
|
||||
WHERE n.RowNum > 1;
|
||||
""");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+6987
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,679 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Update_CaseSensitivity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TraktList",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TemplateGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Template",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "SmartCollection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ShowMetadata",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "RerunCollection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ProgramSchedule",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Playlist",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "MultiCollection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "MovieMetadata",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Guid",
|
||||
table: "MetadataGuid",
|
||||
type: "varchar(128)",
|
||||
maxLength: 128,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "FillerPreset",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplateGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplate",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Deco",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Collection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ChannelWatermark",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Channel",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "BlockGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Block",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ArtistMetadata",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "longtext",
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TraktList_Name",
|
||||
table: "TraktList",
|
||||
column: "Name");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowMetadata_Title",
|
||||
table: "ShowMetadata",
|
||||
column: "Title");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RerunCollection_Name",
|
||||
table: "RerunCollection",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MultiCollection_Name",
|
||||
table: "MultiCollection",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MovieMetadata_Title",
|
||||
table: "MovieMetadata",
|
||||
column: "Title");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MetadataGuid_Guid",
|
||||
table: "MetadataGuid",
|
||||
column: "Guid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FillerPreset_Name",
|
||||
table: "FillerPreset",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Collection_Name",
|
||||
table: "Collection",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelWatermark_Name",
|
||||
table: "ChannelWatermark",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ArtistMetadata_Title",
|
||||
table: "ArtistMetadata",
|
||||
column: "Title");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_TraktList_Name",
|
||||
table: "TraktList");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ShowMetadata_Title",
|
||||
table: "ShowMetadata");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_RerunCollection_Name",
|
||||
table: "RerunCollection");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MultiCollection_Name",
|
||||
table: "MultiCollection");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MovieMetadata_Title",
|
||||
table: "MovieMetadata");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MetadataGuid_Guid",
|
||||
table: "MetadataGuid");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_FillerPreset_Name",
|
||||
table: "FillerPreset");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Collection_Name",
|
||||
table: "Collection");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ChannelWatermark_Name",
|
||||
table: "ChannelWatermark");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ArtistMetadata_Title",
|
||||
table: "ArtistMetadata");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TraktList",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TemplateGroup",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Template",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "SmartCollection",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
collation: "utf8mb4_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ShowMetadata",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "RerunCollection",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ProgramSchedule",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Playlist",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "MultiCollection",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "MovieMetadata",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Guid",
|
||||
table: "MetadataGuid",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(128)",
|
||||
oldMaxLength: 128,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "FillerPreset",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplateGroup",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplate",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoGroup",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Deco",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Collection",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ChannelWatermark",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Channel",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "BlockGroup",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Block",
|
||||
type: "varchar(255)",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ArtistMetadata",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(255)",
|
||||
oldNullable: true,
|
||||
oldCollation: "utf8mb4_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("longtext");
|
||||
.HasColumnType("varchar(255)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
.HasColumnType("int");
|
||||
@@ -148,6 +149,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasIndex("ArtistId");
|
||||
|
||||
b.HasIndex("Title");
|
||||
|
||||
b.ToTable("ArtistMetadata", (string)null);
|
||||
});
|
||||
|
||||
@@ -317,7 +320,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.HasColumnType("varchar(255)");
|
||||
@@ -418,7 +423,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int>("Opacity")
|
||||
.HasColumnType("int");
|
||||
@@ -446,6 +453,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ChannelWatermark", (string)null);
|
||||
});
|
||||
|
||||
@@ -458,13 +468,18 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<bool>("UseCustomPlaybackOrder")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Collection", (string)null);
|
||||
});
|
||||
|
||||
@@ -831,7 +846,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int?>("PadToNearestMinute")
|
||||
.HasColumnType("int");
|
||||
@@ -853,6 +870,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasIndex("MultiCollectionId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("PlaylistId");
|
||||
|
||||
b.HasIndex("SmartCollectionId");
|
||||
@@ -1469,7 +1489,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Guid")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int?>("ImageMetadataId")
|
||||
.HasColumnType("int");
|
||||
@@ -1501,6 +1523,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasIndex("EpisodeMetadataId");
|
||||
|
||||
b.HasIndex("Guid");
|
||||
|
||||
b.HasIndex("ImageMetadataId");
|
||||
|
||||
b.HasIndex("MovieMetadataId");
|
||||
@@ -1583,7 +1607,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("longtext");
|
||||
.HasColumnType("varchar(255)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
.HasColumnType("int");
|
||||
@@ -1592,6 +1617,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasIndex("MovieId");
|
||||
|
||||
b.HasIndex("Title");
|
||||
|
||||
b.ToTable("MovieMetadata", (string)null);
|
||||
});
|
||||
|
||||
@@ -1604,10 +1631,15 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MultiCollection", (string)null);
|
||||
});
|
||||
|
||||
@@ -1791,7 +1823,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int>("PlaylistGroupId")
|
||||
.HasColumnType("int");
|
||||
@@ -2252,7 +2286,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<bool>("RandomStartPoint")
|
||||
.HasColumnType("tinyint(1)");
|
||||
@@ -2540,7 +2576,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int>("RerunPlaybackOrder")
|
||||
.HasColumnType("int");
|
||||
@@ -2556,6 +2594,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasIndex("MultiCollectionId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("SmartCollectionId");
|
||||
|
||||
b.ToTable("RerunCollection", (string)null);
|
||||
@@ -2606,7 +2647,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int>("StopScheduling")
|
||||
.HasColumnType("int");
|
||||
@@ -2628,7 +2671,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2754,7 +2799,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<bool>("UseGraphicsElementsDuringFiller")
|
||||
.HasColumnType("tinyint(1)");
|
||||
@@ -2847,7 +2894,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2872,7 +2921,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2891,7 +2942,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -3078,7 +3131,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int>("TemplateGroupId")
|
||||
.HasColumnType("int");
|
||||
@@ -3100,7 +3155,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -3223,7 +3280,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("longtext");
|
||||
.HasColumnType("varchar(255)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
.HasColumnType("int");
|
||||
@@ -3232,6 +3290,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasIndex("ShowId");
|
||||
|
||||
b.HasIndex("Title");
|
||||
|
||||
b.ToTable("ShowMetadata", (string)null);
|
||||
});
|
||||
|
||||
@@ -3244,7 +3304,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<string>("Query")
|
||||
@@ -3607,7 +3668,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("longtext");
|
||||
.HasColumnType("varchar(255)")
|
||||
.UseCollation("utf8mb4_general_ci");
|
||||
|
||||
b.Property<int?>("PlaylistId")
|
||||
.HasColumnType("int");
|
||||
@@ -3620,6 +3682,8 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name");
|
||||
|
||||
b.HasIndex("PlaylistId");
|
||||
|
||||
b.ToTable("TraktList", (string)null);
|
||||
|
||||
+6750
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,275 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Fix_DuplicateNames : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM Block
|
||||
)
|
||||
UPDATE Block
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE Block.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM BlockGroup
|
||||
)
|
||||
UPDATE BlockGroup
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE BlockGroup.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM ChannelWatermark
|
||||
)
|
||||
UPDATE ChannelWatermark
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE ChannelWatermark.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM Collection
|
||||
)
|
||||
UPDATE Collection
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE Collection.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM Deco
|
||||
)
|
||||
UPDATE Deco
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE Deco.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM DecoGroup
|
||||
)
|
||||
UPDATE DecoGroup
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE DecoGroup.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM DecoTemplate
|
||||
)
|
||||
UPDATE DecoTemplate
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE DecoTemplate.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM DecoTemplateGroup
|
||||
)
|
||||
UPDATE DecoTemplateGroup
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE DecoTemplateGroup.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM FillerPreset
|
||||
)
|
||||
UPDATE FillerPreset
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE FillerPreset.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM MultiCollection
|
||||
)
|
||||
UPDATE MultiCollection
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE MultiCollection.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM Playlist
|
||||
)
|
||||
UPDATE Playlist
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE Playlist.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM ProgramSchedule
|
||||
)
|
||||
UPDATE ProgramSchedule
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE ProgramSchedule.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM RerunCollection
|
||||
)
|
||||
UPDATE RerunCollection
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE RerunCollection.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM SmartCollection
|
||||
)
|
||||
UPDATE SmartCollection
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE SmartCollection.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM Template
|
||||
)
|
||||
UPDATE Template
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE Template.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
WITH Numbered AS (
|
||||
SELECT
|
||||
Id,
|
||||
-- Partition by case-insensitive name
|
||||
ROW_NUMBER() OVER (PARTITION BY Name COLLATE NOCASE ORDER BY Id) AS RowNum
|
||||
FROM TemplateGroup
|
||||
)
|
||||
UPDATE TemplateGroup
|
||||
SET Name = Name || ' (' || (Numbered.RowNum - 1) || ')'
|
||||
FROM Numbered
|
||||
WHERE TemplateGroup.Id = Numbered.Id
|
||||
AND Numbered.RowNum > 1;
|
||||
""");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+6814
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,591 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Update_CaseSensitivity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TraktList",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TemplateGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Template",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "SmartCollection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ShowMetadata",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "RerunCollection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ProgramSchedule",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Playlist",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "MultiCollection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "MovieMetadata",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Guid",
|
||||
table: "MetadataGuid",
|
||||
type: "varchar(128)",
|
||||
maxLength: 128,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "FillerPreset",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplateGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplate",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Deco",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Collection",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ChannelWatermark",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Channel",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "BlockGroup",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Block",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ArtistMetadata",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_TraktList_Name",
|
||||
table: "TraktList",
|
||||
column: "Name");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ShowMetadata_Title",
|
||||
table: "ShowMetadata",
|
||||
column: "Title");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RerunCollection_Name",
|
||||
table: "RerunCollection",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MultiCollection_Name",
|
||||
table: "MultiCollection",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MovieMetadata_Title",
|
||||
table: "MovieMetadata",
|
||||
column: "Title");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_MetadataGuid_Guid",
|
||||
table: "MetadataGuid",
|
||||
column: "Guid");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_FillerPreset_Name",
|
||||
table: "FillerPreset",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Collection_Name",
|
||||
table: "Collection",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ChannelWatermark_Name",
|
||||
table: "ChannelWatermark",
|
||||
column: "Name",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ArtistMetadata_Title",
|
||||
table: "ArtistMetadata",
|
||||
column: "Title");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_TraktList_Name",
|
||||
table: "TraktList");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ShowMetadata_Title",
|
||||
table: "ShowMetadata");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_RerunCollection_Name",
|
||||
table: "RerunCollection");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MultiCollection_Name",
|
||||
table: "MultiCollection");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MovieMetadata_Title",
|
||||
table: "MovieMetadata");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_MetadataGuid_Guid",
|
||||
table: "MetadataGuid");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_FillerPreset_Name",
|
||||
table: "FillerPreset");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Collection_Name",
|
||||
table: "Collection");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ChannelWatermark_Name",
|
||||
table: "ChannelWatermark");
|
||||
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_ArtistMetadata_Title",
|
||||
table: "ArtistMetadata");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TraktList",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "TemplateGroup",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Template",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "SmartCollection",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
collation: "NOCASE",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ShowMetadata",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "RerunCollection",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ProgramSchedule",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Playlist",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "MultiCollection",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "MovieMetadata",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Guid",
|
||||
table: "MetadataGuid",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(128)",
|
||||
oldMaxLength: 128,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "FillerPreset",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplateGroup",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoTemplate",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "DecoGroup",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Deco",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Collection",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "ChannelWatermark",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Channel",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "BlockGroup",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Name",
|
||||
table: "Block",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "Title",
|
||||
table: "ArtistMetadata",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true,
|
||||
oldCollation: "NOCASE");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT");
|
||||
.HasColumnType("TEXT")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -139,6 +140,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasIndex("ArtistId");
|
||||
|
||||
b.HasIndex("Title");
|
||||
|
||||
b.ToTable("ArtistMetadata", (string)null);
|
||||
});
|
||||
|
||||
@@ -304,7 +307,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.HasColumnType("TEXT");
|
||||
@@ -403,7 +408,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int>("Opacity")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -431,6 +438,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("ChannelWatermark", (string)null);
|
||||
});
|
||||
|
||||
@@ -441,13 +451,18 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<bool>("UseCustomPlaybackOrder")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Collection", (string)null);
|
||||
});
|
||||
|
||||
@@ -798,7 +813,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int?>("PadToNearestMinute")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -820,6 +837,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasIndex("MultiCollectionId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("PlaylistId");
|
||||
|
||||
b.HasIndex("SmartCollectionId");
|
||||
@@ -1400,7 +1420,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Guid")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int?>("ImageMetadataId")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -1432,6 +1454,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasIndex("EpisodeMetadataId");
|
||||
|
||||
b.HasIndex("Guid");
|
||||
|
||||
b.HasIndex("ImageMetadataId");
|
||||
|
||||
b.HasIndex("MovieMetadataId");
|
||||
@@ -1510,7 +1534,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT");
|
||||
.HasColumnType("TEXT")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -1519,6 +1544,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasIndex("MovieId");
|
||||
|
||||
b.HasIndex("Title");
|
||||
|
||||
b.ToTable("MovieMetadata", (string)null);
|
||||
});
|
||||
|
||||
@@ -1529,10 +1556,15 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("MultiCollection", (string)null);
|
||||
});
|
||||
|
||||
@@ -1708,7 +1740,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int>("PlaylistGroupId")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2147,7 +2181,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<bool>("RandomStartPoint")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2427,7 +2463,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int>("RerunPlaybackOrder")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2443,6 +2481,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasIndex("MultiCollectionId");
|
||||
|
||||
b.HasIndex("Name")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("SmartCollectionId");
|
||||
|
||||
b.ToTable("RerunCollection", (string)null);
|
||||
@@ -2489,7 +2530,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int>("StopScheduling")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2509,7 +2552,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2631,7 +2676,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<bool>("UseGraphicsElementsDuringFiller")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2720,7 +2767,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2743,7 +2792,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2760,7 +2811,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -2937,7 +2990,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int>("TemplateGroupId")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -2957,7 +3012,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
@@ -3074,7 +3131,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT");
|
||||
.HasColumnType("TEXT")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int?>("Year")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -3083,6 +3141,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasIndex("ShowId");
|
||||
|
||||
b.HasIndex("Title");
|
||||
|
||||
b.ToTable("ShowMetadata", (string)null);
|
||||
});
|
||||
|
||||
@@ -3093,7 +3153,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<string>("Query")
|
||||
@@ -3444,7 +3505,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
.HasColumnType("TEXT")
|
||||
.UseCollation("NOCASE");
|
||||
|
||||
b.Property<int?>("PlaylistId")
|
||||
.HasColumnType("INTEGER");
|
||||
@@ -3457,6 +3519,8 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Name");
|
||||
|
||||
b.HasIndex("PlaylistId");
|
||||
|
||||
b.ToTable("TraktList", (string)null);
|
||||
|
||||
@@ -13,6 +13,10 @@ public class ChannelConfiguration : IEntityTypeConfiguration<Channel>
|
||||
builder.HasIndex(c => c.Number)
|
||||
.IsUnique();
|
||||
|
||||
builder.Property(c => c.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.Property(c => c.IsEnabled)
|
||||
.HasDefaultValue(true);
|
||||
|
||||
|
||||
@@ -6,5 +6,15 @@ namespace ErsatzTV.Infrastructure.Data.Configurations;
|
||||
|
||||
public class ChannelWatermarkConfiguration : IEntityTypeConfiguration<ChannelWatermark>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ChannelWatermark> builder) => builder.ToTable("ChannelWatermark");
|
||||
public void Configure(EntityTypeBuilder<ChannelWatermark> builder)
|
||||
{
|
||||
builder.ToTable("ChannelWatermark");
|
||||
|
||||
builder.Property(wm => wm.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(wm => wm.Name)
|
||||
.IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,13 @@ public class CollectionConfiguration : IEntityTypeConfiguration<Collection>
|
||||
{
|
||||
builder.ToTable("Collection");
|
||||
|
||||
builder.Property(c => c.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(c => c.Name)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasMany(c => c.MediaItems)
|
||||
.WithMany(m => m.Collections)
|
||||
.UsingEntity<CollectionItem>(
|
||||
|
||||
@@ -10,6 +10,13 @@ public class MultiCollectionConfiguration : IEntityTypeConfiguration<MultiCollec
|
||||
{
|
||||
builder.ToTable("MultiCollection");
|
||||
|
||||
builder.Property(mc => mc.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(mc => mc.Name)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasMany(m => m.Collections)
|
||||
.WithMany(m => m.MultiCollections)
|
||||
.UsingEntity<MultiCollectionItem>(
|
||||
|
||||
@@ -10,7 +10,11 @@ public class PlaylistConfiguration : IEntityTypeConfiguration<Playlist>
|
||||
{
|
||||
builder.ToTable("Playlist");
|
||||
|
||||
builder.HasIndex(d => new { d.PlaylistGroupId, d.Name })
|
||||
builder.Property(p => p.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(p => new { p.PlaylistGroupId, p.Name })
|
||||
.IsUnique();
|
||||
|
||||
builder.HasMany(p => p.Items)
|
||||
|
||||
@@ -10,6 +10,13 @@ public class RerunCollectionConfiguration : IEntityTypeConfiguration<RerunCollec
|
||||
{
|
||||
builder.ToTable("RerunCollection");
|
||||
|
||||
builder.Property(rc => rc.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(rc => rc.Name)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasOne(i => i.Collection)
|
||||
.WithMany()
|
||||
.HasForeignKey(i => i.CollectionId)
|
||||
|
||||
@@ -10,6 +10,10 @@ public class SmartCollectionConfiguration : IEntityTypeConfiguration<SmartCollec
|
||||
{
|
||||
builder.ToTable("SmartCollection");
|
||||
|
||||
builder.Property(sc => sc.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(sc => sc.Name)
|
||||
.IsUnique();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ public class TraktListConfiguration : IEntityTypeConfiguration<TraktList>
|
||||
{
|
||||
builder.ToTable("TraktList");
|
||||
|
||||
builder.HasIndex(l => l.Name);
|
||||
|
||||
builder.HasMany(l => l.Items)
|
||||
.WithOne(i => i.TraktList)
|
||||
.HasForeignKey(i => i.TraktListId)
|
||||
|
||||
@@ -10,6 +10,13 @@ public class FillerPresetConfiguration : IEntityTypeConfiguration<FillerPreset>
|
||||
{
|
||||
builder.ToTable("FillerPreset");
|
||||
|
||||
builder.Property(mc => mc.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(c => c.Name)
|
||||
.IsUnique();
|
||||
|
||||
builder.HasOne(i => i.Collection)
|
||||
.WithMany()
|
||||
.HasForeignKey(i => i.CollectionId)
|
||||
|
||||
+11
-9
@@ -10,39 +10,41 @@ public class ArtistMetadataConfiguration : IEntityTypeConfiguration<ArtistMetada
|
||||
{
|
||||
builder.ToTable("ArtistMetadata");
|
||||
|
||||
builder.HasMany(sm => sm.Artwork)
|
||||
builder.HasIndex(am => am.Title);
|
||||
|
||||
builder.HasMany(am => am.Artwork)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Genres)
|
||||
builder.HasMany(am => am.Genres)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Tags)
|
||||
builder.HasMany(am => am.Tags)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Studios)
|
||||
builder.HasMany(am => am.Studios)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Actors)
|
||||
builder.HasMany(am => am.Actors)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(mm => mm.Guids)
|
||||
builder.HasMany(am => am.Guids)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(mm => mm.Subtitles)
|
||||
builder.HasMany(am => am.Subtitles)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Styles)
|
||||
builder.HasMany(am => am.Styles)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Moods)
|
||||
builder.HasMany(am => am.Moods)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
}
|
||||
|
||||
@@ -6,5 +6,14 @@ namespace ErsatzTV.Infrastructure.Data.Configurations;
|
||||
|
||||
public class MetadataGuidConfiguration : IEntityTypeConfiguration<MetadataGuid>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MetadataGuid> builder) => builder.ToTable("MetadataGuid");
|
||||
public void Configure(EntityTypeBuilder<MetadataGuid> builder)
|
||||
{
|
||||
builder.ToTable("MetadataGuid");
|
||||
|
||||
builder.Property(mg => mg.Guid)
|
||||
.HasMaxLength(128)
|
||||
.HasColumnType("varchar(128)");
|
||||
|
||||
builder.HasIndex(mg => mg.Guid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,23 +10,25 @@ public class MovieMetadataConfiguration : IEntityTypeConfiguration<MovieMetadata
|
||||
{
|
||||
builder.ToTable("MovieMetadata");
|
||||
|
||||
builder.HasMany(sm => sm.Artwork)
|
||||
builder.HasIndex(mm => mm.Title);
|
||||
|
||||
builder.HasMany(mm => mm.Artwork)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Genres)
|
||||
builder.HasMany(mm => mm.Genres)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Tags)
|
||||
builder.HasMany(mm => mm.Tags)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Studios)
|
||||
builder.HasMany(mm => mm.Studios)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasMany(sm => sm.Actors)
|
||||
builder.HasMany(mm => mm.Actors)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ public class ShowMetadataConfiguration : IEntityTypeConfiguration<ShowMetadata>
|
||||
{
|
||||
builder.ToTable("ShowMetadata");
|
||||
|
||||
builder.HasIndex(sm => sm.Title);
|
||||
|
||||
builder.HasMany(sm => sm.Artwork)
|
||||
.WithOne()
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
@@ -10,6 +10,10 @@ public class ProgramScheduleConfiguration : IEntityTypeConfiguration<ProgramSche
|
||||
{
|
||||
builder.ToTable("ProgramSchedule");
|
||||
|
||||
builder.Property(p => p.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(ps => ps.Name)
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ public class BlockConfiguration : IEntityTypeConfiguration<Block>
|
||||
{
|
||||
builder.ToTable("Block");
|
||||
|
||||
builder.Property(b => b.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(b => new { b.BlockGroupId, b.Name })
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ public class BlockGroupConfiguration : IEntityTypeConfiguration<BlockGroup>
|
||||
{
|
||||
builder.ToTable("BlockGroup");
|
||||
|
||||
builder.Property(b => b.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(b => b.Name)
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ public class DecoConfiguration : IEntityTypeConfiguration<Deco>
|
||||
{
|
||||
builder.ToTable("Deco");
|
||||
|
||||
builder.Property(d => d.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(d => new { d.DecoGroupId, d.Name })
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ public class DecoGroupConfiguration : IEntityTypeConfiguration<DecoGroup>
|
||||
{
|
||||
builder.ToTable("DecoGroup");
|
||||
|
||||
builder.Property(dg => dg.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(dg => dg.Name)
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ public class DecoTemplateConfiguration : IEntityTypeConfiguration<DecoTemplate>
|
||||
{
|
||||
builder.ToTable("DecoTemplate");
|
||||
|
||||
builder.Property(d => d.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(d => new { d.DecoTemplateGroupId, d.Name })
|
||||
.IsUnique();
|
||||
|
||||
|
||||
+4
@@ -10,6 +10,10 @@ public class DecoTemplateGroupConfiguration : IEntityTypeConfiguration<DecoTempl
|
||||
{
|
||||
builder.ToTable("DecoTemplateGroup");
|
||||
|
||||
builder.Property(d => d.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(b => b.Name)
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ public class TemplateConfiguration : IEntityTypeConfiguration<Template>
|
||||
{
|
||||
builder.ToTable("Template");
|
||||
|
||||
builder.Property(t => t.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(d => new { d.TemplateGroupId, d.Name })
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ public class TemplateGroupConfiguration : IEntityTypeConfiguration<TemplateGroup
|
||||
{
|
||||
builder.ToTable("TemplateGroup");
|
||||
|
||||
builder.Property(t => t.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
builder.HasIndex(b => b.Name)
|
||||
.IsUnique();
|
||||
|
||||
|
||||
@@ -51,9 +51,7 @@ public class ChannelRepository(IDbContextFactory<TvContext> dbContextFactory) :
|
||||
|
||||
List<ChannelWatermark> maybeWatermarks = await dbContext.ChannelWatermarks
|
||||
.AsNoTracking()
|
||||
.Where(cw => EF.Functions.Like(
|
||||
EF.Functions.Collate(cw.Name, TvContext.CaseInsensitiveCollation),
|
||||
$"%{name}%"))
|
||||
.Where(cw => EF.Functions.Like(cw.Name, $"%{name}%"))
|
||||
.ToListAsync();
|
||||
|
||||
return maybeWatermarks.HeadOrNone();
|
||||
|
||||
@@ -176,10 +176,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
|
||||
|
||||
Option<Playlist> maybePlaylist = await dbContext.Playlists
|
||||
.AsNoTracking()
|
||||
.SelectOneAsync(
|
||||
p => p.Name,
|
||||
p => EF.Functions.Collate(p.Name, TvContext.CaseInsensitiveCollation) == name,
|
||||
cancellationToken);
|
||||
.SingleOrDefaultAsync(p => p.Name == name, cancellationToken);
|
||||
|
||||
foreach (Playlist playlist in maybePlaylist)
|
||||
{
|
||||
@@ -360,10 +357,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
|
||||
|
||||
Option<Collection> maybeCollection = await dbContext.Collections
|
||||
.AsNoTracking()
|
||||
.SelectOneAsync(
|
||||
c => c.Name,
|
||||
c => EF.Functions.Collate(c.Name, TvContext.CaseInsensitiveCollation) == name,
|
||||
cancellationToken);
|
||||
.SingleOrDefaultAsync(c => c.Name == name, cancellationToken);
|
||||
|
||||
foreach (Collection collection in maybeCollection)
|
||||
{
|
||||
@@ -416,10 +410,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
|
||||
|
||||
Option<MultiCollection> maybeCollection = await dbContext.MultiCollections
|
||||
.AsNoTracking()
|
||||
.SelectOneAsync(
|
||||
mc => mc.Name,
|
||||
mc => EF.Functions.Collate(mc.Name, TvContext.CaseInsensitiveCollation) == name,
|
||||
cancellationToken);
|
||||
.SingleOrDefaultAsync(mc => mc.Name == name, cancellationToken);
|
||||
|
||||
foreach (MultiCollection collection in maybeCollection)
|
||||
{
|
||||
@@ -451,10 +442,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
|
||||
|
||||
Option<SmartCollection> maybeCollection = await dbContext.SmartCollections
|
||||
.AsNoTracking()
|
||||
.SelectOneAsync(
|
||||
sc => sc.Name,
|
||||
sc => EF.Functions.Collate(sc.Name, TvContext.CaseInsensitiveCollation) == name,
|
||||
cancellationToken);
|
||||
.SingleOrDefaultAsync(sc => sc.Name == name, cancellationToken);
|
||||
|
||||
foreach (SmartCollection collection in maybeCollection)
|
||||
{
|
||||
@@ -694,8 +682,7 @@ public class MediaCollectionRepository : IMediaCollectionRepository
|
||||
|
||||
List<int> nextIds = await dbContext.ShowMetadata
|
||||
.AsNoTracking()
|
||||
.Filter(sm =>
|
||||
sm.Guids.Any(g => EF.Functions.Collate(g.Guid, TvContext.CaseInsensitiveCollation) == guid))
|
||||
.Filter(sm => sm.Guids.Any(g => g.Guid == guid))
|
||||
.Map(sm => sm.ShowId)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
@@ -86,9 +86,7 @@ public class TelevisionRepository : ITelevisionRepository
|
||||
return await dbContext.ShowMetadata
|
||||
.AsNoTracking()
|
||||
.Where(sm => sm.Show.LibraryPath.LibraryId == libraryId)
|
||||
.Where(sm => EF.Functions.Like(
|
||||
EF.Functions.Collate(sm.Title, TvContext.CaseInsensitiveCollation),
|
||||
$"%{title}%"))
|
||||
.Where(sm => EF.Functions.Like(sm.Title, $"%{title}%"))
|
||||
.Map(sm => sm.ShowId)
|
||||
.FirstOrDefaultAsync()
|
||||
.Map(showId => showId > 0 ? Option<int>.Some(showId) : Option<int>.None);
|
||||
@@ -223,9 +221,8 @@ public class TelevisionRepository : ITelevisionRepository
|
||||
if (maybeId.IsNone)
|
||||
{
|
||||
List<int> maybeShowIds = await dbContext.Episodes
|
||||
.Where(e => e.MediaVersions.Any(mv => mv.MediaFiles.Any(mf => EF.Functions.Like(
|
||||
EF.Functions.Collate(mf.Path, TvContext.CaseInsensitiveCollation),
|
||||
$"{showFolder}%"))))
|
||||
.Where(e => e.MediaVersions.Any(mv =>
|
||||
mv.MediaFiles.Any(mf => EF.Functions.Like(mf.Path, $"{showFolder}%"))))
|
||||
.Map(e => e.Season.ShowId)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
@@ -136,18 +136,46 @@ public class TvContext : DbContext
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
string collation = null;
|
||||
|
||||
// mysql-specific configuration
|
||||
if ((Database.ProviderName ?? string.Empty).Contains("MySql", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
modelBuilder.Entity<MediaFile>().Property(mf => mf.Path).HasColumnType("longtext");
|
||||
|
||||
modelBuilder.Entity<SmartCollection>().Property(mc => mc.Name).UseCollation("utf8mb4_general_ci");
|
||||
collation = "utf8mb4_general_ci";
|
||||
}
|
||||
|
||||
// sqlite-specific configuration
|
||||
if ((Database.ProviderName ?? string.Empty).Contains("Sqlite", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
modelBuilder.Entity<SmartCollection>().Property(sc => sc.Name).UseCollation("NOCASE");
|
||||
collation = "NOCASE";
|
||||
}
|
||||
|
||||
// case-insensitive columns
|
||||
if (!string.IsNullOrEmpty(collation))
|
||||
{
|
||||
modelBuilder.Entity<ArtistMetadata>().Property(b => b.Title).UseCollation(collation);
|
||||
modelBuilder.Entity<Block>().Property(b => b.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<BlockGroup>().Property(b => b.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<Channel>().Property(c => c.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<ChannelWatermark>().Property(c => c.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<Collection>().Property(c => c.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<Deco>().Property(d => d.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<DecoGroup>().Property(d => d.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<DecoTemplate>().Property(d => d.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<DecoTemplateGroup>().Property(d => d.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<FillerPreset>().Property(fp => fp.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<MetadataGuid>().Property(mg => mg.Guid).UseCollation(collation);
|
||||
modelBuilder.Entity<MovieMetadata>().Property(mm => mm.Title).UseCollation(collation);
|
||||
modelBuilder.Entity<MultiCollection>().Property(mc => mc.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<Playlist>().Property(p => p.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<ProgramSchedule>().Property(ps => ps.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<RerunCollection>().Property(rc => rc.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<ShowMetadata>().Property(sm => sm.Title).UseCollation(collation);
|
||||
modelBuilder.Entity<SmartCollection>().Property(sc => sc.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<Template>().Property(t => t.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<TemplateGroup>().Property(t => t.Name).UseCollation(collation);
|
||||
modelBuilder.Entity<TraktList>().Property(t => t.Name).UseCollation(collation);
|
||||
}
|
||||
|
||||
modelBuilder.ApplyConfigurationsFromAssembly(typeof(TvContext).Assembly);
|
||||
|
||||
Reference in New Issue
Block a user