From 7d99897b0e7aedff0c2d1f950e4436b26a952ad4 Mon Sep 17 00:00:00 2001 From: Bulat Kurbanov Date: Sat, 25 Oct 2025 21:37:52 +0200 Subject: [PATCH] Use ON CONFLICT upsert for genres Replace the previous IF EXISTS/UPDATE/INSERT logic in the update_genre PL/pgSQL function with a single INSERT ... ON CONFLICT DO UPDATE to perform an atomic upsert and avoid races. Reformat the client.execute call for readability. --- src/types.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/types.rs b/src/types.rs index 3009515..789ae21 100644 --- a/src/types.rs +++ b/src/types.rs @@ -828,25 +828,28 @@ impl FromVecExpression for Genre { #[async_trait] impl Update for Genre { async fn before_update(client: &Client) -> Result<(), Box> { - match client.execute( - " + match client + .execute( + " CREATE OR REPLACE FUNCTION update_genre( source_ smallint, remote_id_ int, code_ varchar, description_ varchar, meta_ varchar ) RETURNS void AS $$ BEGIN - IF EXISTS (SELECT * FROM genres WHERE source = source_ AND remote_id = remote_id_) THEN - UPDATE genres SET code = code_, description = description_, meta = meta_ - WHERE source = source_ AND remote_id = remote_id_; - RETURN; - END IF; INSERT INTO genres (source, remote_id, code, description, meta) - VALUES (source_, remote_id_, code_, description_, meta_); + VALUES (source_, remote_id_, code_, description_, meta_) + ON CONFLICT (source, remote_id) DO UPDATE SET + code = EXCLUDED.code, + description = EXCLUDED.description, + meta = EXCLUDED.meta; END; $$ LANGUAGE plpgsql; - " - , &[]).await { - Ok(_) => Ok(()), - Err(err) => Err(Box::new(err)), + ", + &[], + ) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(Box::new(err)), } }