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, pub album_id: Option, pub track_id: Option, pub user_id: Option, } pub async fn add(db: &DatabaseConnection, item: AddWantedItem<'_>) -> DbResult { 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, user_id: Option, ) -> DbResult> { 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 { 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 { 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> { 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 { 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) }