zoodex/src/data_manager.rs

128 lines
3.6 KiB
Rust
Raw Normal View History

2025-02-05 14:57:07 +01:00
use async_sqlite :: * ;
use async_sqlite :: Error :: * ;
use async_sqlite :: rusqlite :: OpenFlags ;
use async_sqlite :: rusqlite :: Row ;
use async_sqlite :: rusqlite :: Error :: * ;
use async_sqlite :: rusqlite :: ffi :: ErrorCode :: * ;
use fallible_iterator :: * ;
use std :: path :: * ;
2024-11-20 16:32:37 +01:00
2025-02-05 14:57:07 +01:00
use crate :: error :: * ;
use crate :: error :: ZoodexError :: * ;
2024-11-20 16:32:37 +01:00
2025-02-05 00:03:26 +01:00
pub struct DataManager { sqlite_client : Client }
2024-11-20 16:32:37 +01:00
2025-02-05 00:03:26 +01:00
impl DataManager {
pub async fn new () -> Result <Self> {
let sqlite_client = ClientBuilder :: new ()
. path ("zoodex.sqlite")
. flags ( OpenFlags :: SQLITE_OPEN_READ_WRITE | OpenFlags :: SQLITE_OPEN_NO_MUTEX )
. open ()
. await ? ;
Ok ( Self { sqlite_client } )
}
2025-02-05 00:03:26 +01:00
pub async fn get_collection_overview ( & self ) -> CollectionOverview {
self . sqlite_client . conn ( |sqlite_connection| {
let films = sqlite_connection
. prepare ( "
select uuid , name , original_name , release_date , runtime_minutes , poster_file_path
from films
order by release_date desc
" ) ?
. query (()) ?
. map (row_to_film_overview)
. collect () ? ;
let series = sqlite_connection
. prepare ( "
select series . uuid , series . name , series . original_name , series . poster_file_path ,
min ( episodes . release_date )
from series , seasons , episodes
where series . uuid = seasons . series and seasons . uuid = episodes . season
group by series . uuid
" ) ?
. query (()) ?
. map (row_to_series_overview)
. collect () ? ;
Ok ( CollectionOverview { films , series } )
} ) . await . unwrap ()
}
}
pub struct CollectionOverview {
pub films : Vec <FilmOverview> ,
pub series : Vec <SeriesOverview> ,
2024-11-20 16:32:37 +01:00
}
2024-11-29 21:06:14 +01:00
# [ derive (Clone) ] pub struct FilmOverview {
pub uuid : String ,
pub name : String ,
pub original_name : Option <String> ,
pub release_date : String , // TODO: Switch to chrono types, I think rusqlite has crate option for it
pub runtime_minutes : u32 ,
pub poster_file_path : Option <PathBuf> ,
}
# [ derive (Clone) ] pub struct SeriesOverview {
pub uuid : String ,
pub name : String ,
pub original_name : Option <String> ,
pub first_release_date : String , // TODO: Switch to chrono types, I think rusqlite has crate option for it
pub poster_file_path : Option <PathBuf> ,
}
fn row_to_film_overview ( row : & Row ) -> rusqlite :: Result <FilmOverview> {
let uuid = row . get (0) ? ;
let name = row . get (1) ? ;
let original_name = row . get (2) ? ;
let release_date = row . get (3) ? ;
let runtime_minutes = row . get (4) ? ;
let poster_file_path = row . get :: < _ , Option <String> > (5) ?
. map ( PathBuf :: from ) ;
Ok ( FilmOverview {
uuid ,
name ,
original_name ,
release_date ,
runtime_minutes ,
poster_file_path ,
} )
}
fn row_to_series_overview ( row : & Row ) -> rusqlite :: Result <SeriesOverview> {
let uuid = row . get (0) ? ;
let name = row . get (1) ? ;
let original_name = row . get (2) ? ;
let poster_file_path = row. get :: < _ , Option <String> > (3) ?
. map ( PathBuf :: from ) ;
let first_release_date = row . get (4) ? ;
Ok ( SeriesOverview { uuid , name , original_name , first_release_date , poster_file_path } )
}
impl From <Error> for ZoodexError {
fn from ( error : Error ) -> Self {
match error {
Rusqlite (error) => ZoodexError :: from (error) ,
_ => panic ! () ,
}
}
}
impl From < rusqlite :: Error > for ZoodexError {
fn from ( error : rusqlite :: Error ) -> Self {
2024-11-29 21:06:14 +01:00
match error {
SqliteFailure ( error , _ ) => {
match error . code {
CannotOpen => CollectionFileReadError ,
_ => panic ! () ,
}
} ,
2024-11-29 21:06:14 +01:00
_ => panic ! () ,
}
}
}