mithril_client_cli/commands/cardano_db/
list.rs

1use clap::Parser;
2use cli_table::{Cell, Table, format::Justify, print_stdout};
3
4use mithril_client::common::EpochSpecifier;
5use mithril_client::{Client, MithrilResult};
6
7use crate::{
8    CommandContext,
9    commands::{
10        cardano_db::{
11            CardanoDbCommandsBackend, warn_deprecated_v1_backend,
12            warn_unused_parameter_with_v1_backend,
13        },
14        client_builder_with_fallback_genesis_key,
15    },
16    utils::CardanoDbUtils,
17};
18
19/// Clap command to list existing Cardano dbs
20#[derive(Parser, Debug, Clone)]
21pub struct CardanoDbListCommand {
22    ///Backend to use, either: `v1` (default, full database restoration only) or `v2` (full or partial database restoration)
23    #[arg(short, long, value_enum, default_value_t)]
24    backend: CardanoDbCommandsBackend,
25
26    /// [backend `v2` only] Epoch of the Cardano db snapshots to list, or `latest` for the latest artifact, or `latest-X` for the artifact of the latest epoch minus X.
27    #[clap(long)]
28    epoch: Option<String>,
29}
30
31impl CardanoDbListCommand {
32    /// Main command execution
33    pub async fn execute(&self, context: CommandContext) -> MithrilResult<()> {
34        let client = client_builder_with_fallback_genesis_key(context.config_parameters())?
35            .with_logger(context.logger().clone())
36            .build()?;
37
38        match self.backend {
39            CardanoDbCommandsBackend::V1 => self.print_v1(client, context).await?,
40            CardanoDbCommandsBackend::V2 => self.print_v2(client, context).await?,
41        }
42
43        Ok(())
44    }
45
46    #[allow(deprecated)]
47    async fn print_v1(&self, client: Client, context: CommandContext) -> MithrilResult<()> {
48        warn_deprecated_v1_backend(&context);
49        if self.epoch.is_some() {
50            warn_unused_parameter_with_v1_backend(&context, ["--epoch"]);
51        }
52
53        let items = client.cardano_database().list().await?;
54
55        if context.is_json_output_enabled() {
56            println!("{}", serde_json::to_string(&items)?);
57        } else {
58            let items = items
59                .into_iter()
60                .map(|item| {
61                    vec![
62                        format!("{}", item.beacon.epoch).cell(),
63                        format!("{}", item.beacon.immutable_file_number).cell(),
64                        item.network.cell(),
65                        item.digest.cell(),
66                        CardanoDbUtils::format_bytes_to_gigabytes(item.size).cell(),
67                        format!("{}", item.locations.len()).cell(),
68                        item.created_at.to_string().cell(),
69                    ]
70                })
71                .collect::<Vec<_>>()
72                .table()
73                .title(vec![
74                    "Epoch".cell(),
75                    "Immutable".cell(),
76                    "Network".cell(),
77                    "Digest".cell(),
78                    "Size".cell().justify(Justify::Right),
79                    "Locations".cell().justify(Justify::Right),
80                    "Created".cell().justify(Justify::Right),
81                ]);
82            print_stdout(items)?;
83        }
84        Ok(())
85    }
86
87    async fn print_v2(&self, client: Client, context: CommandContext) -> MithrilResult<()> {
88        let cdb_v2_client = client.cardano_database_v2();
89        let items = match &self.epoch {
90            None => cdb_v2_client.list().await?,
91            Some(epoch_str) => match EpochSpecifier::parse(epoch_str)? {
92                EpochSpecifier::Number(epoch) => cdb_v2_client.list_by_epoch(epoch).await?,
93                EpochSpecifier::Latest => cdb_v2_client.list_for_latest_epoch().await?,
94                EpochSpecifier::LatestMinusOffset(offset) => {
95                    cdb_v2_client.list_for_latest_epoch_with_offset(offset).await?
96                }
97            },
98        };
99
100        if context.is_json_output_enabled() {
101            println!("{}", serde_json::to_string(&items)?);
102        } else {
103            let items = items
104                .into_iter()
105                .map(|item| {
106                    vec![
107                        format!("{}", item.beacon.epoch).cell(),
108                        format!("{}", item.beacon.immutable_file_number).cell(),
109                        item.hash.cell(),
110                        item.merkle_root.cell(),
111                        CardanoDbUtils::format_bytes_to_gigabytes(item.total_db_size_uncompressed)
112                            .cell(),
113                        item.cardano_node_version.cell(),
114                        item.created_at.to_string().cell(),
115                    ]
116                })
117                .collect::<Vec<_>>()
118                .table()
119                .title(vec![
120                    "Epoch".cell(),
121                    "Immutable".cell(),
122                    "Hash".cell(),
123                    "Merkle root".cell(),
124                    "Database size".cell().justify(Justify::Right),
125                    "Cardano node".cell(),
126                    "Created".cell().justify(Justify::Right),
127                ]);
128            print_stdout(items)?;
129        }
130
131        Ok(())
132    }
133}