102 lines
2.2 KiB
Rust
102 lines
2.2 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.
|
|
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(())
|
|
}
|