Added merge
This commit is contained in:
@@ -566,6 +566,7 @@ pub struct Stats {
|
||||
pub review_count: i64,
|
||||
pub error_count: i64,
|
||||
pub merged_count: i64,
|
||||
pub active_merges: i64,
|
||||
}
|
||||
|
||||
pub async fn get_stats(pool: &PgPool) -> Result<Stats, sqlx::Error> {
|
||||
@@ -576,7 +577,139 @@ pub async fn get_stats(pool: &PgPool) -> Result<Stats, sqlx::Error> {
|
||||
let (review_count,): (i64,) = sqlx::query_as("SELECT COUNT(*) FROM pending_tracks WHERE status = 'review'").fetch_one(pool).await?;
|
||||
let (error_count,): (i64,) = sqlx::query_as("SELECT COUNT(*) FROM pending_tracks WHERE status = 'error'").fetch_one(pool).await?;
|
||||
let (merged_count,): (i64,) = sqlx::query_as("SELECT COUNT(*) FROM pending_tracks WHERE status = 'merged'").fetch_one(pool).await?;
|
||||
Ok(Stats { total_tracks, total_artists, total_albums, pending_count, review_count, error_count, merged_count })
|
||||
let (active_merges,): (i64,) = sqlx::query_as("SELECT COUNT(*) FROM artist_merges WHERE status IN ('pending','processing')").fetch_one(pool).await?;
|
||||
Ok(Stats { total_tracks, total_artists, total_albums, pending_count, review_count, error_count, merged_count, active_merges })
|
||||
}
|
||||
|
||||
// =================== Library search ===================
|
||||
|
||||
#[derive(Debug, Serialize, sqlx::FromRow)]
|
||||
pub struct TrackRow {
|
||||
pub id: i64,
|
||||
pub title: String,
|
||||
pub artist_name: String,
|
||||
pub album_name: Option<String>,
|
||||
pub year: Option<i32>,
|
||||
pub track_number: Option<i32>,
|
||||
pub duration_secs: Option<f64>,
|
||||
pub genre: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, sqlx::FromRow)]
|
||||
pub struct AlbumRow {
|
||||
pub id: i64,
|
||||
pub name: String,
|
||||
pub artist_name: String,
|
||||
pub year: Option<i32>,
|
||||
pub track_count: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, sqlx::FromRow)]
|
||||
pub struct ArtistRow {
|
||||
pub id: i64,
|
||||
pub name: String,
|
||||
pub album_count: i64,
|
||||
pub track_count: i64,
|
||||
}
|
||||
|
||||
pub async fn search_tracks(
|
||||
pool: &PgPool,
|
||||
q: &str, artist: &str, album: &str,
|
||||
limit: i64, offset: i64,
|
||||
) -> Result<Vec<TrackRow>, sqlx::Error> {
|
||||
sqlx::query_as::<_, TrackRow>(
|
||||
r#"SELECT t.id, t.title, ar.name AS artist_name, al.name AS album_name,
|
||||
al.year, t.track_number, t.duration_secs, t.genre
|
||||
FROM tracks t
|
||||
JOIN track_artists ta ON ta.track_id = t.id AND ta.role = 'primary'
|
||||
JOIN artists ar ON ar.id = ta.artist_id
|
||||
LEFT JOIN albums al ON al.id = t.album_id
|
||||
WHERE ($1 = '' OR t.title ILIKE '%' || $1 || '%')
|
||||
AND ($2 = '' OR ar.name ILIKE '%' || $2 || '%')
|
||||
AND ($3 = '' OR al.name ILIKE '%' || $3 || '%')
|
||||
ORDER BY ar.name, al.name NULLS LAST, t.track_number NULLS LAST, t.title
|
||||
LIMIT $4 OFFSET $5"#,
|
||||
)
|
||||
.bind(q).bind(artist).bind(album).bind(limit).bind(offset)
|
||||
.fetch_all(pool).await
|
||||
}
|
||||
|
||||
pub async fn count_tracks(pool: &PgPool, q: &str, artist: &str, album: &str) -> Result<i64, sqlx::Error> {
|
||||
let (n,): (i64,) = sqlx::query_as(
|
||||
r#"SELECT COUNT(*) FROM tracks t
|
||||
JOIN track_artists ta ON ta.track_id = t.id AND ta.role = 'primary'
|
||||
JOIN artists ar ON ar.id = ta.artist_id
|
||||
LEFT JOIN albums al ON al.id = t.album_id
|
||||
WHERE ($1 = '' OR t.title ILIKE '%' || $1 || '%')
|
||||
AND ($2 = '' OR ar.name ILIKE '%' || $2 || '%')
|
||||
AND ($3 = '' OR al.name ILIKE '%' || $3 || '%')"#,
|
||||
)
|
||||
.bind(q).bind(artist).bind(album)
|
||||
.fetch_one(pool).await?;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
pub async fn search_albums(
|
||||
pool: &PgPool,
|
||||
q: &str, artist: &str,
|
||||
limit: i64, offset: i64,
|
||||
) -> Result<Vec<AlbumRow>, sqlx::Error> {
|
||||
sqlx::query_as::<_, AlbumRow>(
|
||||
r#"SELECT a.id, a.name, ar.name AS artist_name, a.year,
|
||||
COUNT(t.id) AS track_count
|
||||
FROM albums a
|
||||
JOIN artists ar ON ar.id = a.artist_id
|
||||
LEFT JOIN tracks t ON t.album_id = a.id
|
||||
WHERE ($1 = '' OR a.name ILIKE '%' || $1 || '%')
|
||||
AND ($2 = '' OR ar.name ILIKE '%' || $2 || '%')
|
||||
GROUP BY a.id, a.name, ar.name, a.year
|
||||
ORDER BY ar.name, a.year NULLS LAST, a.name
|
||||
LIMIT $3 OFFSET $4"#,
|
||||
)
|
||||
.bind(q).bind(artist).bind(limit).bind(offset)
|
||||
.fetch_all(pool).await
|
||||
}
|
||||
|
||||
pub async fn count_albums(pool: &PgPool, q: &str, artist: &str) -> Result<i64, sqlx::Error> {
|
||||
let (n,): (i64,) = sqlx::query_as(
|
||||
r#"SELECT COUNT(*) FROM albums a
|
||||
JOIN artists ar ON ar.id = a.artist_id
|
||||
WHERE ($1 = '' OR a.name ILIKE '%' || $1 || '%')
|
||||
AND ($2 = '' OR ar.name ILIKE '%' || $2 || '%')"#,
|
||||
)
|
||||
.bind(q).bind(artist)
|
||||
.fetch_one(pool).await?;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
pub async fn search_artists_lib(
|
||||
pool: &PgPool,
|
||||
q: &str,
|
||||
limit: i64, offset: i64,
|
||||
) -> Result<Vec<ArtistRow>, sqlx::Error> {
|
||||
sqlx::query_as::<_, ArtistRow>(
|
||||
r#"SELECT ar.id, ar.name,
|
||||
COUNT(DISTINCT al.id) AS album_count,
|
||||
COUNT(DISTINCT ta.track_id) AS track_count
|
||||
FROM artists ar
|
||||
LEFT JOIN albums al ON al.artist_id = ar.id
|
||||
LEFT JOIN track_artists ta ON ta.artist_id = ar.id AND ta.role = 'primary'
|
||||
WHERE ($1 = '' OR ar.name ILIKE '%' || $1 || '%')
|
||||
GROUP BY ar.id, ar.name
|
||||
ORDER BY ar.name
|
||||
LIMIT $2 OFFSET $3"#,
|
||||
)
|
||||
.bind(q).bind(limit).bind(offset)
|
||||
.fetch_all(pool).await
|
||||
}
|
||||
|
||||
pub async fn count_artists_lib(pool: &PgPool, q: &str) -> Result<i64, sqlx::Error> {
|
||||
let (n,): (i64,) = sqlx::query_as(
|
||||
"SELECT COUNT(*) FROM artists WHERE ($1 = '' OR name ILIKE '%' || $1 || '%')"
|
||||
)
|
||||
.bind(q)
|
||||
.fetch_one(pool).await?;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
// =================== Artist Merges ===================
|
||||
|
||||
Reference in New Issue
Block a user