98 lines
3.0 KiB
Rust
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)
|
|
}
|