Skip to content

Commit 19d8d6a

Browse files
committed
Complete edit in redb
1 parent 538ae60 commit 19d8d6a

File tree

5 files changed

+91
-27
lines changed

5 files changed

+91
-27
lines changed

README.md

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
11
# Rust - redb cli
2-
As a Cli tool for redb
2+
Command line program to operate redb, and provide a command-line interface for the entire redb operation.
33

4-
Under development
5-
# Example
4+
5+
## Requires
6+
Need vim
7+
8+
## Features
9+
- Open a redb database.
10+
- Info will show the tables and datas.
11+
- Edit the redb database.
12+
- Create and Delete a table(TODO).
13+
14+
## Example
615

716
```shell
817
example:
918

10-
$ set {filepath}
19+
DB:[] TAB:[]
20+
>> set /home/[email protected]/hdy/github/redbcli/example/stores.redb
1121
-> set database success!
12-
$ use {table}
13-
-> Use table {table}
14-
$ info tables //info tables
1522

23+
DB:[/home/[email protected]/hdy/github/redbcli/example/stores.redb] TAB:[]
24+
>> use images
25+
-> Use table images
26+
27+
DB:[/home/[email protected]/hdy/github/redbcli/example/stores.redb] TAB:[images]
28+
>> edit
29+
Save data to update the database
30+
31+
DB:[/home/[email protected]/hdy/github/redbcli/example/stores.redb] TAB:[images]
32+
>> edit
33+
No changed!
34+
35+
36+
```
37+
38+
## License
39+
This project is licensed under the MIT License. See the LICENSE file for details.
40+
41+
42+
## Contributing
43+
Contributions are welcome! Please open an issue or submit a pull request if you have any improvements or bug fixes.
1644

