ns_indexer/db/
model_service_protocol.rs1use ns_axum_web::erring::HTTPError;
2use ns_scylla_orm::{ColumnsMap, ToCqlVal};
3use ns_scylla_orm_macros::CqlOrm;
4
5use ns_protocol::state;
6
7use crate::db::scylladb;
8
9#[derive(Debug, Default, Clone, CqlOrm, PartialEq)]
10pub struct ServiceProtocol {
11 pub code: i64,
12 pub version: i32,
13 pub protocol: Vec<u8>,
14 pub submitter: String,
15 pub sequence: i64,
16
17 pub _fields: Vec<String>, }
19
20impl ServiceProtocol {
21 pub fn with_pk(code: i64, version: i32) -> Self {
22 Self {
23 code,
24 version,
25 ..Default::default()
26 }
27 }
28
29 pub fn from_index(value: &state::ServiceProtocol) -> anyhow::Result<Self> {
30 let protocol = state::to_bytes(&value.protocol)?;
31 Ok(Self {
32 code: value.code as i64,
33 version: value.version as i32,
34 protocol,
35 submitter: value.submitter.clone(),
36 sequence: value.sequence as i64,
37 _fields: Self::fields(),
38 })
39 }
40
41 pub fn to_index(&self) -> anyhow::Result<state::ServiceProtocol> {
42 let protocol = state::from_bytes(&self.protocol)?;
43 Ok(state::ServiceProtocol {
44 code: self.code as u64,
45 version: self.version as u16,
46 protocol,
47 submitter: self.submitter.clone(),
48 sequence: self.sequence as u64,
49 })
50 }
51
52 pub fn select_fields(select_fields: Vec<String>, with_pk: bool) -> anyhow::Result<Vec<String>> {
53 if select_fields.is_empty() {
54 return Ok(Self::fields());
55 }
56
57 let fields = Self::fields();
58 let mut select_fields = select_fields;
59 for field in &select_fields {
60 if !fields.contains(field) {
61 return Err(HTTPError::new(400, format!("Invalid field: {}", field)).into());
62 }
63 }
64
65 let field = "submitter".to_string();
66 if !select_fields.contains(&field) {
67 select_fields.push(field);
68 }
69 let field = "sequence".to_string();
70 if !select_fields.contains(&field) {
71 select_fields.push(field);
72 }
73
74 if with_pk {
75 let field = "code".to_string();
76 if !select_fields.contains(&field) {
77 select_fields.push(field);
78 }
79 let field = "version".to_string();
80 if !select_fields.contains(&field) {
81 select_fields.push(field);
82 }
83 }
84
85 Ok(select_fields)
86 }
87
88 pub async fn get_one(
89 &mut self,
90 db: &scylladb::ScyllaDB,
91 select_fields: Vec<String>,
92 ) -> anyhow::Result<()> {
93 let fields = Self::select_fields(select_fields, false)?;
94 self._fields = fields.clone();
95
96 let query = format!(
97 "SELECT {} FROM service_protocol WHERE code=? AND version=? LIMIT 1",
98 fields.join(",")
99 );
100 let params = (self.code.to_cql(), self.version.to_cql());
101 let res = db.execute(query, params).await?.single_row()?;
102
103 let mut cols = ColumnsMap::with_capacity(fields.len());
104 cols.fill(res, &fields)?;
105 self.fill(&cols);
106
107 Ok(())
108 }
109
110 pub async fn get_latest(
111 db: &scylladb::ScyllaDB,
112 code: i64,
113 select_fields: Vec<String>,
114 ) -> anyhow::Result<Self> {
115 let fields = Self::select_fields(select_fields, true)?;
116
117 let query = format!(
118 "SELECT {} FROM service_protocol WHERE code=? LIMIT 1",
119 fields.join(",")
120 );
121 let params = (code.to_cql(),);
122 let res = db.execute(query, params).await?.single_row()?;
123
124 let mut cols = ColumnsMap::with_capacity(fields.len());
125 cols.fill(res, &fields)?;
126 let mut doc = Self::default();
127 doc.fill(&cols);
128 doc._fields = fields.clone();
129
130 Ok(doc)
131 }
132}