tuwunel_admin/query/raw/
keys.rs1use futures::{FutureExt, StreamExt, TryStreamExt};
2use tokio::time::Instant;
3use tuwunel_core::{Result, utils::TryReadyExt};
4
5use super::encode;
6use crate::admin_command;
7
8#[admin_command]
9pub(super) async fn raw_keys(
10 &self,
11 map: String,
12 prefix: Option<String>,
13 limit: Option<usize>,
14 from: Option<String>,
15 backwards: bool,
16) -> Result {
17 writeln!(self, "```").boxed().await?;
18
19 let map = self.services.db.get(map.as_str())?;
20 let timer = Instant::now();
21 let stream = match from.as_ref().or(prefix.as_ref()) {
22 | Some(from) if !backwards => map.raw_keys_from(from).boxed(),
23 | Some(from) => map.rev_raw_keys_from(from).boxed(),
24 | None if !backwards => map.raw_keys().boxed(),
25 | None => map.rev_raw_keys().boxed(),
26 };
27
28 let prefix = prefix.as_ref().map(String::as_bytes);
29
30 stream
31 .ready_try_take_while(|k| {
32 Ok(prefix
33 .map(|prefix| k.starts_with(prefix))
34 .unwrap_or(true))
35 })
36 .take(limit.unwrap_or(usize::MAX))
37 .map_ok(encode)
38 .try_for_each(|str| writeln!(self, "{str}"))
39 .boxed()
40 .await?;
41
42 let query_time = timer.elapsed();
43 write!(self, "\n```\n\nQuery completed in {query_time:?}").await
44}