Files
slavasilru-shortener/src/db.rs
2026-03-09 12:36:43 +03:00

72 lines
2.1 KiB
Rust

use std::time::{Duration, SystemTime};
use rocket::futures::lock::Mutex;
use tokio_postgres::{Client, Error, Statement};
use crate::GlobalState;
pub const STATEMENT_GET_LINK: usize = 0;
pub const STATEMENT_ADD_LINK: usize = 1;
pub const STATEMENT_ADD_TEMP_LINK: usize = 2;
pub const STATEMENT_DELETE_EXPIRED: usize = 3;
pub const N_STATEMENTS: usize = 4;
pub async fn get_link(state: &Mutex<GlobalState>, link: &str) -> Result<Option<String>, Error> {
let lock = state.lock().await;
Ok(lock
.db_client
.query_opt(&lock.statements[STATEMENT_GET_LINK], &[&link])
.await?
.map(|row| row.get(0)))
}
pub async fn add_link(state: &Mutex<GlobalState>, link: &str, url: &str) -> Result<(), Error> {
let lock = state.lock().await;
lock.db_client
.execute(&lock.statements[STATEMENT_ADD_LINK], &[&link, &url])
.await?;
Ok(())
}
pub async fn add_temporary_link(
state: &Mutex<GlobalState>,
link: &str,
url: &str,
ttl: u64,
) -> Result<(), Error> {
let time = SystemTime::now() + Duration::from_secs(ttl);
let lock = state.lock().await;
lock.db_client
.execute(
&lock.statements[STATEMENT_ADD_TEMP_LINK],
&[&link, &url, &time],
)
.await?;
Ok(())
}
pub async fn delete_expired_links(state: &Mutex<GlobalState>) -> Result<(), Error> {
let lock = state.lock().await;
lock.db_client
.execute(&lock.statements[STATEMENT_DELETE_EXPIRED], &[])
.await?;
Ok(())
}
pub async fn prepare_statements(db: &Client) -> Result<[Statement; N_STATEMENTS], Error> {
Ok([
db.prepare("SELECT url FROM links WHERE id = $1").await?,
db.prepare("INSERT INTO links (id, url) VALUES ($1, $2)")
.await?,
db.prepare("INSERT INTO links (id, url, valid_until) VALUES ($1, $2, $3)")
.await?,
db.prepare("DELETE FROM links WHERE valid_until < NOW()")
.await?,
])
}
pub async fn prepare_tables(db: &Client) -> Result<(), Error> {
db.execute("CREATE TABLE IF NOT EXISTS links (id TEXT PRIMARY KEY, url TEXT NOT NULL, valid_until TIMESTAMP NOT NULL)", &[]).await?;
Ok(())
}