fix: include Release nav on all TrackRepository query paths; add unique constraint on release(title, artist)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Data.Errors;
|
||||
using Data.Managers;
|
||||
using DeepDrftData.Repositories;
|
||||
using DeepDrftModels.DTOs;
|
||||
@@ -121,13 +122,12 @@ public class TrackManager
|
||||
}
|
||||
};
|
||||
|
||||
// An all-null filter must produce identical results to no filter, so collapse it to
|
||||
// null and take the unfiltered base path (preserves backward compatibility).
|
||||
// Always route through GetPagedFilteredAsync — it handles a null filter by skipping
|
||||
// all Where predicates, and it always includes Release. This removes the base-class
|
||||
// GetPagedAsync path, which has no .Include and would return entities with null Release.
|
||||
var effectiveFilter = filter is null || filter.IsEmpty ? null : filter;
|
||||
|
||||
var page = effectiveFilter is null
|
||||
? await Repository.GetPagedAsync(parameters)
|
||||
: await Repository.GetPagedFilteredAsync(parameters, effectiveFilter, cancellationToken);
|
||||
var page = await Repository.GetPagedFilteredAsync(parameters, effectiveFilter, cancellationToken);
|
||||
|
||||
var dtoPage = PagedResult<TrackDto>.From(page, page.Items.Select(TrackConverter.Convert));
|
||||
return ResultContainer<PagedResult<TrackDto>>.CreatePassResult(dtoPage);
|
||||
@@ -178,8 +178,20 @@ public class TrackManager
|
||||
entity.Title = title;
|
||||
entity.Artist = artist;
|
||||
|
||||
var added = await Repository.AddReleaseAsync(entity, cancellationToken);
|
||||
return ResultContainer<ReleaseDto>.CreatePassResult(TrackConverter.Convert(added));
|
||||
try
|
||||
{
|
||||
var added = await Repository.AddReleaseAsync(entity, cancellationToken);
|
||||
return ResultContainer<ReleaseDto>.CreatePassResult(TrackConverter.Convert(added));
|
||||
}
|
||||
catch (ClassifiedDbException ex) when (ex.Error.Category == DbErrorCategory.UniqueViolation)
|
||||
{
|
||||
// Concurrent upload inserted the same (title, artist) between our read and write.
|
||||
// Re-query and return the winning row. Should not return null here since the
|
||||
// constraint just fired, but re-throw if it does so the caller sees an error.
|
||||
var race = await Repository.GetReleaseByTitleAndArtistAsync(title, artist, cancellationToken);
|
||||
if (race is null) throw;
|
||||
return ResultContainer<ReleaseDto>.CreatePassResult(TrackConverter.Convert(race));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user