Skip to content

Commit d32aec2

Browse files
committed
Add relationship controller & refractor test dir
1 parent 5406bab commit d32aec2

File tree

14 files changed

+295
-177
lines changed

14 files changed

+295
-177
lines changed

db/src/controller/label.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use crate::util::{build_bytes, from_uuid_bytes, Component};
2-
use crate::{DatastoreAdapter, Error, Label, SimpleTransaction};
1+
use crate::util::{
2+
build_bytes, build_meta, deserialize_data_with_meta, from_uuid_bytes, Component,
3+
};
4+
use crate::{AccountDiscriminator, DatastoreAdapter, Error, Label, SimpleTransaction};
35

46
impl_controller!(LabelController("labels:v1"));
57

@@ -19,7 +21,9 @@ impl LabelController {
1921

2022
let cf = self.get_cf();
2123
let key = build_bytes(&[Component::Uuid(label.id)]).unwrap();
22-
let val = name.as_bytes();
24+
let discriminator = AccountDiscriminator::Label.serialize();
25+
let meta = &build_meta(1, name.len());
26+
let val = [discriminator, meta.to_vec(), name.as_bytes().to_vec()].concat();
2327

2428
tx.set(cf, key, val).await.unwrap();
2529
tx.commit().await.unwrap();
@@ -40,23 +44,16 @@ impl LabelController {
4044
let tx = self.config.ds.transaction(false).unwrap();
4145

4246
let cf = self.get_cf();
43-
let val = tx.get(cf, id.to_vec()).await.unwrap();
44-
match val {
45-
Some(v) => Ok(Label {
46-
id: from_uuid_bytes(&id).unwrap(),
47-
name: String::from_utf8(v).unwrap(),
48-
}),
47+
let raw = tx.get(cf, id.to_vec()).await.unwrap();
48+
match raw {
49+
Some(r) => {
50+
let (data, _, _) = deserialize_data_with_meta(r, true).unwrap();
51+
Ok(Label {
52+
id: from_uuid_bytes(&id).unwrap(),
53+
name: String::from_utf8(data[0].to_vec()).unwrap(),
54+
})
55+
}
4956
None => panic!("No label value"),
5057
}
5158
}
5259
}
53-
54-
// #[cfg(feature = "test-suite")]
55-
#[cfg(test)]
56-
#[tokio::test]
57-
async fn should_create_label() {
58-
let lc = LabelController::default();
59-
let res = lc.create_label("Person").await.unwrap();
60-
let label = lc.get_label(res.id.as_bytes().to_vec()).await.unwrap();
61-
assert_eq!(label, res);
62-
}

db/src/controller/property.rs

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::util::{build_bytes, build_offset, deserialize_byte_data, from_uuid_bytes, Component};
2-
use crate::{DatastoreAdapter, Error, Property, PropertyVariant, SimpleTransaction};
1+
use crate::util::{build_bytes, build_meta, deserialize_byte_data, from_uuid_bytes, Component};
2+
use crate::{DatastoreAdapter, Error, PropType, Property, SimpleTransaction};
33

44
impl_controller!(PropertyController("properties:v1"));
55

@@ -12,22 +12,18 @@ impl Default for PropertyController {
1212
}
1313

1414
impl PropertyController {
15-
pub async fn create_property(
16-
&self,
17-
name: &str,
18-
variant: PropertyVariant,
19-
) -> Result<Property, Error> {
15+
pub async fn create_property(&self, name: &str, variant: PropType) -> Result<Property, Error> {
2016
let mut tx = self.config.ds.transaction(true).unwrap();
2117

2218
let cf = self.get_cf();
2319
// First four bytes are the property
24-
let serialized_variant = bincode::serialize::<PropertyVariant>(&variant).unwrap();
20+
let serialized_variant = bincode::serialize::<PropType>(&variant).unwrap();
2521
let property = Property::new(name, variant).unwrap();
26-
let property_offset = &build_offset(1, serialized_variant.len());
22+
let property_meta = &build_meta(1, serialized_variant.len());
2723
let name = name.as_bytes();
28-
let name_offset = &build_offset(1, name.len());
24+
let name_meta = &build_meta(1, name.len());
2925
// Dynamic length string will be concatenated at the end
30-
let val = [property_offset, &serialized_variant, name_offset, name].concat();
26+
let val = [property_meta, &serialized_variant, name_meta, name].concat();
3127

3228
let key = build_bytes(&[Component::Uuid(property.id)]).unwrap();
3329
tx.set(cf, key, val).await.unwrap();
@@ -37,7 +33,7 @@ impl PropertyController {
3733

3834
pub async fn create_properties(
3935
&self,
40-
properties: Vec<(&str, PropertyVariant)>,
36+
properties: Vec<(&str, PropType)>,
4137
) -> Result<Vec<Property>, Error> {
4238
let mut result = vec![];
4339
for (name, variant) in properties {
@@ -59,7 +55,7 @@ impl PropertyController {
5955
let name = &deserialized[1].0.first().unwrap();
6056

6157
let name = String::from_utf8(name.to_vec()).unwrap();
62-
let t = bincode::deserialize::<PropertyVariant>(property).unwrap();
58+
let t = bincode::deserialize::<PropType>(property).unwrap();
6359
Ok(Property {
6460
id: from_uuid_bytes(&id).unwrap(),
6561
name,
@@ -70,26 +66,3 @@ impl PropertyController {
7066
}
7167
}
7268
}
73-
74-
#[cfg(test)]
75-
#[tokio::test]
76-
async fn should_create_property() {
77-
let pc = PropertyController::default();
78-
let res = pc.create_property("Name", PropertyVariant::String).await.unwrap();
79-
let property = pc.get_property(res.id.as_bytes().to_vec()).await.unwrap();
80-
assert_eq!(property, res);
81-
}
82-
83-
#[cfg(test)]
84-
#[tokio::test]
85-
async fn should_create_properties() {
86-
let pc = PropertyController::default();
87-
let properties = pc
88-
.create_properties(vec![
89-
("name", PropertyVariant::String),
90-
("age", PropertyVariant::UInt128),
91-
])
92-
.await
93-
.unwrap();
94-
assert_eq!(properties.len(), 2);
95-
}

db/src/controller/relationship.rs

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::collections::HashMap;
2-
32
use uuid::Uuid;
43

5-
use crate::util::{build_bytes, Component};
6-
use crate::{DatastoreAdapter, Error, Identifier, Relationship, SimpleTransaction};
4+
use crate::util::{build_bytes, deserialize_data_with_meta, from_uuid_bytes, Component};
5+
use crate::{
6+
AccountDiscriminator, DatastoreAdapter, Error, Identifier, Relationship, SimpleTransaction,
7+
};
78

89
impl_controller!(RelationshipController("relationships:v1"));
910

@@ -16,29 +17,73 @@ impl Default for RelationshipController {
1617
}
1718

1819
impl RelationshipController {
19-
pub async fn create_property(
20+
pub async fn create_relationship(
2021
&self,
21-
s_node: Uuid,
22-
t_node: Uuid,
22+
source_vertex: Uuid,
23+
target_vertex: Uuid,
2324
t: &str,
2425
props: HashMap<Uuid, Vec<u8>>,
2526
) -> Result<Relationship, Error> {
2627
let mut tx = self.config.ds.transaction(true).unwrap();
28+
let prop_components =
29+
props.iter().map(|(id, val)| Component::Property(id, val)).collect::<Vec<Component>>();
2730

2831
let cf = self.get_cf();
2932
let t_id = Identifier::new(t.to_string()).unwrap();
3033
let key = build_bytes(&[
31-
Component::Uuid(s_node),
32-
Component::Uuid(s_node),
34+
Component::Uuid(source_vertex),
3335
Component::Identifier(&t_id),
34-
Component::Uuid(t_node),
36+
Component::Uuid(target_vertex),
3537
])
3638
.unwrap();
37-
let relationship = Relationship::new(s_node, t_node, t_id, props).unwrap();
38-
let val = [];
39+
40+
// Handle byte concatenate for property components
41+
let _prop_discriminator = AccountDiscriminator::Property.serialize();
42+
let _props = &build_bytes(&prop_components).unwrap();
43+
// (Property discriminator, Property byte array - meta for each property generated)
44+
let (p_dis, p) = (_prop_discriminator.as_slice(), _props.as_slice());
45+
let props_concat = [p_dis, p].concat();
46+
47+
let val = [props_concat].concat();
3948

4049
tx.set(cf, key, val).await.unwrap();
4150
tx.commit().await.unwrap();
51+
52+
let relationship = Relationship::new(source_vertex, target_vertex, t_id, props).unwrap();
53+
Ok(relationship)
54+
}
55+
56+
pub async fn get_relationship(
57+
&self,
58+
source_vertex: Uuid,
59+
target_vertex: Uuid,
60+
t: &str,
61+
) -> Result<Relationship, Error> {
62+
let tx = self.config.ds.transaction(false).unwrap();
63+
let cf = self.get_cf();
64+
let t_id = Identifier::new(t.to_string()).unwrap();
65+
let key = build_bytes(&[
66+
Component::Uuid(source_vertex),
67+
Component::Identifier(&t_id),
68+
Component::Uuid(target_vertex),
69+
])
70+
.unwrap();
71+
72+
let mut props = HashMap::default();
73+
let raw_relationship = tx.get(cf, key).await.unwrap();
74+
match raw_relationship {
75+
Some(r) => {
76+
let (props_bytes, _, _) = deserialize_data_with_meta(r, true).unwrap();
77+
let uuid_len = Component::Uuid(Uuid::nil()).len();
78+
for slice in props_bytes {
79+
let (uuid, value) = (&slice[..uuid_len], &slice[uuid_len..]);
80+
props.insert(from_uuid_bytes(uuid).unwrap(), value.to_vec());
81+
}
82+
}
83+
None => panic!("No relationship found"),
84+
}
85+
86+
let relationship = Relationship::new(source_vertex, target_vertex, t_id, props).unwrap();
4287
Ok(relationship)
4388
}
4489
}

db/src/controller/vertex.rs

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use std::collections::HashMap;
22

33
use crate::{
44
model::adapter::DatastoreAdapter,
5-
serialize_discriminator,
6-
util::{build_bytes, build_offset, deserialize_byte_data, from_uuid_bytes, Component},
5+
util::{build_bytes, build_meta, deserialize_byte_data, from_uuid_bytes, Component},
76
AccountDiscriminator, Error, Label, SimpleTransaction, Vertex,
87
};
98

@@ -21,6 +20,14 @@ impl Default for VertexController {
2120

2221
impl VertexController {
2322
/// # Create a new vertex from labels and properties
23+
/// ## Description
24+
/// Because Vertex has multiple dynamic sized attributes:
25+
/// - labels: Vec<Label>
26+
/// - props: HashMap<Uuid, Vec<u8>>
27+
/// It will be a bit more complicated.
28+
///
29+
/// Data will be store in Vertex as
30+
/// + label_discriminator | label_meta | label data
2431
pub async fn create_vertex(
2532
&self,
2633
labels: Vec<Label>,
@@ -35,19 +42,21 @@ impl VertexController {
3542
let label_components =
3643
labels.iter().map(|l| Component::Uuid(l.id)).collect::<Vec<Component>>();
3744
let prop_components =
38-
props.iter().map(|p| Component::Property(p.0, p.1)).collect::<Vec<Component>>();
45+
props.iter().map(|(id, val)| Component::Property(id, val)).collect::<Vec<Component>>();
3946

4047
// Handle byte concatenate for label components
41-
let _label_discriminator = serialize_discriminator(AccountDiscriminator::Label).unwrap();
48+
let label_discriminator = AccountDiscriminator::Label.serialize();
4249
let _labels = build_bytes(&label_components).unwrap();
43-
let _label_offset = &build_offset(ll, uuid_len);
44-
let (l_dis, l, l_offset) =
45-
(_label_discriminator.as_slice(), _label_offset.as_slice(), _labels.as_slice());
46-
let labels_concat = [l_dis, l, l_offset].concat();
50+
let label_meta = &build_meta(ll, uuid_len);
51+
// (Label discriminator, Label byte array, Label metadata)
52+
let (l_dis, l, l_meta) =
53+
(label_discriminator.as_slice(), label_meta.as_slice(), _labels.as_slice());
54+
let labels_concat = [l_dis, l, l_meta].concat();
4755

4856
// Handle byte concatenate for property components
57+
let _prop_discriminator = AccountDiscriminator::Property.serialize();
4958
let _props = &build_bytes(&prop_components).unwrap();
50-
let _prop_discriminator = serialize_discriminator(AccountDiscriminator::Property).unwrap();
59+
// (Property discriminator, Property byte array - meta for each property generated)
5160
let (p_dis, p) = (_prop_discriminator.as_slice(), _props.as_slice());
5261
let props_concat = [p_dis, p].concat();
5362

@@ -105,41 +114,3 @@ impl VertexController {
105114
}
106115
}
107116
}
108-
109-
// #[cfg(feature = "test-suite")]
110-
#[cfg(test)]
111-
#[tokio::test]
112-
async fn should_create_label() {
113-
use crate::{LabelController, PropertyController, PropertyVariant};
114-
115-
let vc = VertexController::default();
116-
let lc = LabelController::default();
117-
let pc = PropertyController::default();
118-
119-
let raw_labels = ["Person", "Student", "Employee"];
120-
let properties = pc
121-
.create_properties(vec![
122-
("name", PropertyVariant::String),
123-
("age", PropertyVariant::UInt128),
124-
("addresses", PropertyVariant::VecString),
125-
])
126-
.await
127-
.unwrap();
128-
let labels = lc.create_labels(raw_labels.to_vec()).await.unwrap();
129-
let res = vc
130-
.create_vertex(
131-
labels,
132-
HashMap::from([
133-
(properties[0].id, "example name 1234".as_bytes().to_vec()),
134-
(properties[1].id, Vec::from([15])),
135-
(properties[2].id, ["address 1", "address 2"].concat().as_bytes().to_vec()),
136-
]),
137-
)
138-
.await
139-
.unwrap();
140-
assert_eq!(res.labels.len(), raw_labels.len());
141-
142-
let vertex = vc.get_vertex(res.id.as_bytes().to_vec()).await.unwrap();
143-
assert_eq!(vertex, res);
144-
assert_eq!(vertex.labels.len(), raw_labels.len());
145-
}

db/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod util;
1212
pub use crate::storage::kvs::CassandraDBAdapter;
1313
#[cfg(feature = "kv-rocksdb")]
1414
pub use crate::storage::kvs::RocksDBAdapter;
15-
#[cfg(feature = "test-suite")]
15+
// #[cfg(feature = "test-suite")]
1616
#[macro_use]
1717
pub mod tests;
1818

db/src/model/graph/account.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use bincode::Error;
21
use serde::{Deserialize, Serialize};
32

43
#[derive(PartialEq, Serialize, Deserialize, Eq, Debug, Clone)]
@@ -15,7 +14,3 @@ impl AccountDiscriminator {
1514
bincode::serialize(self).unwrap()
1615
}
1716
}
18-
19-
pub fn serialize_discriminator(ad: AccountDiscriminator) -> Result<Vec<u8>, Error> {
20-
bincode::serialize(&ad)
21-
}

db/src/model/graph/property.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use uuid::Uuid;
44
use crate::Error;
55

66
#[derive(PartialEq, Serialize, Deserialize, Eq, Debug, Clone)]
7-
pub enum PropertyVariant {
7+
pub enum PropType {
88
Unknown = 0,
99
String = 1,
1010
UInt32 = 2,
@@ -17,9 +17,9 @@ pub enum PropertyVariant {
1717
VecUint128 = 9,
1818
}
1919

20-
impl Default for PropertyVariant {
20+
impl Default for PropType {
2121
fn default() -> Self {
22-
PropertyVariant::Unknown
22+
PropType::Unknown
2323
}
2424
}
2525

@@ -29,12 +29,12 @@ impl Default for PropertyVariant {
2929
#[derive(PartialEq, Eq, Debug, Clone, Default)]
3030
pub struct Property {
3131
pub id: Uuid,
32-
pub t: PropertyVariant,
32+
pub t: PropType,
3333
pub name: String,
3434
}
3535

3636
impl Property {
37-
pub fn new(name: &str, t: PropertyVariant) -> Result<Self, Error> {
37+
pub fn new(name: &str, t: PropType) -> Result<Self, Error> {
3838
Ok(Property {
3939
id: Uuid::new_v4(),
4040
name: name.to_string(),

0 commit comments

Comments
 (0)