17-
```
45+
For more detailed information, please refer to the source code and documentation.

example/stores.redb

0 Bytes
Binary file not shown.

src/flags.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ pub enum Commands {
3434

3535
#[command(short_flag='e',about = "edit table data", long_about = None)]
3636
Edit,
37-
37+
38+
//todo create table
39+
40+
//todo delete table
3841
Exit,
3942
}
4043

@@ -57,6 +60,4 @@ pub enum InfoCommands {
5760
//show table data
5861
#[command(short_flag='t',about = "get table data", long_about = None)]
5962
Table { tablename: String },
60-
61-
6263
}

src/main.rs

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use redbcli::{
88
use redbcli::{KvInfo, TableInfo};
99
use rustyline::error::ReadlineError;
1010
use rustyline::DefaultEditor;
11+
use std::collections::HashMap;
1112
use std::io::Write;
1213
use std::path::PathBuf;
1314
#[derive(Default)]
@@ -23,13 +24,20 @@ fn main() -> Result<(), String> {
2324
if let Some(db_path) = parse_flags.path {
2425
clistatus.filepath = db_path;
2526
}
26-
let history_path = PathBuf::from("/tmp/redbcli/history");
27+
let history_path = PathBuf::from("/tmp/redbcli");
2728
if !history_path.exists() {
28-
std::fs::create_dir_all(&history_path).expect("create history failed");
29-
std::fs::OpenOptions::new().create(true).open(&history_path);
29+
std::fs::create_dir_all(&history_path).expect("create history dir failed");
3030
}
31+
let file_history = history_path.join("history.txt");
32+
//check history file
33+
{
34+
if !file_history.exists() {
35+
std::fs::File::create(&file_history).expect("create history file failed");
36+
}
37+
}
38+
3139
let mut rl = DefaultEditor::new().unwrap();
32-
if rl.load_history(&history_path).is_err() {
40+
if rl.load_history(&file_history).is_err() {
3341
println!("No previous history.");
3442
}
3543
loop {
@@ -38,7 +46,7 @@ fn main() -> Result<(), String> {
3846
clistatus.filepath, clistatus.tablename
3947
);
4048
let readline = rl.readline(&prompt);
41-
let _ = rl.save_history(&history_path);
49+
4250
match readline {
4351
Ok(line) => {
4452
let _ = rl.add_history_entry(line.as_str());
@@ -67,7 +75,7 @@ fn main() -> Result<(), String> {
6775
}
6876
}
6977
}
70-
78+
let _ = rl.save_history(&file_history);
7179
Ok(())
7280
}
7381

@@ -102,31 +110,60 @@ fn respond(line: &str, status: &mut CliStatus) -> Result<bool, String> {
102110
write_io(format!("Use table {}", tablename))?;
103111
}
104112
Commands::Edit => {
113+
if status.tablename.is_empty() {
114+
write_io("you must set table first !!".to_string())?;
115+
return Ok(false);
116+
}
105117
let mut temp_file = tempfile::NamedTempFile::new().unwrap();
106118
let result = status.dbm.common_get_all().map_err(|e| e.to_string())?;
107-
let json_data = serde_json::to_string(&result).unwrap();
119+
let json_data = serde_json::to_string_pretty(&result).unwrap();
120+
108121
temp_file.write_all(json_data.as_bytes()).unwrap();
109122

110123
let temp_path = temp_file.path().to_str().expect("Invalid path");
111124

112-
// 调用 vim 编辑器
113125
let mut child = std::process::Command::new("vim")
114126
.arg(temp_path)
127+
.arg("+syntax on")
128+
.arg("+set number")
129+
.arg("+set filetype=json")
115130
.stdin(std::process::Stdio::inherit())
116131
.stdout(std::process::Stdio::inherit())
117132
.stderr(std::process::Stdio::inherit())
118-
.spawn().unwrap();
133+
.spawn()
134+
.unwrap();
119135

120-
// 等待用户完成编辑
121-
let status = child.wait().unwrap();
136+
let vim_status = child.wait().unwrap();
122137

123-
if !status.success() {
138+
if !vim_status.success() {
124139
eprintln!("Vim exited with an error");
125140
return Ok(true);
126141
}
127142

128143
let modified_data = std::fs::read_to_string(temp_path).unwrap();
129-
println!("Modified data:\n{}", modified_data);
144+
match serde_json::from_str::<HashMap<String, String>>(&modified_data) {
145+
Ok(r_data) => {
146+
if modified_data == json_data {
147+
println!("No changed!");
148+
return Ok(false);
149+
}
150+
result.iter().for_each(|(key, _)| {
151+
let _ = status.dbm.common_remove_by_key(key.to_string());
152+
});
153+
154+
println!("Save data to update the database");
155+
r_data.iter().for_each(|(key, value)| {
156+
let _ = status
157+
.dbm
158+
.common_update_by_key(key.to_string(), value.to_string());
159+
});
160+
return Ok(false);
161+
}
162+
Err(_) => {
163+
println!("This is not a valid json str");
164+
return Ok(false);
165+
}
166+
};
130167
}
131168

132169
Commands::Info(subcmd) => {
@@ -136,7 +173,6 @@ fn respond(line: &str, status: &mut CliStatus) -> Result<bool, String> {
136173
if status.tablename.is_empty() {
137174
let result = status.dbm.gettables().map_err(|e| e.to_string())?;
138175
TableInfo { tablename: result }.print_data();
139-
// write_io(format!("data \n{:?}", result))?;
140176
return Ok(false);
141177
} else {
142178
let result = status.dbm.common_get_all().map_err(|e| e.to_string())?;
@@ -161,7 +197,6 @@ fn respond(line: &str, status: &mut CliStatus) -> Result<bool, String> {
161197
KvInfo { kvdatas: result }.print_data();
162198
return Ok(false);
163199
}
164-
165200
}
166201
}
167202
Commands::Exit => {

src/redbcontrol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::path::Path;
88
#[derive(Debug, Default)]
99
pub struct CommonDbManager {
1010
pub tablename: String,
11-
dbpath: String,
11+
pub dbpath: String,
1212
}
1313

1414
pub trait CommonDbInterface {

0 commit comments

Comments
 (0)