aboutsummaryrefslogtreecommitdiff
path: root/tool/src/migrate.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-10-24 20:04:19 +0200
committermetamuffin <metamuffin@disroot.org>2023-10-24 20:04:19 +0200
commit5ee01d06c0b067f2f07d0288c499897cd0df29f7 (patch)
tree91dd323219a2102770d40919d5e713b03f48b1e5 /tool/src/migrate.rs
parentd9b3b92e8ddd27aac39269a03a0eeb18e3a62a6a (diff)
downloadjellything-5ee01d06c0b067f2f07d0288c499897cd0df29f7.tar
jellything-5ee01d06c0b067f2f07d0288c499897cd0df29f7.tar.bz2
jellything-5ee01d06c0b067f2f07d0288c499897cd0df29f7.tar.zst
migration tool
Diffstat (limited to 'tool/src/migrate.rs')
-rw-r--r--tool/src/migrate.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/tool/src/migrate.rs b/tool/src/migrate.rs
new file mode 100644
index 0000000..7c24087
--- /dev/null
+++ b/tool/src/migrate.rs
@@ -0,0 +1,89 @@
+/*
+ This file is part of jellything (https://codeberg.org/metamuffin/jellything)
+ which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
+ Copyright (C) 2023 metamuffin <metamuffin.org>
+*/
+use crate::{Action, MigrateMode};
+use anyhow::bail;
+use indicatif::ProgressIterator;
+use jellybase::database::{typed_sled::Tree, Database};
+use log::info;
+use serde::Serialize;
+use std::{
+ fs::File,
+ io::{BufRead, BufReader, BufWriter, Write},
+ path::Path,
+};
+
+pub(crate) fn migrate(action: Action) -> anyhow::Result<()> {
+ match action {
+ Action::Migrate {
+ mode,
+ save_location,
+ database,
+ } => {
+ std::fs::create_dir_all(&save_location)?;
+ let db = Database::open(&database)?;
+
+ info!("processing 'user'");
+ process_tree(mode, &save_location.join("user"), &db.user)?;
+ info!("processing 'invite'");
+ process_tree(mode, &save_location.join("invite"), &db.invite)?;
+ info!("processing 'node'");
+ process_tree(mode, &save_location.join("node"), &db.node)?;
+ info!("done");
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+}
+
+fn process_tree<
+ K: Serialize + for<'de> serde::Deserialize<'de>,
+ V: Serialize + for<'de> serde::Deserialize<'de>,
+>(
+ mode: MigrateMode,
+ path: &Path,
+ tree: &Tree<K, V>,
+) -> anyhow::Result<()> {
+ match mode {
+ MigrateMode::Export => export_tree(path, tree),
+ MigrateMode::Import => import_tree(path, tree),
+ }
+}
+
+fn export_tree<
+ K: Serialize + for<'de> serde::Deserialize<'de>,
+ V: Serialize + for<'de> serde::Deserialize<'de>,
+>(
+ path: &Path,
+ tree: &Tree<K, V>,
+) -> anyhow::Result<()> {
+ let mut o = BufWriter::new(File::create(path)?);
+ let len = tree.len();
+ for r in tree.iter().progress_count(len.try_into().unwrap()) {
+ let (k, v) = r?;
+ serde_json::to_writer(&mut o, &(k, v))?;
+ writeln!(&mut o)?;
+ }
+ Ok(())
+}
+
+fn import_tree<
+ K: Serialize + for<'de> serde::Deserialize<'de>,
+ V: Serialize + for<'de> serde::Deserialize<'de>,
+>(
+ path: &Path,
+ tree: &Tree<K, V>,
+) -> anyhow::Result<()> {
+ if !tree.is_empty() {
+ bail!("tree not empty, `rm -rf` your db please :)")
+ }
+ let i = BufReader::new(File::open(path)?);
+ for l in i.lines() {
+ let l = l?;
+ let (k, v) = serde_json::from_str::<(K, V)>(&l)?;
+ tree.insert(&k, &v)?;
+ }
+ Ok(())
+}