Skip to main content

v_common/module/
veda_backend.rs

1use crate::module::module_impl::Module;
2use crate::module::ticket::Ticket;
3use v_individual_model::onto::individual::Individual;
4use crate::search::ft_client::FTClient;
5use v_storage::{StorageId, StorageMode, VStorage, StorageResult, storage_factory::StorageProvider};
6use crate::v_api::api_client::{AuthClient, IndvOp, MStorageClient};
7use crate::v_api::common_type::ResultCode;
8use std::env;
9use url::Url;
10
11pub struct Backend {
12    pub storage: VStorage,
13    pub fts: FTClient,
14    pub mstorage_api: MStorageClient,
15    pub auth_api: AuthClient,
16}
17
18impl Default for Backend {
19    fn default() -> Self {
20        Backend::create(StorageMode::ReadOnly, false)
21    }
22}
23
24impl Backend {
25    pub fn create(storage_mode: StorageMode, use_remote_storage: bool) -> Self {
26        let args: Vec<String> = env::args().collect();
27
28        let mut ft_query_service_url = String::default();
29
30        for el in args.iter() {
31            if el.starts_with("--ft_query_service_url") {
32                let p: Vec<&str> = el.split('=').collect();
33                ft_query_service_url = p[1].to_owned();
34            }
35        }
36
37        if ft_query_service_url.is_empty() {
38            ft_query_service_url = Module::get_property("ft_query_service_url").expect("param [ft_query_service_url] not found in veda.properties");
39        }
40
41        info!("use ft_query_service_url={}", ft_query_service_url);
42
43        let storage: VStorage = if !use_remote_storage {
44            get_storage_use_prop(storage_mode)
45        } else {
46            let ro_storage_url: String = Module::get_property("ro_storage_url").expect("param [ro_storage_url] not found in veda.properties");
47            VStorage::new(StorageProvider::remote(&ro_storage_url))
48        };
49
50        let ft_client = FTClient::new(ft_query_service_url);
51
52        let param_name = "main_module_url";
53        let mstorage_api = if let Some(url) = Module::get_property(param_name) {
54            MStorageClient::new(url)
55        } else {
56            error!("not found param {} in properties file", param_name);
57            MStorageClient::new("".to_owned())
58        };
59
60        let param_name = "auth_url";
61        let auth_api = if let Some(url) = Module::get_property(param_name) {
62            AuthClient::new(url)
63        } else {
64            error!("not found param {} in properties file", param_name);
65            AuthClient::new("".to_owned())
66        };
67
68        Backend {
69            storage,
70            fts: ft_client,
71            mstorage_api,
72            auth_api,
73        }
74    }
75
76    pub fn get_sys_ticket_id(&mut self) -> Result<String, i32> {
77        Module::get_sys_ticket_id_from_db(&mut self.storage)
78    }
79
80    pub fn get_literal_of_link(&mut self, indv: &mut Individual, link: &str, field: &str, to: &mut Individual) -> Option<String> {
81        if let Some(v) = indv.get_literals(link) {
82            for el in v {
83                if self.storage.get_individual(&el, to) == StorageResult::Ok(()) {
84                    return to.get_first_literal(field);
85                }
86            }
87        }
88        None
89    }
90
91    pub fn get_literals_of_link(&mut self, indv: &mut Individual, link: &str, field: &str) -> Vec<String> {
92        let mut res = Vec::new();
93        if let Some(v) = indv.get_literals(link) {
94            for el in v {
95                let to = &mut Individual::default();
96                if self.storage.get_individual(&el, to) == StorageResult::Ok(()) {
97                    if let Some(s) = to.get_first_literal(field) {
98                        res.push(s);
99                    }
100                }
101            }
102        }
103        res
104    }
105
106    pub fn get_datetime_of_link(&mut self, indv: &mut Individual, link: &str, field: &str, to: &mut Individual) -> Option<i64> {
107        if let Some(v) = indv.get_literals(link) {
108            for el in v {
109                if self.storage.get_individual(&el, to) == StorageResult::Ok(()) {
110                    return to.get_first_datetime(field);
111                }
112            }
113        }
114        None
115    }
116
117    pub fn get_individual_h(&mut self, uri: &str) -> Option<Box<Individual>> {
118        let mut iraw = Box::<Individual>::default();
119        if self.storage.get_individual(uri, &mut iraw) != StorageResult::Ok(()) {
120            return None;
121        }
122        Some(iraw)
123    }
124
125    pub fn get_individual_s(&mut self, uri: &str) -> Option<Individual> {
126        let mut iraw = Individual::default();
127        if self.storage.get_individual(uri, &mut iraw) != StorageResult::Ok(()) {
128            return None;
129        }
130        Some(iraw)
131    }
132
133    pub fn get_individual<'a>(&mut self, uri: &str, iraw: &'a mut Individual) -> Option<&'a mut Individual> {
134        if uri.is_empty() || self.storage.get_individual(uri, iraw) != StorageResult::Ok(()) {
135            return None;
136        }
137        Some(iraw)
138    }
139
140    pub fn get_ticket_from_db(&mut self, id: &str) -> Ticket {
141        let mut dest = Ticket::default();
142        let mut indv = Individual::default();
143        if self.storage.get_individual_from_storage(StorageId::Tickets, id, &mut indv) == StorageResult::Ok(()) {
144            dest.update_from_individual(&mut indv);
145            dest.result = ResultCode::Ok;
146        }
147        dest
148    }
149}
150
151pub fn indv_apply_cmd(cmd: &IndvOp, prev_indv: &mut Individual, indv: &mut Individual) {
152    if !prev_indv.is_empty() {
153        let list_predicates = indv.get_predicates();
154
155        for predicate in list_predicates {
156            if predicate != "v-s:updateCounter" {
157                if cmd == &IndvOp::AddTo {
158                    // add value to set or ignore if exists
159                    prev_indv.apply_predicate_as_add_unique(&predicate, indv);
160                } else if cmd == &IndvOp::SetIn {
161                    // set value to predicate
162                    prev_indv.apply_predicate_as_set(&predicate, indv);
163                } else if cmd == &IndvOp::RemoveFrom {
164                    // remove predicate or value in set
165                    prev_indv.apply_predicate_as_remove(&predicate, indv);
166                } else if cmd == &IndvOp::RemovePredicates {
167                    // remove entire predicates
168                    prev_indv.remove(&predicate);
169                }
170            }
171        }
172    }
173}
174
175pub fn get_storage_use_prop(mode: StorageMode) -> VStorage {
176    get_storage_with_prop(mode, "db_connection")
177}
178
179pub fn get_storage_with_prop(mode: StorageMode, prop_name: &str) -> VStorage {
180    let mut lmdb_db_path = None;
181
182    if let Some(p) = Module::get_property::<String>(prop_name) {
183        if p.contains("tcp://") {
184            match Url::parse(&p) {
185                Ok(url) => {
186                    let host = url.host_str().unwrap_or("127.0.0.1");
187                    let port = url.port().unwrap_or(3309);
188                    let user = url.username();
189                    let pass = url.password().unwrap_or("123");
190                    return VStorage::new(StorageProvider::tarantool(format!("{}:{}", host, port), user, pass));
191                },
192                Err(e) => {
193                    error!("fail parse {}, err={}", p, e);
194                },
195            }
196        } else {
197            lmdb_db_path = Some(p);
198        }
199    }
200
201    if let Some(db_path) = lmdb_db_path {
202        return VStorage::new(StorageProvider::lmdb(&db_path, mode, None));
203    }
204
205    VStorage::none()
206}