Design Prot Merge #1
@@ -8,7 +8,7 @@ using Musify.Domain.ValueObjects;
|
||||
|
||||
namespace Musify.Application.Services;
|
||||
|
||||
public sealed record YouTubeTrackProvision(Track Track, bool Created, YouTubeSongResult? Song);
|
||||
public sealed record YouTubeTrackProvision(Track Track, YouTubeSongResult? Song);
|
||||
|
||||
public sealed class YouTubeTrackProvisioner(
|
||||
IDatabase database,
|
||||
@@ -26,7 +26,7 @@ public sealed class YouTubeTrackProvisioner(
|
||||
{
|
||||
var existing = await FindAsync(videoId, cancellationToken);
|
||||
if (existing is not null)
|
||||
return new YouTubeTrackProvision(existing, Created: false, Song: null);
|
||||
return new YouTubeTrackProvision(existing, Song: null);
|
||||
|
||||
var songResult = await youTubeMusicService.GetSongAsync(videoId, cancellationToken);
|
||||
if (songResult.IsError)
|
||||
@@ -81,7 +81,7 @@ public sealed class YouTubeTrackProvisioner(
|
||||
{
|
||||
await database.SaveChangesAsync(cancellationToken);
|
||||
logger.LogInformation("Created YouTube track {VideoId} ({TrackId})", videoId, track.Id);
|
||||
return new YouTubeTrackProvision(track, Created: true, Song: song);
|
||||
return new YouTubeTrackProvision(track, Song: song);
|
||||
}
|
||||
catch (DbUpdateException)
|
||||
{
|
||||
@@ -92,7 +92,7 @@ public sealed class YouTubeTrackProvisioner(
|
||||
logger.LogWarning("YouTube track {VideoId} creation raced but could not be refetched", videoId);
|
||||
return Error.Conflict(description: "The track was just created by another request. Retry the operation.");
|
||||
}
|
||||
return new YouTubeTrackProvision(refetched, Created: false, Song: null);
|
||||
return new YouTubeTrackProvision(refetched, Song: null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,30 @@ public sealed class YouTubeTrackProvisioner(
|
||||
if (existing is not null)
|
||||
return existing;
|
||||
|
||||
if (byExternalId)
|
||||
{
|
||||
var adoptable = await database.Artists
|
||||
.SingleOrDefaultAsync(a => a.ExternalId == null && a.UserId == null && a.NormalizedName == normalized, cancellationToken);
|
||||
if (adoptable is not null)
|
||||
{
|
||||
var previousName = adoptable.Name;
|
||||
adoptable.ExternalId = reference.Id;
|
||||
adoptable.Name = name;
|
||||
|
||||
try
|
||||
{
|
||||
await database.SaveChangesAsync(cancellationToken);
|
||||
return adoptable;
|
||||
}
|
||||
catch (DbUpdateException)
|
||||
{
|
||||
adoptable.ExternalId = null;
|
||||
adoptable.Name = previousName;
|
||||
return await database.Artists.SingleAsync(a => a.ExternalId == reference.Id, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var artist = new Artist
|
||||
{
|
||||
Name = name,
|
||||
|
||||
@@ -47,6 +47,14 @@ namespace Musify.Application.Users
|
||||
user.SecondName = request.SecondName;
|
||||
user.ProfilePictureUrl = request.ProfilePictureUrl;
|
||||
|
||||
var artist = await database.Artists
|
||||
.SingleOrDefaultAsync(a => a.UserId == request.Id, cancellationToken);
|
||||
if (artist is not null)
|
||||
{
|
||||
artist.Name = request.Name;
|
||||
artist.NormalizedName = request.Name.ToUpperInvariant();
|
||||
}
|
||||
|
||||
var written = await database.SaveChangesAsync(cancellationToken);
|
||||
if (written > 0)
|
||||
logger.LogInformation("Synced profile for user {UserId}", request.Id);
|
||||
|
||||
+12
-2
@@ -108,6 +108,11 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
||||
WHERE t."Source" = 0 AND ut."TrackId" = t."Id";
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
DELETE FROM "Tracks" WHERE "Source" = 0 AND "OwnerUserId" IS NULL;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
"""
|
||||
INSERT INTO "Artists" ("Id", "Name", "NormalizedName", "UserId", "ExternalId", "CreatedAt", "UpdatedAt")
|
||||
@@ -120,7 +125,12 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
||||
"""
|
||||
INSERT INTO "Artists" ("Id", "Name", "NormalizedName", "UserId", "ExternalId", "CreatedAt", "UpdatedAt")
|
||||
SELECT gen_random_uuid(), s."Artist", upper(s."Artist"), NULL, NULL, now(), now()
|
||||
FROM (SELECT DISTINCT "Artist" FROM "Tracks" WHERE "Source" = 1 AND "Artist" IS NOT NULL) s;
|
||||
FROM (
|
||||
SELECT DISTINCT ON (upper("Artist")) "Artist"
|
||||
FROM "Tracks"
|
||||
WHERE "Source" = 1 AND "Artist" IS NOT NULL
|
||||
ORDER BY upper("Artist"), "Artist"
|
||||
) s;
|
||||
""");
|
||||
|
||||
migrationBuilder.Sql(
|
||||
@@ -135,7 +145,7 @@ namespace Musify.Infrastructure.Persistence.Migrations
|
||||
"""
|
||||
INSERT INTO "TrackArtist" ("TrackId", "ArtistId", "Position")
|
||||
SELECT t."Id", a."Id", 0 FROM "Tracks" t
|
||||
JOIN "Artists" a ON a."UserId" IS NULL AND a."ExternalId" IS NULL AND a."Name" = t."Artist"
|
||||
JOIN "Artists" a ON a."UserId" IS NULL AND a."ExternalId" IS NULL AND a."NormalizedName" = upper(t."Artist")
|
||||
WHERE t."Source" = 1 AND t."Artist" IS NOT NULL;
|
||||
""");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user