fc_cli/frontier_db_cmd/
mod.rs1#![allow(clippy::result_large_err)]
20
21mod mapping_db;
22mod meta_db;
23#[cfg(test)]
24mod tests;
25pub(crate) mod utils;
26
27use std::{path::PathBuf, str::FromStr, sync::Arc};
28
29use clap::ValueEnum;
30use ethereum_types::H256;
31use serde::Deserialize;
32use sc_cli::{PruningParams, SharedParams};
34use sp_api::ProvideRuntimeApi;
35use sp_blockchain::HeaderBackend;
36use sp_runtime::traits::Block as BlockT;
37
38use self::{
39 mapping_db::{MappingDb, MappingKey, MappingValue},
40 meta_db::{MetaDb, MetaKey, MetaValue},
41};
42
43#[derive(Debug, Clone, clap::Parser)]
45pub struct FrontierDbCmd {
46 #[arg(value_enum, ignore_case = true, required = true)]
50 pub operation: Operation,
51
52 #[arg(value_enum, ignore_case = true, required = true)]
56 pub column: Column,
57
58 #[arg(short('k'), long, required = true)]
60 pub key: String,
61
62 #[arg(long)]
69 pub value: Option<PathBuf>,
70
71 #[command(flatten)]
73 pub shared_params: SharedParams,
74
75 #[allow(missing_docs)]
76 #[command(flatten)]
77 pub pruning_params: PruningParams,
78}
79
80#[derive(ValueEnum, Debug, Clone)]
81pub enum Operation {
82 Create,
83 Read,
84 Update,
85 Delete,
86}
87
88#[derive(ValueEnum, Debug, Clone)]
89pub enum Column {
90 Meta,
91 Block,
92 Transaction,
93}
94
95#[derive(Debug, Deserialize)]
96#[serde(untagged)]
97pub enum DbValue<H> {
98 Meta(MetaValue<H>),
99 Mapping(MappingValue<H>),
100}
101
102impl FrontierDbCmd {
103 pub fn run<B, C>(
104 &self,
105 client: Arc<C>,
106 backend: Arc<fc_db::kv::Backend<B, C>>,
107 ) -> sc_cli::Result<()>
108 where
109 B: BlockT,
110 C: HeaderBackend<B> + ProvideRuntimeApi<B>,
111 C::Api: fp_rpc::EthereumRuntimeRPCApi<B>,
112 {
113 match self.column {
114 Column::Meta => {
115 let meta_db = MetaDb::new(self, backend);
117 let key = MetaKey::from_str(&self.key)?;
119 let value = match utils::maybe_deserialize_value::<B>(
121 &self.operation,
122 self.value.as_ref(),
123 )? {
124 Some(DbValue::Meta(value)) => Some(value),
125 None => None,
126 _ => return Err(format!("Unexpected `{:?}` value", self.value).into()),
127 };
128 meta_db.query(&key, &value)?
130 }
131 Column::Block | Column::Transaction => {
132 let mapping_db = MappingDb::new(self, client, backend);
134 let key = MappingKey::EthBlockOrTransactionHash(
136 H256::from_str(&self.key).expect("H256 provided key"),
137 );
138 let value = match utils::maybe_deserialize_value::<B>(
140 &self.operation,
141 self.value.as_ref(),
142 )? {
143 Some(DbValue::Mapping(value)) => Some(value),
144 None => None,
145 _ => return Err(format!("Unexpected `{:?}` value", self.value).into()),
146 };
147 mapping_db.query(&self.column, &key, &value)?
149 }
150 }
151 Ok(())
152 }
153}
154
155impl sc_cli::CliConfiguration for FrontierDbCmd {
156 fn shared_params(&self) -> &SharedParams {
157 &self.shared_params
158 }
159
160 fn pruning_params(&self) -> Option<&PruningParams> {
161 Some(&self.pruning_params)
162 }
163}