Files
db/src/queries/wanted.rs
T
2026-03-24 12:51:42 -04:00

98 lines
3.0 KiB
Rust

use chrono::Utc;
use sea_orm::sea_query::Expr;
use sea_orm::*;
use crate::entities::wanted_item::{
self, ActiveModel, Entity as WantedItems, ItemType, Model as WantedItem, WantedStatus,
};
use crate::error::{DbError, DbResult};
pub struct AddWantedItem<'a> {
pub item_type: ItemType,
pub name: &'a str,
pub musicbrainz_id: Option<&'a str>,
pub artist_id: Option<i32>,
pub album_id: Option<i32>,
pub track_id: Option<i32>,
pub user_id: Option<i32>,
}
pub async fn add(db: &DatabaseConnection, item: AddWantedItem<'_>) -> DbResult<WantedItem> {
let now = Utc::now().naive_utc();
let active = ActiveModel {
item_type: Set(item.item_type),
name: Set(item.name.to_string()),
musicbrainz_id: Set(item.musicbrainz_id.map(String::from)),
artist_id: Set(item.artist_id),
album_id: Set(item.album_id),
track_id: Set(item.track_id),
user_id: Set(item.user_id),
status: Set(WantedStatus::Wanted),
added_at: Set(now),
updated_at: Set(now),
..Default::default()
};
Ok(active.insert(db).await?)
}
pub async fn list(
db: &DatabaseConnection,
status_filter: Option<WantedStatus>,
user_id: Option<i32>,
) -> DbResult<Vec<WantedItem>> {
let mut query = WantedItems::find();
if let Some(status) = status_filter {
query = query.filter(wanted_item::Column::Status.eq(status));
}
if let Some(uid) = user_id {
query = query.filter(wanted_item::Column::UserId.eq(uid));
}
Ok(query.all(db).await?)
}
pub async fn get_by_id(db: &DatabaseConnection, id: i32) -> DbResult<WantedItem> {
WantedItems::find_by_id(id)
.one(db)
.await?
.ok_or_else(|| DbError::NotFound(format!("wanted_item id={id}")))
}
pub async fn update_status(
db: &DatabaseConnection,
id: i32,
status: WantedStatus,
) -> DbResult<WantedItem> {
let existing = get_by_id(db, id).await?;
let mut active: ActiveModel = existing.into();
active.status = Set(status);
active.updated_at = Set(Utc::now().naive_utc());
Ok(active.update(db).await?)
}
pub async fn find_by_mbid(
db: &DatabaseConnection,
musicbrainz_id: &str,
) -> DbResult<Option<WantedItem>> {
Ok(WantedItems::find()
.filter(wanted_item::Column::MusicbrainzId.eq(musicbrainz_id))
.one(db)
.await?)
}
pub async fn remove(db: &DatabaseConnection, id: i32) -> DbResult<()> {
WantedItems::delete_by_id(id).exec(db).await?;
Ok(())
}
/// Promote all Downloaded items to Owned status. Returns the count updated.
pub async fn promote_downloaded_to_owned(db: &DatabaseConnection) -> DbResult<u64> {
let now = Utc::now().naive_utc();
let result = WantedItems::update_many()
.col_expr(wanted_item::Column::Status, Expr::value("owned"))
.col_expr(wanted_item::Column::UpdatedAt, Expr::value(now))
.filter(wanted_item::Column::Status.eq(WantedStatus::Downloaded))
.exec(db)
.await?;
Ok(result.rows_affected)
}