diff options
author | Vika <vika@fireburn.ru> | 2021-12-02 15:07:49 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2021-12-02 15:07:49 +0300 |
commit | 11a57326f17b4f33d8683b9d12aa63b5f3a2d41d (patch) | |
tree | 126af0be64583c99aaecfe88c87281d19730e453 | |
parent | 99d6a56336c8c6e5a3e5fb9f132bb15157fc1525 (diff) | |
download | kittybox-11a57326f17b4f33d8683b9d12aa63b5f3a2d41d.tar.zst |
Finally finish the migration tool
It works. Launch it using the "kittybox-database-converter" command. First argument should be the old database URI, second should be the new one. It will migrate the DB for you. If you're doing this on a test machine, you can then migrate the database to production using `rsync -rl` to preserve symbolic links created by Kittybox's database backend.
-rw-r--r-- | src/bin/kittybox_database_converter.rs | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/src/bin/kittybox_database_converter.rs b/src/bin/kittybox_database_converter.rs index ff28d49..900a5c6 100644 --- a/src/bin/kittybox_database_converter.rs +++ b/src/bin/kittybox_database_converter.rs @@ -1,6 +1,5 @@ use anyhow::{anyhow, Context}; use redis::{self, AsyncCommands}; -use futures_util::StreamExt; use kittybox::database::Storage; use kittybox::database::FileStorage; use std::collections::HashMap; @@ -14,26 +13,33 @@ async fn convert_from_redis<S: Storage>(from: String, new_storage: S) -> anyhow: // Rebinding to convince the borrow checker we're not smuggling stuff outta scope let storage = &new_storage; - conn.hscan::<_, String>("posts").await?.map(|it| async move { - let json = serde_json::from_str(&it); - (it, json) - }).for_each_concurrent(8, |it| async move { - let (orig, res): (String, serde_json::Result<serde_json::Value>) = it.await; - match res { - Ok(json) => { - // XXX this assumes a trusted database that was created with Kittybox that checks for UID matching user token's prefix - let user = &(url::Url::parse(json["properties"]["uid"][0].as_str().unwrap()).unwrap().origin().ascii_serialization().clone() + "/"); - if let Err(err) = storage.clone().put_post(&json, user).await { - eprintln!("Error saving post: {}", err); - } - }, - Err(err) => { - eprintln!("Error: {} (rejected JSON follows below on stderr)", err); - eprintln!("{}", orig); - } + let mut stream = conn.hscan::<_, String>("posts").await?; + + while let Some(key) = stream.next_item().await { + let value = serde_json::from_str::<serde_json::Value>( + &stream.next_item().await + .ok_or(anyhow!("Failed to find a corresponding value for the key"))? + )?; + + println!("{}, {:?}", key, value); + + if value["see_other"].is_string() { + continue } - }).await; + let user = &( + url::Url::parse( + value["properties"]["uid"][0] + .as_str().unwrap() + ).unwrap().origin().ascii_serialization().clone() + + "/" + ); + if let Err(err) = storage.clone().put_post(&value, user).await { + eprintln!("Error saving post: {}", err); + } + + } + let mut stream: redis::AsyncIter<String> = conn.scan_match("settings_*").await?; while let Some(key) = stream.next_item().await { let mut conn = db.get_async_std_connection().await.context("Failed to connect to Redis")?; |