diff --git a/src/db/queries.rs b/src/db/queries.rs index d4a093b..70eef61 100644 --- a/src/db/queries.rs +++ b/src/db/queries.rs @@ -406,6 +406,30 @@ pub async fn upsert_relay(pool: &SqlitePool, url: &str) -> anyhow::Result<()> { Ok(()) } +/// Sync the relays table to exactly match the configured relay list. +/// Removes stale rows (old config), upserts current ones. +pub async fn sync_relays(pool: &SqlitePool, urls: &[String]) -> anyhow::Result<()> { + // Delete rows not in the current config. + // SQLite doesn't support array binding, so build the IN clause manually. + if urls.is_empty() { + sqlx::query("DELETE FROM relays").execute(pool).await?; + return Ok(()); + } + let placeholders = urls.iter().map(|_| "?").collect::>().join(","); + let sql = format!("DELETE FROM relays WHERE url NOT IN ({placeholders})"); + let mut q = sqlx::query(&sql); + for url in urls { + q = q.bind(url); + } + q.execute(pool).await?; + + // Upsert current relays. + for url in urls { + upsert_relay(pool, url).await?; + } + Ok(()) +} + pub async fn get_relay_last_event(pool: &SqlitePool, url: &str) -> anyhow::Result> { let row: Option<(Option,)> = sqlx::query_as("SELECT last_event FROM relays WHERE url = ?") diff --git a/src/main.rs b/src/main.rs index 9b36fdd..cc1f9cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,8 @@ async fn main() -> anyhow::Result<()> { let pool = db::open(&cfg.database.path).await?; info!("database ready"); + db::sync_relays(&pool, &cfg.relays).await?; + let relay_count = Arc::new(AtomicI32::new(0)); let cfg = Arc::new(cfg);