use super::PeerMetaEntry;
use sqlx::{Executor, Sqlite};
pub(super) async fn put<'e, E>(
executor: E,
peer_url: &str,
meta_key: &str,
meta_value: &[u8],
expires_at: Option<i64>,
) -> sqlx::Result<()>
where
E: Executor<'e, Database = Sqlite>,
{
sqlx::query(
"INSERT INTO peer_meta (peer_url, meta_key, meta_value, expires_at) VALUES (?, ?, ?, ?)",
)
.bind(peer_url)
.bind(meta_key)
.bind(meta_value)
.bind(expires_at)
.execute(executor)
.await?;
Ok(())
}
pub(super) async fn get<'e, E>(
executor: E,
peer_url: &str,
meta_key: &str,
) -> sqlx::Result<Option<Vec<u8>>>
where
E: Executor<'e, Database = Sqlite>,
{
let value: Option<Vec<u8>> = sqlx::query_scalar(
"SELECT meta_value FROM peer_meta
WHERE peer_url = ? AND meta_key = ?
AND (expires_at IS NULL OR expires_at > unixepoch())",
)
.bind(peer_url)
.bind(meta_key)
.fetch_optional(executor)
.await?;
Ok(value)
}
pub(super) async fn get_all_by_key<'e, E>(
executor: E,
meta_key: &str,
) -> sqlx::Result<Vec<(String, Vec<u8>)>>
where
E: Executor<'e, Database = Sqlite>,
{
#[derive(sqlx::FromRow)]
struct Row {
peer_url: String,
meta_value: Vec<u8>,
}
let rows: Vec<Row> = sqlx::query_as(
"SELECT peer_url, meta_value FROM peer_meta
WHERE meta_key = ?
AND (expires_at IS NULL OR expires_at > unixepoch())",
)
.bind(meta_key)
.fetch_all(executor)
.await?;
Ok(rows
.into_iter()
.map(|r| (r.peer_url, r.meta_value))
.collect())
}
pub(super) async fn get_all_by_url<'e, E>(
executor: E,
peer_url: &str,
) -> sqlx::Result<Vec<PeerMetaEntry>>
where
E: Executor<'e, Database = Sqlite>,
{
let entries: Vec<PeerMetaEntry> = sqlx::query_as(
"SELECT meta_key, meta_value, expires_at FROM peer_meta
WHERE peer_url = ?
AND (expires_at IS NULL OR expires_at > unixepoch())",
)
.bind(peer_url)
.fetch_all(executor)
.await?;
Ok(entries)
}
pub(super) async fn delete<'e, E>(executor: E, peer_url: &str, meta_key: &str) -> sqlx::Result<()>
where
E: Executor<'e, Database = Sqlite>,
{
sqlx::query("DELETE FROM peer_meta WHERE peer_url = ? AND meta_key = ?")
.bind(peer_url)
.bind(meta_key)
.execute(executor)
.await?;
Ok(())
}
pub(super) async fn prune<'e, E>(executor: E) -> sqlx::Result<u64>
where
E: Executor<'e, Database = Sqlite>,
{
let result = sqlx::query("DELETE FROM peer_meta WHERE expires_at <= unixepoch()")
.execute(executor)
.await?;
Ok(result.rows_affected())
}