Skip to main content

v_storage/
tt_storage.rs

1use super::tt_wrapper::{Client, ClientConfig, IteratorType};
2use v_individual_model::onto::individual::Individual;
3use v_individual_model::onto::parser::parse_raw;
4use crate::common::{Storage, StorageId, StorageResult};
5use crate::RuntimeWrapper;
6use std::str;
7
8pub struct TTStorage {
9    rt: RuntimeWrapper,
10    client: Client,
11}
12
13const INDIVIDUALS_SPACE_ID: i32 = 512;
14const TICKETS_SPACE_ID: i32 = 513;
15const AZ_SPACE_ID: i32 = 514;
16
17impl TTStorage {
18    pub fn new(tt_uri: String, login: &str, pass: &str) -> TTStorage {
19        TTStorage {
20            rt: RuntimeWrapper::new(),
21            client: ClientConfig::new(tt_uri, login, pass).set_timeout_time_ms(1000).set_reconnect_time_ms(10000).build(),
22        }
23    }
24}
25
26impl Storage for TTStorage {
27    fn get_individual(&mut self, storage: StorageId, uri: &str, iraw: &mut Individual) -> StorageResult<()> {
28        let space = if storage == StorageId::Tickets {
29            TICKETS_SPACE_ID
30        } else if storage == StorageId::Az {
31            AZ_SPACE_ID
32        } else {
33            INDIVIDUALS_SPACE_ID
34        };
35
36        let key = (uri,);
37
38        match self.rt.block_on(self.client.select(space, 0, &key, 0, 100, IteratorType::EQ)) {
39            Ok(v) => {
40                if !v.data.is_empty() {
41                    iraw.set_raw(&v.data[5..]);
42                    if parse_raw(iraw).is_ok() {
43                        return StorageResult::Ok(());
44                    } else {
45                        return StorageResult::UnprocessableEntity;
46                    }
47                }
48                StorageResult::NotFound
49            },
50            Err(_) => StorageResult::UnprocessableEntity,
51        }
52    }
53
54    fn get_value(&mut self, storage: StorageId, key: &str) -> StorageResult<String> {
55        let space = if storage == StorageId::Tickets {
56            TICKETS_SPACE_ID
57        } else if storage == StorageId::Az {
58            AZ_SPACE_ID
59        } else {
60            INDIVIDUALS_SPACE_ID
61        };
62
63        let key_tuple = (key,);
64
65        match self.rt.block_on(self.client.select(space, 0, &key_tuple, 0, 100, IteratorType::EQ)) {
66            Ok(v) => {
67                match std::str::from_utf8(&v.data[5..]) {
68                    Ok(s) => StorageResult::Ok(s.to_string()),
69                    Err(_) => StorageResult::Error("Invalid UTF-8 data".to_string()),
70                }
71            },
72            Err(e) => {
73                error!("TTStorage: fail get [{}] from tarantool, err={:?}", key, e);
74                StorageResult::NotFound
75            },
76        }
77    }
78
79    fn get_raw_value(&mut self, storage: StorageId, key: &str) -> StorageResult<Vec<u8>> {
80        let space = if storage == StorageId::Tickets {
81            TICKETS_SPACE_ID
82        } else if storage == StorageId::Az {
83            AZ_SPACE_ID
84        } else {
85            INDIVIDUALS_SPACE_ID
86        };
87
88        let key_tuple = (key,);
89
90        match self.rt.block_on(self.client.select(space, 0, &key_tuple, 0, 100, IteratorType::EQ)) {
91            Ok(v) => StorageResult::Ok(v.data[5..].to_vec()),
92            Err(e) => {
93                error!("TTStorage: fail get raw [{}] from tarantool, err={:?}", key, e);
94                StorageResult::NotFound
95            },
96        }
97    }
98
99    fn put_value(&mut self, storage: StorageId, key: &str, val: &str) -> StorageResult<()> {
100        let space = if storage == StorageId::Tickets {
101            TICKETS_SPACE_ID
102        } else if storage == StorageId::Az {
103            AZ_SPACE_ID
104        } else {
105            INDIVIDUALS_SPACE_ID
106        };
107
108        let tuple = (key, val);
109
110        match self.rt.block_on(self.client.replace(space, &tuple)) {
111            Ok(_) => StorageResult::Ok(()),
112            Err(e) => {
113                error!("tarantool: fail replace, db [{:?}], err = {:?}", storage, e);
114                StorageResult::Error(format!("Failed to put value: {:?}", e))
115            },
116        }
117    }
118
119    fn put_raw_value(&mut self, storage: StorageId, _key: &str, val: Vec<u8>) -> StorageResult<()> {
120        let space = if storage == StorageId::Tickets {
121            TICKETS_SPACE_ID
122        } else if storage == StorageId::Az {
123            AZ_SPACE_ID
124        } else {
125            INDIVIDUALS_SPACE_ID
126        };
127
128        match self.rt.block_on(self.client.replace_raw(space, val)) {
129            Ok(_) => StorageResult::Ok(()),
130            Err(e) => {
131                error!("tarantool: fail replace raw, db [{:?}], err = {:?}", storage, e);
132                StorageResult::Error(format!("Failed to put raw value: {:?}", e))
133            },
134        }
135    }
136
137    fn remove_value(&mut self, storage: StorageId, key: &str) -> StorageResult<()> {
138        let space = if storage == StorageId::Tickets {
139            TICKETS_SPACE_ID
140        } else if storage == StorageId::Az {
141            AZ_SPACE_ID
142        } else {
143            INDIVIDUALS_SPACE_ID
144        };
145
146        let tuple = (key,);
147
148        match self.rt.block_on(self.client.delete(space, &tuple)) {
149            Ok(_) => StorageResult::Ok(()),
150            Err(e) => {
151                error!("tarantool: fail remove, db [{:?}], err = {:?}", storage, e);
152                StorageResult::NotFound
153            },
154        }
155    }
156
157    fn count(&mut self, storage: StorageId) -> StorageResult<usize> {
158        let space_name = if storage == StorageId::Tickets {
159            "TICKETS"
160        } else if storage == StorageId::Az {
161            "AZ"
162        } else {
163            "INDIVIDUALS"
164        };
165
166        match self.rt.block_on(self.client.eval(format!("return box.space.{}:len()", space_name), &(0,))) {
167            Ok(response) => {
168                match response.decode::<(u64,)>() {
169                    Ok(res) => StorageResult::Ok(res.0 as usize),
170                    Err(e) => {
171                        error!("failed to decode count response: db [{}], err = {:?}", space_name, e);
172                        StorageResult::Error("Failed to decode count response".to_string())
173                    },
174                }
175            },
176            Err(e) => {
177                error!("failed to count the number of records: db [{}], err = {:?}", space_name, e);
178                StorageResult::Error(format!("Failed to count records: {:?}", e))
179            },
180        }
181    }
182}