use crate::error::Result;
use sqlx::PgConnection;
use uuid::Uuid;
#[derive(Clone, Debug, Default)]
pub struct PushTokenRepository {}
impl PushTokenRepository {
#[must_use]
pub const fn new() -> Self {
Self {}
}
#[tracing::instrument(level = "debug", skip(self, conn, token), err)]
pub async fn upsert_token(&self, conn: &mut PgConnection, device_id: Uuid, token: &str) -> Result<()> {
sqlx::query(
r#"
INSERT INTO push_tokens (device_id, token, updated_at)
VALUES ($1, $2, NOW())
ON CONFLICT (device_id) DO UPDATE
SET token = $2, updated_at = NOW()
"#,
)
.bind(device_id)
.bind(token)
.execute(conn)
.await?;
Ok(())
}
#[tracing::instrument(level = "debug", skip(self, conn), err)]
pub(crate) async fn find_tokens_for_devices(
&self,
conn: &mut PgConnection,
device_ids: &[Uuid],
) -> Result<Vec<(Uuid, String)>> {
let rows =
sqlx::query_as::<_, (Uuid, String)>("SELECT device_id, token FROM push_tokens WHERE device_id = ANY($1)")
.bind(device_ids)
.fetch_all(conn)
.await?;
Ok(rows)
}
#[tracing::instrument(level = "debug", skip(self, conn), err)]
pub async fn delete_tokens_batch(&self, conn: &mut PgConnection, tokens: &[String]) -> Result<()> {
if tokens.is_empty() {
return Ok(());
}
sqlx::query("DELETE FROM push_tokens WHERE token = ANY($1)").bind(tokens).execute(conn).await?;
Ok(())
}
}