Fixes and preparation for in-memory solution

This commit is contained in:
Jan-Peter von Hunnius 2025-03-30 17:07:36 +02:00
parent 02ff6eddb2
commit 12a3868a46
2 changed files with 45 additions and 7 deletions

View file

@ -18,3 +18,4 @@ tokio = { version = "1.44.1", features = ["full"] }
rusqlite = { version = "0.32.1", features = ["bundled", "backup"] } rusqlite = { version = "0.32.1", features = ["bundled", "backup"] }
serde_json = "1.0.140" serde_json = "1.0.140"
futures = "0.3.31" futures = "0.3.31"
once_cell = "1.20.2"

View file

@ -1,11 +1,36 @@
use std::collections::HashMap;
use reqwest::get; use reqwest::get;
use rusqlite::backup::Backup; use rusqlite::backup::Backup;
use rusqlite::{params, CachedStatement, Connection}; use rusqlite::{params, CachedStatement, Connection};
use serde_json::Value; use serde_json::Value;
use std::env; use std::env;
use std::fs; use std::fs;
use once_cell::sync::Lazy;
use std::sync::Mutex;
use futures::future::{join_all};
use tokio::sync::Semaphore; 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<Mutex<HashMap<TripletKey, BestCarRecord>>> = Lazy::new(|| Mutex::new(HashMap::new()));
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
@ -19,9 +44,6 @@ async fn main() {
let command = argument.as_str(); let command = argument.as_str();
match command { match command {
"init" => { "init" => {
get_cars_file().await;
get_tracks_file().await;
let mut connection = let mut connection =
Connection::open_in_memory().expect("Issue opening in-memory DB!"); Connection::open_in_memory().expect("Issue opening in-memory DB!");
@ -39,6 +61,8 @@ async fn main() {
file.close().unwrap(); file.close().unwrap();
} }
"fetch" => { "fetch" => {
get_cars_file().await;
get_tracks_file().await;
fetch_times().await; fetch_times().await;
} }
"parse" => { "parse" => {
@ -300,6 +324,7 @@ async fn parse_car_times(rid: String, statement: &mut CachedStatement<'_>) {
time.to_string().as_str(), time.to_string().as_str(),
config, 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); 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) { 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!"); 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(); let permit = semaphore.clone().acquire_owned().await.unwrap();
handles.push(tokio::spawn(async move { handles.push(tokio::spawn(async move {
fetch_car(car).await; fetch_car(car).await;
drop(permit); // Release semaphore drop(permit);
})); }));
} }
// Wait for all fetch tasks to complete
join_all(handles).await; join_all(handles).await;
} }
async fn fetch_car(rid: String) { async fn fetch_car(rid: String) {
let file_name = rid.to_owned() + ".json"; let file_name = rid.to_owned() + ".json";
let url = "https://api.topdrivesrecords.com/car/".to_owned() + rid.as_str(); 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(); 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; get_file(url.as_str(), local_file_path.as_str()).await;
} }
fn get_cars_from_db() -> Vec<String> { fn get_cars_from_db() -> Vec<String> {