feat(db): cascade-cleanup queries for M7 #372 track removal

DeleteTrack returns album_id + artist_id so the calling service can
chain the album-empty / artist-empty cascade. DeleteAlbumIfEmpty and
DeleteArtistIfEmpty are no-ops when other rows still reference the
parent — the service treats pgx.ErrNoRows as "not orphaned, skip".
This commit is contained in:
2026-05-02 21:53:33 -04:00
parent 9c53c9894a
commit 30b0edf97b
6 changed files with 103 additions and 0 deletions
+18
View File
@@ -33,6 +33,24 @@ func (q *Queries) CountArtistsMatching(ctx context.Context, dollar_1 string) (in
return count, err
}
const deleteArtistIfEmpty = `-- name: DeleteArtistIfEmpty :one
DELETE FROM artists a
WHERE a.id = $1
AND NOT EXISTS (SELECT 1 FROM albums al WHERE al.artist_id = a.id)
AND NOT EXISTS (SELECT 1 FROM tracks t WHERE t.artist_id = a.id)
RETURNING a.id
`
// M7 #372: deletes the artist row only when it has no remaining albums
// AND no remaining tracks (defensive — tracks can in principle exist
// without an album, though the scanner doesn't write that shape today).
func (q *Queries) DeleteArtistIfEmpty(ctx context.Context, id pgtype.UUID) (pgtype.UUID, error) {
row := q.db.QueryRow(ctx, deleteArtistIfEmpty, id)
var id_2 pgtype.UUID
err := row.Scan(&id_2)
return id_2, err
}
const getArtistByID = `-- name: GetArtistByID :one
SELECT id, name, sort_name, mbid, created_at, updated_at FROM artists WHERE id = $1
`