// Dump a redb table in text form // Usage: dump-table // Tables: key_to_uuid, uuid_offsets, nodes_by_provenance, nodes_by_type, rels use consciousness::store::{ memory_dir, KEY_TO_UUID, UUID_OFFSETS, NODES_BY_PROVENANCE, NODES_BY_TYPE, RELS, unpack_node_meta, unpack_provenance_value, unpack_rel, }; use redb::{Database, ReadableDatabase, ReadableTable, ReadableMultimapTable}; fn format_uuid(uuid: &[u8; 16]) -> String { format!("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]) } fn main() { let args: Vec = std::env::args().collect(); if args.len() != 2 { eprintln!("usage: dump-table "); eprintln!("tables: key_to_uuid, uuid_offsets, nodes_by_provenance, nodes_by_type, rels"); std::process::exit(1); } let table_name = &args[1]; let db_path = memory_dir().join("index.redb"); let db = Database::open(&db_path).expect("open db"); let txn = db.begin_read().expect("begin read"); match table_name.as_str() { "key_to_uuid" => { let table = txn.open_table(KEY_TO_UUID).expect("open"); for entry in table.iter().expect("iter") { let (key, data) = entry.expect("entry"); let (uuid, node_type, ts, deleted, weight) = unpack_node_meta(data.value()); println!("{}\t{}\ttype={}\tts={}\tdel={}\tw={:.3}", key.value(), format_uuid(&uuid), node_type, ts, deleted, weight); } } "uuid_offsets" => { // Key: [uuid:16][offset:8 BE], Value: () let table = txn.open_table(UUID_OFFSETS).expect("open"); for entry in table.iter().expect("iter") { let (key_bytes, _) = entry.expect("entry"); let key = key_bytes.value(); if key.len() >= 24 { let mut uuid = [0u8; 16]; uuid.copy_from_slice(&key[0..16]); let offset = u64::from_be_bytes([ key[16], key[17], key[18], key[19], key[20], key[21], key[22], key[23], ]); println!("{}\t{}", format_uuid(&uuid), offset); } } } "nodes_by_provenance" => { let table = txn.open_multimap_table(NODES_BY_PROVENANCE).expect("open"); for entry in table.iter().expect("iter") { let (prov, values) = entry.expect("entry"); for val in values { let (ts, uuid) = unpack_provenance_value(val.expect("val").value()); println!("{}\t{}\t{}", prov.value(), ts, format_uuid(&uuid)); } } } "nodes_by_type" => { // Key: [type:1][neg_timestamp:8], Value: uuid let table = txn.open_table(NODES_BY_TYPE).expect("open"); for entry in table.iter().expect("iter") { let (key_bytes, uuid_bytes) = entry.expect("entry"); let key = key_bytes.value(); let node_type = key[0]; let neg_ts = i64::from_be_bytes([key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8]]); let ts = !neg_ts; let mut uuid = [0u8; 16]; uuid.copy_from_slice(uuid_bytes.value()); println!("type={}\tts={}\t{}", node_type, ts, format_uuid(&uuid)); } } "rels" => { let table = txn.open_multimap_table(RELS).expect("open"); for entry in table.iter().expect("iter") { let (uuid_bytes, values) = entry.expect("entry"); let uuid = uuid_bytes.value(); let uuid_str = if uuid.len() >= 16 { let mut arr = [0u8; 16]; arr.copy_from_slice(&uuid[..16]); format_uuid(&arr) } else { format!("{:02x?}", uuid) }; for val in values { let (other, strength, rel_type, is_out) = unpack_rel(val.expect("val").value()); println!("{}\t{}\tstr={:.3}\ttype={}\tout={}", uuid_str, format_uuid(&other), strength, rel_type, is_out); } } } _ => { eprintln!("unknown table: {}", table_name); std::process::exit(1); } } }