Something went wrong. Try again.
Our Personal Data Server from scratch!
Something went wrong. Try again.
3.0 kB · 101 lines
Rust
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102use async_trait::async_trait;use sqlx::PgPool;use tranquil_db_traits::{Backlink, BacklinkRepository, DbError};use tranquil_types::{AtUri, Nsid};use uuid::Uuid;
use super::col;use super::column_vec;use super::user::map_sqlx_error;
pub struct PostgresBacklinkRepository { pool: PgPool,}
impl PostgresBacklinkRepository { pub fn new(pool: PgPool) -> Self { Self { pool } }}
#[async_trait]impl BacklinkRepository for PostgresBacklinkRepository { async fn get_backlink_conflicts( &self, repo_id: Uuid, collection: &Nsid, backlinks: &[Backlink], ) -> Result<Vec<AtUri>, DbError> { if backlinks.is_empty() { return Ok(Vec::new()); }
let paths: Vec<&str> = backlinks.iter().map(|b| b.path.as_str()).collect(); let link_tos: Vec<&str> = backlinks.iter().map(|b| b.link_to.as_str()).collect(); let collection_pattern = format!("%/{}/%", collection.as_str());
let results = sqlx::query_scalar!( r#" SELECT DISTINCT uri FROM backlinks WHERE repo_id = $1 AND uri LIKE $4 AND (path, link_to) IN (SELECT unnest($2::text[]), unnest($3::text[])) "#, repo_id, &paths as &[&str], &link_tos as &[&str], collection_pattern ) .fetch_all(&self.pool) .await .map_err(map_sqlx_error)?;
column_vec(results, col::BACKLINKS_URI) }
async fn add_backlinks(&self, repo_id: Uuid, backlinks: &[Backlink]) -> Result<(), DbError> { if backlinks.is_empty() { return Ok(()); }
let uris: Vec<&str> = backlinks.iter().map(|b| b.uri.as_str()).collect(); let paths: Vec<&str> = backlinks.iter().map(|b| b.path.as_str()).collect(); let link_tos: Vec<&str> = backlinks.iter().map(|b| b.link_to.as_str()).collect();
sqlx::query!( r#" INSERT INTO backlinks (uri, path, link_to, repo_id) SELECT unnest($1::text[]), unnest($2::text[]), unnest($3::text[]), $4 ON CONFLICT (uri, path) DO NOTHING "#, &uris as &[&str], &paths as &[&str], &link_tos as &[&str], repo_id ) .execute(&self.pool) .await .map_err(map_sqlx_error)?;
Ok(()) }
async fn remove_backlinks_by_uri(&self, uri: &AtUri) -> Result<(), DbError> { sqlx::query!("DELETE FROM backlinks WHERE uri = $1", uri.as_str()) .execute(&self.pool) .await .map_err(map_sqlx_error)?;
Ok(()) }
async fn remove_backlinks_by_repo(&self, repo_id: Uuid) -> Result<(), DbError> { sqlx::query!("DELETE FROM backlinks WHERE repo_id = $1", repo_id) .execute(&self.pool) .await .map_err(map_sqlx_error)?;
Ok(()) }}