From a8c1d47132d4c47863ae7dc5b6f4816d024d3de4 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 01:31:45 +0100 Subject: cron: validate expressions and allocate ids atomically --- src/database/mod.rs | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'src/database/mod.rs') diff --git a/src/database/mod.rs b/src/database/mod.rs index d15bb00..192416f 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -361,24 +361,11 @@ pub async fn add_cron_job( audio_filename: Option<&str>, message: Option<&str>, ) -> Result { - // Find the lowest unused ID to reuse freed slots - let existing: Vec = sqlx::query_scalar("SELECT id FROM cron_jobs ORDER BY id") - .fetch_all(pool) - .await?; - - let next_id = existing.iter().enumerate().find_map(|(i, &id)| { - let expected = (i as i64) + 1; - if id != expected { - Some(expected) - } else { - None - } - }).unwrap_or(existing.len() as i64 + 1); - + // Let SQLite allocate the id atomically; a SELECT-then-INSERT scheme + // races when two users create jobs at the same time. let result = sqlx::query( - "INSERT INTO cron_jobs (id, guild_id, cron_expression, type, channel_id, audio_filename, message) VALUES (?, ?, ?, ?, ?, ?, ?)", + "INSERT INTO cron_jobs (guild_id, cron_expression, type, channel_id, audio_filename, message) VALUES (?, ?, ?, ?, ?, ?)", ) - .bind(next_id) .bind(guild_id) .bind(cron_expression) .bind(r#type) -- cgit v1.2.3