// grimhilde - mirror stats // Copyright (C) 2022 Amanda Graven and Emelie Graven // Licensed under the EUPL // use std::error::Error as StdError; use sqlx::PgPool; use crate::Request; /// Connect to a postgress address. pub async fn connect(address: &str) -> sqlx::Result { let pool = PgPool::connect(address).await?; sqlx::migrate!().run(&pool).await?; Ok(pool) } /// Insert a request hit into the database pub async fn insert(pool: &PgPool, req: Request) -> Result<(), Box> { let mut trans = pool.begin().await?; // Get the id's for deduplicated values. Insert a value if one is missing. sqlx::query!( "INSERT INTO paths (path) VALUES ($1) ON CONFLICT DO NOTHING", &req.path, ) .execute(&mut *trans) .await?; sqlx::query!( "INSERT INTO remote_addresses (addr) VALUES ($1) ON CONFLICT DO NOTHING", &req.addr ) .execute(&mut *trans) .await?; sqlx::query!( "INSERT INTO hosts (host) VALUES ($1) ON CONFLICT DO NOTHING", &req.host ) .execute(&mut *trans) .await?; sqlx::query!( "INSERT INTO user_agents (agent) VALUES ($1) ON CONFLICT DO NOTHING", &req.user_agent, ) .execute(&mut *trans) .await?; sqlx::query!( "INSERT INTO referrers (referrer) VALUES ($1) ON CONFLICT DO NOTHING", &req.referrer, ) .execute(&mut *trans) .await?; let path_id = sqlx::query!("SELECT id FROM paths WHERE path = ($1)", &req.path) .fetch_one(&mut *trans) .await? .id; let path_id = sqlx::query!( "SELECT id FROM remote_addresses WHERE addr = ($1)", &req.addr ) .fetch_one(&mut *trans) .await? .id; let path_id = sqlx::query!("SELECT id FROM hosts WHERE host = ($1)", &req.host) .fetch_one(&mut *trans) .await? .id; let path_id = sqlx::query!( "SELECT id FROM user_agents WHERE agent = ($1)", &req.user_agent ) .fetch_one(&mut *trans) .await? .id; let path_id = sqlx::query!( "SELECT id FROM referrers WHERE referrer = ($1)", &req.referrer ) .fetch_one(&mut *trans) .await? .id; sqlx::query!( "INSERT INTO hits (size, path, remote, host, user_agent, referrer, secure, time) \ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", req.size, path_id, remote_id, host_id, user_agent_id, referrer_id, req.secure, req.timestamp, ) .execute(&mut *trans) .await?; trans.commit().await?; Ok(()) }