60 lines
1.7 KiB
Rust
60 lines
1.7 KiB
Rust
// 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<PgPool> {
|
|
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<dyn StdError>> {
|
|
let mut trans = pool.begin().await?;
|
|
|
|
// Get the id's for deduplicated values. Insert a value if one is missing.
|
|
let path_id = sqlx::query!(
|
|
"INSERT INTO paths (path) VALUES ($1) ON CONFLICT DO NOTHING RETURNING id",
|
|
&req.path,
|
|
).fetch_one(&mut *trans).await?.id;
|
|
let remote_id = sqlx::query!(
|
|
"INSERT INTO remote_addresses (addr) VALUES ($1) ON CONFLICT DO NOTHING RETURNING id",
|
|
req.addr)
|
|
.fetch_one(&mut *trans).await?.id;
|
|
let host_id = sqlx::query!(
|
|
"INSERT INTO hosts (host) VALUES ($1) ON CONFLICT DO NOTHING RETURNING id",
|
|
&req.host)
|
|
.fetch_one(&mut *trans).await?.id;
|
|
let user_agent_id = sqlx::query!(
|
|
"INSERT INTO user_agents (agent) VALUES ($1) ON CONFLICT DO NOTHING RETURNING id",
|
|
&req.user_agent,
|
|
).fetch_one(&mut *trans).await?.id;
|
|
let referrer_id = sqlx::query!(
|
|
"INSERT INTO referrers (referrer) VALUES ($1) ON CONFLICT DO NOTHING RETURNING id",
|
|
&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(())
|
|
}
|