diff --git a/Cargo.toml b/Cargo.toml index 6e35502..e2282c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ tokio = { version = "1.44.1", features = ["full"] } rusqlite = { version = "0.32.1", features = ["bundled", "backup"] } serde_json = "1.0.140" futures = "0.3.31" +once_cell = "1.20.2" diff --git a/src/records.rs b/src/records.rs index b6f7078..14fff61 100644 --- a/src/records.rs +++ b/src/records.rs @@ -1,11 +1,36 @@ +use std::collections::HashMap; use reqwest::get; use rusqlite::backup::Backup; use rusqlite::{params, CachedStatement, Connection}; use serde_json::Value; use std::env; use std::fs; +use once_cell::sync::Lazy; +use std::sync::Mutex; +use futures::future::{join_all}; use tokio::sync::Semaphore; -use futures::future::join_all; + +#[derive(Debug, Clone)] +struct Car { + rid: String, + brand: String, + only_name: String, + year: u16, + rq: u8, + drive: String, + tyres: String, + top_speed: u32, + acel: f64, + hand: u32, +} +#[derive(Debug, Clone)] +struct BestCarRecord { + car_rid: String, + configuration: String, + time: f64, +} +type TripletKey = (String, u8, String); // (Track ID, RQ, Surface) +static BEST_CARS: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); #[tokio::main] async fn main() { @@ -19,9 +44,6 @@ async fn main() { let command = argument.as_str(); match command { "init" => { - get_cars_file().await; - get_tracks_file().await; - let mut connection = Connection::open_in_memory().expect("Issue opening in-memory DB!"); @@ -39,6 +61,8 @@ async fn main() { file.close().unwrap(); } "fetch" => { + get_cars_file().await; + get_tracks_file().await; fetch_times().await; } "parse" => { @@ -300,6 +324,7 @@ async fn parse_car_times(rid: String, statement: &mut CachedStatement<'_>) { time.to_string().as_str(), config, ]); +//TODO: update_best_car(cleaned_track_id, translate_track_type(track_type), None) } } } @@ -308,6 +333,18 @@ async fn parse_car_times(rid: String, statement: &mut CachedStatement<'_>) { } println!("Track times imported for {}", rid); } +fn update_best_car(track_id: &str, rq: u8, surface: &str, new_record: BestCarRecord) { + let key = (track_id.to_string(), rq, surface.to_string()); + let mut best_cars = BEST_CARS.lock().unwrap(); + + if let Some(existing) = best_cars.get(&key) { + if new_record.time < existing.time { + best_cars.insert(key, new_record); + } + } else { + best_cars.insert(key, new_record); + } +} async fn parse_all_times(connection: &mut Connection) { let mut statement = connection.prepare_cached("INSERT INTO car_track_times (car_rid, track_id, track_type, time, configuration) VALUES (?1, ?2, ?3, ?4, ?5)").expect("Could not prepare statement!"); @@ -376,17 +413,17 @@ async fn fetch_times() { let permit = semaphore.clone().acquire_owned().await.unwrap(); handles.push(tokio::spawn(async move { fetch_car(car).await; - drop(permit); // Release semaphore + drop(permit); })); } - // Wait for all fetch tasks to complete + join_all(handles).await; } async fn fetch_car(rid: String) { let file_name = rid.to_owned() + ".json"; let url = "https://api.topdrivesrecords.com/car/".to_owned() + rid.as_str(); - println!("Fetching {}.", url); let local_file_path = "times/".to_owned() + file_name.as_str(); + println!("Fetching {}.", url); get_file(url.as_str(), local_file_path.as_str()).await; } fn get_cars_from_db() -> Vec {