add ll and lu commands to show table sizes
This commit is contained in:
parent
da95f014a2
commit
927a369036
4 changed files with 72 additions and 22 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -195,6 +195,12 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "humansize"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -425,6 +431,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"hexdump",
|
"hexdump",
|
||||||
|
"humansize",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
"sled",
|
"sled",
|
||||||
"structopt",
|
"structopt",
|
||||||
|
|
|
@ -14,3 +14,4 @@ structopt = { version = "0.3", default-features = false }
|
||||||
hexdump = "0.1"
|
hexdump = "0.1"
|
||||||
utf-8 = "0.7"
|
utf-8 = "0.7"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
humansize = "1.1"
|
||||||
|
|
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
hard_tabs = true
|
85
src/main.rs
85
src/main.rs
|
@ -1,8 +1,10 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
use humansize::{file_size_opts, FileSize};
|
||||||
|
|
||||||
use rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
use rustyline::Editor;
|
use rustyline::Editor;
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ use sled::IVec;
|
||||||
#[structopt(name = "sledcli")]
|
#[structopt(name = "sledcli")]
|
||||||
struct Opt {
|
struct Opt {
|
||||||
/// Path to Sled database
|
/// Path to Sled database
|
||||||
#[structopt(name="path")]
|
#[structopt(name = "path")]
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,38 +47,45 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut readline = Editor::<()>::new();
|
let mut readline = Editor::<()>::new();
|
||||||
loop {
|
loop {
|
||||||
let lineread = readline.readline(&format!("{}> ", try_string(&state.tree.name())));
|
let prefix = match state.displaymode {
|
||||||
match lineread {
|
DisplayMode::HexDump => "hex",
|
||||||
Ok(line) => {
|
DisplayMode::TryString => "str",
|
||||||
readline.add_history_entry(line.as_str());
|
DisplayMode::Mixed => "mix",
|
||||||
|
};
|
||||||
|
let prompt = format!("[{}] {}> ", prefix, try_string(&state.tree.name()));
|
||||||
|
let lineread = readline.readline(&prompt);
|
||||||
|
match lineread {
|
||||||
|
Ok(line) => {
|
||||||
|
readline.add_history_entry(line.as_str());
|
||||||
if let Err(e) = do_command(&line, &mut state) {
|
if let Err(e) = do_command(&line, &mut state) {
|
||||||
println!("Error: {}", e);
|
println!("Error: {}", e);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(ReadlineError::Interrupted) => {
|
Err(ReadlineError::Interrupted) => {
|
||||||
println!("^C");
|
println!("^C");
|
||||||
continue;
|
continue;
|
||||||
},
|
}
|
||||||
Err(ReadlineError::Eof) => {
|
Err(ReadlineError::Eof) => break,
|
||||||
break
|
Err(err) => {
|
||||||
},
|
println!("Readline error: {:?}", err);
|
||||||
Err(err) => {
|
break;
|
||||||
println!("Readline error: {:?}", err);
|
}
|
||||||
break
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_string(input: &sled::IVec) -> String {
|
fn try_string(input: &sled::IVec) -> String {
|
||||||
let mut string = String::new();
|
let mut string = String::new();
|
||||||
utf8::LossyDecoder::new(|s| string.push_str(s)).feed(input);
|
utf8::LossyDecoder::new(|s| string.push_str(s)).feed(input);
|
||||||
string
|
string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_command(line: &str, state: &mut State) -> Result<()> {
|
fn do_command(line: &str, state: &mut State) -> Result<()> {
|
||||||
let parts = line.split(' ').filter(|part| part.len() > 0).collect::<Vec<_>>();
|
let parts = line
|
||||||
|
.split(' ')
|
||||||
|
.filter(|part| part.len() > 0)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
if parts.is_empty() {
|
if parts.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -89,8 +98,40 @@ fn do_command(line: &str, state: &mut State) -> Result<()> {
|
||||||
println!("{}", try_string(&name));
|
println!("{}", try_string(&name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
["ll"] => {
|
||||||
|
let mut names = state.db.tree_names();
|
||||||
|
names.sort();
|
||||||
|
for name in names {
|
||||||
|
let nent = state.db.open_tree(&name)?.len();
|
||||||
|
println!("{:8} {}", nent, try_string(&name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
["lu"] => {
|
||||||
|
let mut names = state.db.tree_names();
|
||||||
|
names.sort();
|
||||||
|
for name in names {
|
||||||
|
let tree = state.db.open_tree(&name)?;
|
||||||
|
let nent = tree.len();
|
||||||
|
let mut size = 0;
|
||||||
|
for ent in tree.iter() {
|
||||||
|
let (k, v) = ent?;
|
||||||
|
size += k.len() + v.len();
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"{:8} {:>12} {}",
|
||||||
|
nent,
|
||||||
|
size.file_size(file_size_opts::CONVENTIONAL).unwrap(),
|
||||||
|
try_string(&name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
["cd", treename] => {
|
["cd", treename] => {
|
||||||
if state.db.tree_names().iter().any(|t| t == treename.as_bytes()) {
|
if state
|
||||||
|
.db
|
||||||
|
.tree_names()
|
||||||
|
.iter()
|
||||||
|
.any(|t| t == treename.as_bytes())
|
||||||
|
{
|
||||||
state.tree = state.db.open_tree(treename.as_bytes())?;
|
state.tree = state.db.open_tree(treename.as_bytes())?;
|
||||||
} else {
|
} else {
|
||||||
println!("Tree {} does not exist", treename);
|
println!("Tree {} does not exist", treename);
|
||||||
|
|
Loading…
Reference in a new issue