ckb_instrument/
export.rs

1use ckb_chain_iter::ChainIterator;
2use ckb_jsonrpc_types::BlockView as JsonBlock;
3use ckb_shared::shared::Shared;
4#[cfg(feature = "progress_bar")]
5use indicatif::{ProgressBar, ProgressStyle};
6use std::error::Error;
7use std::fs;
8use std::io;
9use std::io::Write;
10use std::path::PathBuf;
11
12/// Export block from database to specify file.
13pub struct Export {
14    /// export target path
15    pub target: PathBuf,
16    /// CKB shared data.
17    pub shared: Shared,
18}
19
20impl Export {
21    /// Creates the export job.
22    pub fn new(shared: Shared, target: PathBuf) -> Self {
23        Export { shared, target }
24    }
25
26    /// export file name
27    fn file_name(&self) -> String {
28        format!("{}.{}", self.shared.consensus().id, "json")
29    }
30
31    /// Executes the export job.
32    pub fn execute(self) -> Result<(), Box<dyn Error>> {
33        fs::create_dir_all(&self.target)?;
34        self.write_to_json()
35    }
36
37    #[cfg(not(feature = "progress_bar"))]
38    pub fn write_to_json(self) -> Result<(), Box<dyn Error>> {
39        let f = fs::OpenOptions::new()
40            .create_new(true)
41            .read(true)
42            .write(true)
43            .open(self.target.join(self.file_name()))?;
44        let mut writer = io::BufWriter::new(f);
45        let snapshot = self.shared.snapshot();
46
47        for block in ChainIterator::new(snapshot.as_ref()) {
48            let block: JsonBlock = block.into();
49            let encoded = serde_json::to_vec(&block)?;
50            writer.write_all(&encoded)?;
51            writer.write_all(b"\n")?;
52        }
53        Ok(())
54    }
55
56    /// Export the chain into JSON.
57    #[cfg(feature = "progress_bar")]
58    pub fn write_to_json(self) -> Result<(), Box<dyn Error>> {
59        let f = fs::OpenOptions::new()
60            .create_new(true)
61            .read(true)
62            .write(true)
63            .open(self.target.join(self.file_name()))?;
64
65        let mut writer = io::BufWriter::new(f);
66        let snapshot = self.shared.snapshot();
67        let blocks_iter = ChainIterator::new(snapshot.as_ref());
68        let progress_bar = ProgressBar::new(blocks_iter.len());
69        progress_bar.set_style(
70            ProgressStyle::default_bar()
71                .template("[{elapsed_precise}] {bar:50.cyan/blue} {pos:>6}/{len:6} {msg}")
72                .expect("Failed to set progress bar template")
73                .progress_chars("##-"),
74        );
75        for block in blocks_iter {
76            let block: JsonBlock = block.into();
77            let encoded = serde_json::to_vec(&block)?;
78            writer.write_all(&encoded)?;
79            writer.write_all(b"\n")?;
80            progress_bar.inc(1);
81        }
82        progress_bar.finish_with_message("done!");
83        Ok(())
84    }
85}