diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2022-08-12 19:33:11 -0700 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2022-08-12 19:33:11 -0700 | 
| commit | cdb5f03d89e6b2f96d7f7b28d8c3161793c85382 (patch) | |
| tree | 8fbea29de26ffe6532afab1fbc2933f32cff930c /rust/src | |
| parent | 8a1c8792a592b0eba532846b399f08841437093b (diff) | |
| download | fatcat-cdb5f03d89e6b2f96d7f7b28d8c3161793c85382.tar.gz fatcat-cdb5f03d89e6b2f96d7f7b28d8c3161793c85382.zip  | |
rust: new fatcat-doctor fixup tool, with changelog gap filler
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/bin/fatcat-doctor.rs | 97 | 
1 files changed, 97 insertions, 0 deletions
diff --git a/rust/src/bin/fatcat-doctor.rs b/rust/src/bin/fatcat-doctor.rs new file mode 100644 index 00000000..6e869634 --- /dev/null +++ b/rust/src/bin/fatcat-doctor.rs @@ -0,0 +1,97 @@ +//! Database cleanup tool + +use clap::{value_t_or_exit, App, SubCommand}; + +use fatcat::database_models::*; +use fatcat::database_schema::*; +use fatcat::errors::Result; +use fatcat::identifiers::FatcatId; +use fatcat::server; +use fatcat::server::DbConn; +use std::process; +use std::str::FromStr; + +use diesel; +use diesel::prelude::*; + +fn backfill_changelog_gap(conn: &DbConn, last_good: i64, max_index: i64) -> Result<()> { +    // sanity check arguments against database +    assert!(last_good > 0); +    assert!(max_index > 0); +    assert!(last_good < max_index); +    let highest_row: ChangelogRow = changelog::table.order(changelog::id.desc()).first(conn)?; +    assert!(highest_row.id >= max_index); + +    // default values +    // 'root' editor_id is aaaaaaaaaaaabkvkaaaaaaaaae +    // 'admin' editor_id is aaaaaaaaaaaabkvkaaaaaaaaai +    let editor_id = FatcatId::from_str("aaaaaaaaaaaabkvkaaaaaaaaai").unwrap(); +    let description = "Backfill of missing changelog entries due to database id gap"; + +    // fetch the last entry before the gap, to re-use the timestamp +    let existing_row: ChangelogRow = changelog::table.find(last_good).first(conn)?; + +    for index in last_good + 1..max_index + 1 { +        // ensure this index is actually a gap +        let count: i64 = changelog::table +            .filter(changelog::id.eq(index)) +            .count() +            .get_result(conn)?; +        if count != 0 { +            println!("Found existing changelog: {}", index); +            return Ok(()); +        } + +        // create dummy empty editgroup, then add a changelog entry +        let eg_row: EditgroupRow = diesel::insert_into(editgroup::table) +            .values(( +                editgroup::editor_id.eq(editor_id.to_uuid()), +                editgroup::created.eq(existing_row.timestamp), +                editgroup::is_accepted.eq(true), +                editgroup::description.eq(Some(description)), +            )) +            .get_result(conn)?; +        let _entry_row: ChangelogRow = diesel::insert_into(changelog::table) +            .values(( +                changelog::id.eq(index), +                changelog::editgroup_id.eq(eg_row.id), +                changelog::timestamp.eq(existing_row.timestamp), +            )) +            .get_result(conn)?; +        println!("Inserted changelog: {}", index); +    } +    Ok(()) +} + +fn main() -> Result<()> { +    let m = App::new("fatcat-doctor") +        .version(env!("CARGO_PKG_VERSION")) +        .author("Bryan Newbold <bnewbold@archive.org>") +        .about("Database cleanup / fixup tool") +        .subcommand( +            SubCommand::with_name("backfill-changelog-gap") +                .about("Inserts dummy changelog entries and editgroups for gap") +                .args_from_usage( +                    "<start> 'changelog index of entry just before gap' +                    <end> 'highest changelog index to backfill'", +                ), +        ) +        .get_matches(); + +    let db_conn = server::database_worker_pool()? +        .get() +        .expect("database pool"); +    match m.subcommand() { +        ("backfill-changelog-gap", Some(subm)) => { +            let last_good: i64 = value_t_or_exit!(subm.value_of("start"), i64); +            let max_index: i64 = value_t_or_exit!(subm.value_of("end"), i64); +            backfill_changelog_gap(&db_conn, last_good, max_index)?; +        } +        _ => { +            println!("Missing or unimplemented command!"); +            println!("{}", m.usage()); +            process::exit(-1); +        } +    } +    Ok(()) +}  | 
