db/repo/
property.rs

1use 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::PropertyMap;
10use solomon_gremlin::{GValue, Property, GID};
11
12impl_repository!(PropertyRepository(Property));
13
14fn build_property_value(value: &GValue) -> Vec<u8> {
15	build_bytes(&[Component::GValueType(value), Component::GValue(value)]).unwrap()
16}
17
18impl<'a> PropertyRepository<'a> {
19	/// The property()-step is used to add properties to the elements of the graph (sideEffect).
20	/// Unlike addV() and addE(), property() is a full sideEffect step in that it does not return
21	/// the property it created, but the element that streamed into it. Moreover, if property()
22	/// follows an addV() or addE(), then it is "folded" into the previous step to enable vertex
23	/// and edge creation with all its properties in one creation operation.
24	pub async fn property(
25		&self,
26		tx: &mut Transaction,
27		id: &GID,
28		label: &GValue,
29		value: &GValue,
30	) -> Result<Property, Error> {
31		let cf = self.cf();
32		let val = build_property_value(value);
33		let key = concat_bytes(vec![
34			build_sized(Component::Gid(id)),
35			build_sized(Component::GValue(label)),
36		]);
37		tx.set(cf, key.to_vec(), val).await.unwrap();
38		let label = label.get::<String>().unwrap();
39		Ok(Property::new(label, value.clone()))
40	}
41
42	/// Method to iterate the pairs of byte data
43	fn iterate(&self, iterator: Vec<Result<KeyValuePair, Error>>) -> Result<PropertyMap, Error> {
44		let mut map = HashMap::<String, Property>::new();
45		iterator.iter().for_each(|p| {
46			let (k, v) = p.as_ref().unwrap();
47			// Handle deserializing and rebuild vertex stream
48			let bytemap = &build_byte_map(vec!["vertex_id", "label"], k.to_vec());
49			let label_bytes = bytemap.get("label").unwrap().to_vec();
50			let label = String::from_utf8(label_bytes).unwrap();
51			// Handle deserializing GValue
52			let variant = build_usize_from_bytes(v[..1].to_vec());
53			let value = GValue::from_bytes(variant, v[1..].to_vec());
54			let property = Property::new(label.clone(), value);
55			map.insert(label, property);
56		});
57
58		Ok(map)
59	}
60
61	/// Method to iterate the pairs of byte data with prefix as edge id
62	pub async fn iterate_from_edge(
63		&self,
64		tx: &Transaction,
65		edge_id: &GID,
66	) -> Result<PropertyMap, Error> {
67		let cf = self.cf();
68		let prefix = build_sized(Component::Gid(edge_id));
69		let iterator = tx.prefix_iterate(cf, prefix).await.unwrap();
70		self.iterate(iterator)
71	}
72
73	pub async fn iterate_from_label(
74		&self,
75		tx: &Transaction,
76		edge_id: &GID,
77		label: &GValue,
78	) -> Result<PropertyMap, Error> {
79		let cf = self.cf();
80		let prefix = concat_bytes(vec![
81			build_sized(Component::Gid(edge_id)),
82			build_sized(Component::GValue(label)),
83		]);
84		let iterator = tx.prefix_iterate(cf, prefix).await.unwrap();
85		self.iterate(iterator)
86	}
87}