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> {
|
2025-02-04 23:46:51 +01:00
|
|
|
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 {
|
2025-02-04 23:46:51 +01:00
|
|
|
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 ()
|
|
|
|
}
|
|
|
|
}
|
2024-12-23 23:20:08 +01:00
|
|
|
|
2025-02-04 23:46:51 +01:00
|
|
|
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
|
|
|
|
2025-02-04 23:46:51 +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> {
|
2024-12-23 23:25:25 +01:00
|
|
|
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 ) ;
|
|
|
|
|
2025-02-04 23:46:51 +01:00
|
|
|
Ok ( FilmOverview {
|
2024-12-23 23:25:25 +01:00
|
|
|
uuid ,
|
|
|
|
name ,
|
|
|
|
original_name ,
|
|
|
|
release_date ,
|
|
|
|
runtime_minutes ,
|
|
|
|
poster_file_path ,
|
|
|
|
} )
|
|
|
|
}
|
2025-02-04 23:46:51 +01:00
|
|
|
fn row_to_series_overview ( row : & Row ) -> rusqlite :: Result <SeriesOverview> {
|
2024-12-23 23:25:25 +01:00
|
|
|
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 ) ;
|
2025-02-04 23:46:51 +01:00
|
|
|
let first_release_date = row . get (4) ? ;
|
2024-12-23 23:25:25 +01:00
|
|
|
|
2025-02-04 23:46:51 +01:00
|
|
|
Ok ( SeriesOverview { uuid , name , original_name , first_release_date , poster_file_path } )
|
2024-12-23 23:25:25 +01:00
|
|
|
}
|
|
|
|
|
2024-11-30 14:38:08 +01:00
|
|
|
impl From <Error> for ZoodexError {
|
|
|
|
fn from ( error : Error ) -> Self {
|
2024-12-23 23:20:08 +01:00
|
|
|
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 {
|
2024-11-30 14:38:08 +01:00
|
|
|
SqliteFailure ( error , _ ) => {
|
|
|
|
match error . code {
|
2024-12-23 23:20:08 +01:00
|
|
|
CannotOpen => CollectionFileReadError ,
|
2024-11-30 14:38:08 +01:00
|
|
|
_ => panic ! () ,
|
|
|
|
}
|
|
|
|
} ,
|
2024-11-29 21:06:14 +01:00
|
|
|
_ => panic ! () ,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|