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:
@@ -69,6 +69,37 @@ func (q *Queries) CountTracksMatchingForUser(ctx context.Context, arg CountTrack
|
||||
return count, err
|
||||
}
|
||||
|
||||
const deleteTrack = `-- name: DeleteTrack :one
|
||||
DELETE FROM tracks WHERE id = $1
|
||||
RETURNING id, album_id, artist_id, file_path, mbid
|
||||
`
|
||||
|
||||
type DeleteTrackRow struct {
|
||||
ID pgtype.UUID
|
||||
AlbumID pgtype.UUID
|
||||
ArtistID pgtype.UUID
|
||||
FilePath string
|
||||
Mbid *string
|
||||
}
|
||||
|
||||
// M7 #372: hard delete with FK cascade. The CASCADE on track_id from
|
||||
// play_events / general_likes_tracks / lidarr_quarantine /
|
||||
// lidarr_quarantine_actions handles their cleanup. RETURNING gives us
|
||||
// album_id + artist_id for the album-empty / artist-empty cascade
|
||||
// checks the service does next.
|
||||
func (q *Queries) DeleteTrack(ctx context.Context, id pgtype.UUID) (DeleteTrackRow, error) {
|
||||
row := q.db.QueryRow(ctx, deleteTrack, id)
|
||||
var i DeleteTrackRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.AlbumID,
|
||||
&i.ArtistID,
|
||||
&i.FilePath,
|
||||
&i.Mbid,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTrackByID = `-- name: GetTrackByID :one
|
||||
SELECT id, title, album_id, artist_id, track_number, disc_number, duration_ms, file_path, file_size, file_format, bitrate, mbid, genre, added_at, updated_at FROM tracks WHERE id = $1
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user