Caching SQL INSERTS

This commit is contained in:
Jan-Peter von Hunnius 2025-03-23 10:35:55 +01:00
parent 2fa2966aaa
commit 137ebde68b
4 changed files with 59 additions and 50 deletions

View file

@ -2,7 +2,6 @@ WITH RECURSIVE rq_range AS (
SELECT DISTINCT rq from cars SELECT DISTINCT rq from cars
), ),
track_combinations AS ( track_combinations AS (
-- Extract unique human-readable track_id and track_type combinations
SELECT DISTINCT track_id, track_type SELECT DISTINCT track_id, track_type
FROM car_track_times FROM car_track_times
), ),

View file

@ -2,7 +2,6 @@ WITH RECURSIVE rq_range AS (
SELECT DISTINCT rq from cars SELECT DISTINCT rq from cars
), ),
track_combinations AS ( track_combinations AS (
-- Extract unique human-readable track_id and track_type combinations
SELECT DISTINCT track_id, track_type SELECT DISTINCT track_id, track_type
FROM car_track_times FROM car_track_times
), ),

View file

@ -1,3 +0,0 @@
UPDATE car_track_times
SET time = 2000 / time
WHERE track_id LIKE 'Test Bowl%';

View file

@ -1,5 +1,5 @@
use reqwest::get; use reqwest::get;
use rusqlite::{params, 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;
@ -39,7 +39,7 @@ async fn main() {
async fn list_best_cars() { async fn list_best_cars() {
todo!() todo!()
} }
async fn parse_car_times(rid: String, connection: &Connection) { async fn parse_car_times(rid: String, statement: &mut CachedStatement<'_>) {
let file_name = rid.to_owned() + ".json"; let file_name = rid.to_owned() + ".json";
let local_file_path = "times/".to_owned() + file_name.as_str(); let local_file_path = "times/".to_owned() + file_name.as_str();
let file_content = fs::read_to_string(local_file_path); let file_content = fs::read_to_string(local_file_path);
@ -57,17 +57,26 @@ async fn parse_car_times(rid: String, connection: &Connection) {
{ {
// Extract time and configuration // Extract time and configuration
let mut time = details["t"].as_f64().unwrap_or(0.0); let mut time = details["t"].as_f64().unwrap_or(0.0);
let down_votes = details["down"].as_array();
let no_down_votes = match down_votes {
None => true,
Some(votes) => votes.len() <= 0,
};
if track_id.starts_with("testBowl") { if track_id.starts_with("testBowl") {
time = 2000.0 / time; time = 2000.0 / time;
} }
// Insert into the database // Insert into the database
if time > 0.0 { if time > 1.2 && no_down_votes {
let _ = connection.execute( let _ = statement.execute([
"INSERT INTO car_track_times (car_rid, track_id, track_type, time, configuration) rid.as_str(),
VALUES (?1, ?2, ?3, ?4, ?5)", translate_track_name(cleaned_track_id),
params![rid, translate_track_name(cleaned_track_id), translate_track_type(track_type), time, config], translate_track_type(track_type),
); time.to_string().as_str(),
config,
]);
} }
} }
} }
@ -78,9 +87,13 @@ async fn parse_car_times(rid: String, connection: &Connection) {
} }
async fn parse_all_times() { async fn parse_all_times() {
let connection = Connection::open("top_drives.db").expect("Issue opening DB file!"); let connection = Connection::open("top_drives.db").expect("Issue opening DB file!");
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!");
for car in get_cars_from_db() { for car in get_cars_from_db() {
parse_car_times(car, &connection).await; parse_car_times(car, &mut statement).await;
connection.flush_prepared_statement_cache();
} }
let _ = connection.execute("DELETE FROM car_track_times WHERE time < 1.2;", ());
} }
fn parse_cars() { fn parse_cars() {
let connection = Connection::open("top_drives.db").expect("Issue opening DB file!"); let connection = Connection::open("top_drives.db").expect("Issue opening DB file!");
@ -90,40 +103,40 @@ fn parse_cars() {
serde_json::from_str(&fs::read_to_string(cars_file).unwrap()).unwrap(); serde_json::from_str(&fs::read_to_string(cars_file).unwrap()).unwrap();
for car in cars_data { for car in cars_data {
let _ = connection.execute( if let Err(e) = connection.execute("INSERT OR IGNORE INTO cars
"INSERT OR IGNORE INTO cars
(class, rq, onlyName, brand, year, abs, tcs, clearance, country, topSpeed, acel, hand, (class, rq, onlyName, brand, year, abs, tcs, clearance, country, topSpeed, acel, hand,
drive, tyres, mra, weight, name, rid, prize, bodyTypes, fuel, seats, engine, tags, guid, brake) drive, tyres, mra, weight, name, rid, prize, bodyTypes, fuel, seats, engine, tags, guid, brake)
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26)", VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26);",
params![ params![
car["class"].as_str(), car["class"].as_str().unwrap(),
car["rq"].as_i64(), car["rq"].as_u64().unwrap(),
car["onlyName"].as_str(), car["onlyName"].as_str().unwrap(),
car["brand"].as_str(), car["brand"].as_str().unwrap(),
car["year"].as_i64(), car["year"].as_u64().unwrap(),
car["abs"].as_bool(), car["abs"].as_bool().unwrap(),
car["tcs"].as_bool(), car["tcs"].as_bool().unwrap(),
car["clearance"].as_str(), car["clearance"].as_str().unwrap(),
car["country"].as_str(), car["country"].as_str().unwrap(),
car["topSpeed"].as_i64(), car["topSpeed"].as_u64().unwrap(),
car["acel"].as_f64(), car["acel"].as_f64().unwrap_or_default(),
car["hand"].as_i64(), car["hand"].as_u64().unwrap(),
car["drive"].as_str(), car["drive"].as_str().unwrap(),
car["tyres"].as_str(), car["tyres"].as_str().unwrap(),
car["mra"].as_f64(), car["mra"].as_f64().unwrap_or_default(),
car["weight"].as_i64(), car["weight"].as_u64().unwrap(),
car["name"].as_str(), car["name"].as_str().unwrap(),
car["rid"].as_str(), car["rid"].as_str().unwrap(),
car["prize"].as_bool(), car["prize"].as_bool().unwrap(),
serde_json::to_string(&car["bodyTypes"]).unwrap(), Some(serde_json::to_string(&car["bodyTypes"]).unwrap().as_str()).unwrap_or_default(),
car["fuel"].as_str(), car["fuel"].as_str().unwrap(),
car["seats"].as_str(), car["seats"].as_u64().unwrap_or_default(),
car["engine"].as_str(), car["engine"].as_str().unwrap(),
serde_json::to_string(&car["tags"]).unwrap(), Some(serde_json::to_string(&car["tags"]).unwrap().as_str()).unwrap_or_default(),
car["guid"].as_str(), car["guid"].as_str().unwrap(),
car["brake"].as_str(), car["brake"].as_str().unwrap(),
], ]) {
); eprintln!("Insertion error: {}", e);
};
} }
} }
fn split_prefix_postfix<'a>(input: &'a str, delimiter: &'a str) -> Option<(&'a str, &'a str)> { fn split_prefix_postfix<'a>(input: &'a str, delimiter: &'a str) -> Option<(&'a str, &'a str)> {
@ -214,10 +227,10 @@ fn init_db() {
); );
} }
async fn get_tracks_file() { async fn get_tracks_file() {
get_file("https://raw.githubusercontent.com/TiagoXavi/topdrives-records/refs/heads/main/src/database/tracks_repo.json","tracks_repo.json").await; get_file("https://github.com/TiagoXavi/topdrives-records/raw/refs/heads/main/src/database/tracks_repo.json","tracks_repo.json").await;
} }
async fn get_cars_file() { async fn get_cars_file() {
get_file("https://github.com/TiagoXavi/topdrives-records/raw/refs/heads/main/src/database/cars_final_PL24_2-fixed.json", "cars_repo.json").await; get_file("https://github.com/TiagoXavi/topdrives-records/raw/refs/heads/main/src/database/cars_final_PL25-fixed.json", "cars_repo.json").await;
} }
async fn get_file(file_url: &str, local_file_path: &str) { async fn get_file(file_url: &str, local_file_path: &str) {
let _ = fs::remove_file(local_file_path); let _ = fs::remove_file(local_file_path);
@ -344,10 +357,11 @@ fn translate_track_name(track_code: &str) -> &str {
"miBeachDrag" => "Miami Beach Drag", "miBeachDrag" => "Miami Beach Drag",
"mnGforce" => "Monaco G-Force Test", "mnGforce" => "Monaco G-Force Test",
"mnHairpin" => "Monaco Hairpin", "mnHairpin" => "Monaco Hairpin",
"mnCityNarrow" => "Monaco Narrow Streets", "mnNarrowStreets" => "Monaco Narrow Streets",
"mnCity" => "Monaco Streets", "mnCity" => "Monaco Streets",
"mnCityLong" => "Monaco Streets Long", "mnCityLong" => "Monaco Streets Long",
"moto" => "Motocross Track", "moto" => "Motocross Track",
"mtButte" => "mtButte",
"mtHairpin" => "Mountain Hairpin", "mtHairpin" => "Mountain Hairpin",
"mtHill" => "Mountain Hill Climb", "mtHill" => "Mountain Hill Climb",
"mtIncline" => "Mountain Incline Road", "mtIncline" => "Mountain Incline Road",