diff options
author | Vika <vika@fireburn.ru> | 2024-08-28 15:01:57 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2024-08-28 15:04:17 +0300 |
commit | 4f1fe5404c954c85f3bc2379c7ae130b57ea5e73 (patch) | |
tree | 9b36f884ce23849ac9fd1ebd03d1e394d05b976c /src/database/postgres | |
parent | e03ff3151878851af954aa2e9a17e7578873bbae (diff) | |
download | kittybox-4f1fe5404c954c85f3bc2379c7ae130b57ea5e73.tar.zst |
Introduce `Storage::update_with`
This function takes a closure that modifies the post. This could be useful in maintenance utilities that scan and fixup posts. For now this isn't used anywhere within Kittybox, but once all backends implement this correctly, this could replace `Storage::update_post` calls. For supporting backends, `Storage::update_post` is implemented in terms of `Storage::update_with`.
Diffstat (limited to 'src/database/postgres')
-rw-r--r-- | src/database/postgres/mod.rs | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/database/postgres/mod.rs b/src/database/postgres/mod.rs index 27ec51c..b705eed 100644 --- a/src/database/postgres/mod.rs +++ b/src/database/postgres/mod.rs @@ -189,11 +189,13 @@ WHERE txn.commit().await.map_err(Into::into) } - #[tracing::instrument(skip(self))] - async fn update_post(&self, url: &str, update: MicropubUpdate) -> Result<()> { + #[tracing::instrument(skip(self), fields(f = std::any::type_name::<F>()))] + async fn update_with<F: FnOnce(&mut serde_json::Value) + Send>( + &self, url: &str, f: F + ) -> Result<(serde_json::Value, serde_json::Value)> { tracing::debug!("Updating post {}", url); let mut txn = self.db.begin().await?; - let (uid, mut post) = sqlx::query_as::<_, (String, serde_json::Value)>("SELECT uid, mf2 FROM kittybox.mf2_json WHERE uid = $1 OR mf2['properties']['url'] ? $1 FOR UPDATE") + let (uid, old_post) = sqlx::query_as::<_, (String, serde_json::Value)>("SELECT uid, mf2 FROM kittybox.mf2_json WHERE uid = $1 OR mf2['properties']['url'] ? $1 FOR UPDATE") .bind(url) .fetch_optional(&mut *txn) .await? @@ -202,15 +204,22 @@ WHERE "The specified post wasn't found in the database." ))?; - update.apply(&mut post); + let new_post = { + let mut post = old_post.clone(); + tokio::task::block_in_place(|| f(&mut post)); + + post + }; sqlx::query("UPDATE kittybox.mf2_json SET mf2 = $2 WHERE uid = $1") .bind(uid) - .bind(post) + .bind(&new_post) .execute(&mut *txn) .await?; - txn.commit().await.map_err(Into::into) + txn.commit().await?; + + Ok((old_post, new_post)) } #[tracing::instrument(skip(self))] |