Async playlist operations
This commit is contained in:
parent
369bf3821b
commit
98bcd41e43
1 changed files with 88 additions and 59 deletions
|
@ -6,6 +6,7 @@ use std::time::Duration;
|
||||||
use native_db::*;
|
use native_db::*;
|
||||||
use native_model::{native_model, Model};
|
use native_model::{native_model, Model};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tokio::task::spawn_blocking;
|
||||||
|
|
||||||
use crate::app::{index, ndb, Error};
|
use crate::app::{index, ndb, Error};
|
||||||
|
|
||||||
|
@ -79,24 +80,36 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_playlists(&self, owner: &str) -> Result<Vec<PlaylistHeader>, Error> {
|
pub async fn list_playlists(&self, owner: &str) -> Result<Vec<PlaylistHeader>, Error> {
|
||||||
let transaction = self.db.r_transaction()?;
|
spawn_blocking({
|
||||||
|
let manager = self.clone();
|
||||||
|
let owner = owner.to_owned();
|
||||||
|
move || {
|
||||||
|
let transaction = manager.db.r_transaction()?;
|
||||||
let playlists = transaction
|
let playlists = transaction
|
||||||
.scan()
|
.scan()
|
||||||
.secondary::<PlaylistModel>(PlaylistModelKey::owner)?
|
.secondary::<PlaylistModel>(PlaylistModelKey::owner)?
|
||||||
.range(owner..=owner)?
|
.range(owner.as_str()..=owner.as_str())?
|
||||||
.filter_map(|p| p.ok())
|
.filter_map(|p| p.ok())
|
||||||
.map(PlaylistHeader::from)
|
.map(PlaylistHeader::from)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
Ok(playlists)
|
Ok(playlists)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn save_playlist(
|
pub async fn save_playlist(
|
||||||
&self,
|
&self,
|
||||||
playlist_name: &str,
|
name: &str,
|
||||||
owner: &str,
|
owner: &str,
|
||||||
songs: Vec<index::Song>,
|
songs: Vec<index::Song>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let transaction = self.db.rw_transaction()?;
|
spawn_blocking({
|
||||||
|
let manager = self.clone();
|
||||||
|
let owner = owner.to_owned();
|
||||||
|
let name = name.to_owned();
|
||||||
|
move || {
|
||||||
|
let transaction = manager.db.rw_transaction()?;
|
||||||
|
|
||||||
let duration = songs
|
let duration = songs
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -114,13 +127,13 @@ impl Manager {
|
||||||
|
|
||||||
transaction.remove::<PlaylistModel>(PlaylistModel {
|
transaction.remove::<PlaylistModel>(PlaylistModel {
|
||||||
owner: owner.to_owned(),
|
owner: owner.to_owned(),
|
||||||
name: playlist_name.to_owned(),
|
name: name.to_owned(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
transaction.insert::<PlaylistModel>(PlaylistModel {
|
transaction.insert::<PlaylistModel>(PlaylistModel {
|
||||||
owner: owner.to_owned(),
|
owner: owner.to_owned(),
|
||||||
name: playlist_name.to_owned(),
|
name: name.to_owned(),
|
||||||
duration: Duration::from_secs(duration),
|
duration: Duration::from_secs(duration),
|
||||||
num_songs_by_genre,
|
num_songs_by_genre,
|
||||||
virtual_paths,
|
virtual_paths,
|
||||||
|
@ -130,29 +143,45 @@ impl Manager {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn read_playlist(&self, playlist_name: &str, owner: &str) -> Result<Playlist, Error> {
|
pub async fn read_playlist(&self, name: &str, owner: &str) -> Result<Playlist, Error> {
|
||||||
let transaction = self.db.r_transaction()?;
|
spawn_blocking({
|
||||||
match transaction
|
let manager = self.clone();
|
||||||
.get()
|
let owner = owner.to_owned();
|
||||||
.primary::<PlaylistModel>((owner, playlist_name))
|
let name = name.to_owned();
|
||||||
{
|
move || {
|
||||||
|
let transaction = manager.db.r_transaction()?;
|
||||||
|
match transaction.get().primary::<PlaylistModel>((&owner, &name)) {
|
||||||
Ok(Some(p)) => Ok(Playlist::from(p)),
|
Ok(Some(p)) => Ok(Playlist::from(p)),
|
||||||
Ok(None) => Err(Error::PlaylistNotFound),
|
Ok(None) => Err(Error::PlaylistNotFound),
|
||||||
Err(e) => Err(Error::NativeDatabase(e)),
|
Err(e) => Err(Error::NativeDatabase(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn delete_playlist(&self, playlist_name: &str, owner: &str) -> Result<(), Error> {
|
pub async fn delete_playlist(&self, name: &str, owner: &str) -> Result<(), Error> {
|
||||||
let transaction = self.db.rw_transaction()?;
|
spawn_blocking({
|
||||||
|
let manager = self.clone();
|
||||||
|
let owner = owner.to_owned();
|
||||||
|
let name = name.to_owned();
|
||||||
|
move || {
|
||||||
|
let transaction = manager.db.rw_transaction()?;
|
||||||
transaction.remove::<PlaylistModel>(PlaylistModel {
|
transaction.remove::<PlaylistModel>(PlaylistModel {
|
||||||
name: playlist_name.to_owned(),
|
name: name.to_owned(),
|
||||||
owner: owner.to_owned(),
|
owner: owner.to_owned(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})?;
|
})?;
|
||||||
transaction.commit()?;
|
transaction.commit()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.await?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue