Something went wrong. Try again.
A lexicon-driven AppView for ATProto.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114use crate::db::{DatabaseBackend, adapt_sql};use serde_json::Value;use std::collections::HashSet;
/// Recursively walk a JSON value and collect all string values starting with "at://".pub fn extract_at_uris(value: &Value) -> HashSet<String> { let mut uris = HashSet::new(); collect_at_uris(value, &mut uris); uris}
fn collect_at_uris(value: &Value, uris: &mut HashSet<String>) { match value { Value::String(s) if s.starts_with("at://") => { uris.insert(s.clone()); } Value::Array(arr) => { for item in arr { collect_at_uris(item, uris); } } Value::Object(obj) => { for v in obj.values() { collect_at_uris(v, uris); } } _ => {} }}
/// Update record_refs for a given source record./// Deletes old refs and inserts new ones.pub async fn sync_refs( db: &sqlx::AnyPool, source_uri: &str, collection: &str, record: &Value, backend: DatabaseBackend,) -> Result<(), sqlx::Error> { let uris = extract_at_uris(record);
// Delete existing refs for this source let delete_sql = adapt_sql("DELETE FROM record_refs WHERE source_uri = ?", backend); sqlx::query(&delete_sql) .bind(source_uri) .execute(db) .await?;
// Insert new refs let insert_sql = adapt_sql( "INSERT INTO record_refs (source_uri, target_uri, collection) VALUES (?, ?, ?) ON CONFLICT DO NOTHING", backend, ); for target_uri in &uris { sqlx::query(&insert_sql) .bind(source_uri) .bind(target_uri) .bind(collection) .execute(db) .await?; }
Ok(())}
#[cfg(test)]mod tests { use super::*; use serde_json::json;
#[test] fn extracts_top_level_uri() { let val = json!({"subject": "at://did:plc:abc/com.example/123"}); let uris = extract_at_uris(&val); assert_eq!(uris.len(), 1); assert!(uris.contains("at://did:plc:abc/com.example/123")); }
#[test] fn extracts_nested_uri() { let val = json!({"outer": {"inner": "at://did:plc:abc/col/rkey"}}); let uris = extract_at_uris(&val); assert_eq!(uris.len(), 1); assert!(uris.contains("at://did:plc:abc/col/rkey")); }
#[test] fn extracts_uris_from_arrays() { let val = json!({"refs": ["at://did:plc:a/col/1", "at://did:plc:b/col/2"]}); let uris = extract_at_uris(&val); assert_eq!(uris.len(), 2); }
#[test] fn ignores_non_at_strings() { let val = json!({"url": "https://example.com", "name": "test"}); let uris = extract_at_uris(&val); assert!(uris.is_empty()); }
#[test] fn empty_object_returns_empty() { let uris = extract_at_uris(&json!({})); assert!(uris.is_empty()); }
#[test] fn deduplicates_repeated_uris() { let val = json!({"a": "at://did:plc:x/c/1", "b": "at://did:plc:x/c/1"}); let uris = extract_at_uris(&val); assert_eq!(uris.len(), 1); }}