Skip to main content

sierradb_server/request/
esver.rs

1use combine::{Parser, optional};
2use redis_protocol::resp3::types::BytesFrame;
3use sierradb::StreamId;
4use sierradb::id::{NAMESPACE_PARTITION_KEY, uuid_to_partition_hash};
5use sierradb_cluster::read::GetStreamVersion;
6use uuid::Uuid;
7
8use crate::error::MapRedisError;
9use crate::parser::{FrameStream, keyword, partition_key, stream_id};
10use crate::request::{HandleRequest, number};
11use crate::server::Conn;
12
13/// Get the current version number for a stream.
14///
15/// # Syntax
16/// ```text
17/// ESVER <stream_id> [PARTITION_KEY <partition_key>]
18/// ```
19///
20/// # Parameters
21/// - `stream_id`: Stream identifier to get version for
22/// - `partition_key` (optional): UUID to check specific partition
23///
24/// # Examples
25/// ```text
26/// ESVER my-stream
27/// ESVER my-stream PARTITION_KEY 550e8400-e29b-41d4-a716-446655440000
28/// ```
29pub struct ESVer {
30    pub stream_id: StreamId,
31    pub partition_key: Option<Uuid>,
32}
33
34impl ESVer {
35    pub fn parser<'a>() -> impl Parser<FrameStream<'a>, Output = ESVer> + 'a {
36        (
37            stream_id(),
38            optional(keyword("PARTITION_KEY").with(partition_key())),
39        )
40            .map(|(stream_id, partition_key)| ESVer {
41                stream_id,
42                partition_key,
43            })
44    }
45}
46
47impl HandleRequest for ESVer {
48    type Error = String;
49    type Ok = ESVerResp;
50
51    async fn handle_request(self, conn: &mut Conn) -> Result<Option<Self::Ok>, Self::Error> {
52        let partition_key = self
53            .partition_key
54            .unwrap_or_else(|| Uuid::new_v5(&NAMESPACE_PARTITION_KEY, self.stream_id.as_bytes()));
55        let partition_id = uuid_to_partition_hash(partition_key) % conn.num_partitions;
56
57        let version = conn
58            .cluster_ref
59            .ask(GetStreamVersion {
60                partition_id,
61                stream_id: self.stream_id,
62            })
63            .await
64            .map_redis_err()?;
65
66        Ok(Some(ESVerResp { version }))
67    }
68}
69
70pub struct ESVerResp {
71    version: Option<u64>,
72}
73
74impl From<ESVerResp> for BytesFrame {
75    fn from(resp: ESVerResp) -> Self {
76        match resp.version {
77            Some(n) => number(n as i64),
78            None => BytesFrame::Null,
79        }
80    }
81}