db/repo/
vertex_property.rs1use std::collections::HashMap;
2
3use crate::interface::KeyValuePair;
4use crate::storage::Transaction;
5use crate::util::{
6 build_byte_map, build_bytes, build_sized, build_usize_from_bytes, concat_bytes, Component,
7};
8use crate::{Error, SimpleTransaction};
9use solomon_gremlin::structure::VertexPropertyMap;
10use solomon_gremlin::{GValue, VertexProperty, GID};
11
12impl_repository!(VertexPropertyRepository(VertexProperty));
13
14fn build_vertex_property_value(value: &GValue) -> Vec<u8> {
15 build_bytes(&[Component::GValueType(value), Component::GValue(value)]).unwrap()
17}
18
19fn build_vertex_property_key(vertex_id: &GID, id: &GID, label: &GValue) -> Vec<u8> {
20 concat_bytes(vec![
21 build_sized(Component::Gid(vertex_id)),
22 build_sized(Component::GValue(label)),
23 build_sized(Component::Gid(id)),
24 ])
25}
26
27impl<'a> VertexPropertyRepository<'a> {
28 pub async fn property(
34 &self,
35 tx: &mut Transaction,
36 vertex_id: &GID,
37 id: &GID,
38 label: &GValue,
39 value: &GValue,
40 ) -> Result<VertexProperty, Error> {
41 let cf = self.cf();
42 let key = build_vertex_property_key(vertex_id, id, label);
43 let val = self.append_value(tx, vertex_id, id, label, value).await.unwrap();
44 tx.set(cf, key.to_vec(), val).await.unwrap();
45 let label = label.get::<String>().unwrap();
46 Ok(VertexProperty::new(vertex_id, label, value.clone()))
47 }
48
49 async fn append_value(
50 &self,
51 tx: &mut Transaction,
52 vertex_id: &GID,
53 id: &GID,
54 label: &GValue,
55 value: &GValue,
56 ) -> Result<Vec<u8>, Error> {
57 let cf = self.cf();
58 let val = build_vertex_property_value(value);
59 let key = build_vertex_property_key(vertex_id, id, label);
60
61 let get_current_val = tx.get(cf, key.to_vec()).await;
62 match get_current_val {
63 Ok(v) => {
64 let existing_val = v.unwrap_or_default();
65 Ok([existing_val, val].concat())
66 }
67 Err(_) => Ok(vec![]),
68 }
69 }
70
71 fn iterate(
73 &self,
74 iterator: Vec<Result<KeyValuePair, Error>>,
75 ) -> Result<VertexPropertyMap, Error> {
76 let mut map = HashMap::<String, Vec<VertexProperty>>::new();
77 iterator.iter().for_each(|p| {
78 let (k, v) = p.as_ref().unwrap();
79 let bytemap = &build_byte_map(vec!["vertex_id", "label", "id"], k.to_vec());
81 let label = String::from_utf8(bytemap.get("label").unwrap().to_vec()).unwrap();
82 let gid = GID::Bytes(bytemap.get("id").unwrap().to_vec());
83 let variant = build_usize_from_bytes(v[..1].to_vec());
85 let value = GValue::from_bytes(variant, v[1..].to_vec());
86 let property = VertexProperty::new(gid, label.clone(), value);
87 map.entry(label).or_default().push(property);
88 });
89
90 Ok(map)
91 }
92
93 pub async fn iterate_from_vertex(
95 &self,
96 tx: &Transaction,
97 vertex_id: &GID,
98 ) -> Result<VertexPropertyMap, Error> {
99 let cf = self.cf();
100 let prefix = concat_bytes(vec![build_sized(Component::Gid(vertex_id))]);
101 let iterator = tx.prefix_iterate(cf, prefix).await.unwrap();
102 self.iterate(iterator)
103 }
104
105 pub async fn iterate_from_label(
106 &self,
107 tx: &Transaction,
108 vertex_id: &GID,
109 label: &GValue,
110 ) -> Result<VertexPropertyMap, Error> {
111 let cf = self.cf();
112 let prefix = concat_bytes(vec![
113 build_sized(Component::Gid(vertex_id)),
114 build_sized(Component::GValue(label)),
115 ]);
116 let iterator = tx.prefix_iterate(cf, prefix).await.unwrap();
117 self.iterate(iterator)
118 }
119}