From c56ff3fc1f05a119ea29783564a48ba75411ddc6 Mon Sep 17 00:00:00 2001 From: Anton Rusev Date: Thu, 7 Sep 2023 16:39:16 +0300 Subject: [PATCH 1/6] feat: add logEntity function Signed-off-by: Anton Rusev --- Cargo.lock | 1 + Cargo.toml | 1 + src/context/mod.rs | 149 +++++++++++++++++++++++++++++++++++++-------- src/instance.rs | 8 +++ 4 files changed, 132 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e574cc1..fe187b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2112,6 +2112,7 @@ dependencies = [ "lazy_static", "regex", "run_script", + "serde", "serde_json", "serde_yaml 0.8.26", "serial_test", diff --git a/Cargo.toml b/Cargo.toml index 83cfa7e..ab25e23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ run_script = "0.9" regex = "1.5.4" serde_yaml = "0.8.21" graphql-parser = "0.4.0" +serde = "1.0.139" [dev-dependencies] serial_test = "0.5.1" diff --git a/src/context/mod.rs b/src/context/mod.rs index 87aa2d7..a2fb26c 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -26,6 +26,7 @@ use graph_runtime_wasm::{ ExperimentalFeatures, }; use lazy_static::lazy_static; +use serde::Serialize; use serde_json::to_string_pretty; use crate::logging; @@ -72,6 +73,13 @@ pub enum StoreScope { Cache, } +#[derive(Serialize)] +#[serde(untagged)] +enum LogEntityValue { + Native(Value), + Derived(Vec>), +} + type Entity = Vec<(Word, graph::prelude::Value)>; trait Sortable { @@ -188,6 +196,85 @@ impl MatchstickInstanceContext { Ok(()) } + /// function logEntity(entity: string, id: string, showRelated: bool): void + pub fn log_entity( + &mut self, + _gas: &GasCounter, + entity_type_ptr: AscPtr, + entity_id_ptr: AscPtr, + show_related_ptr: AscPtr, + ) -> Result<(), HostExportError> { + let entity_type: String = asc_get(&self.wasm_ctx, entity_type_ptr, &GasCounter::new(), 0)?; + let entity_id: String = asc_get(&self.wasm_ctx, entity_id_ptr, &GasCounter::new(), 0)?; + let show_related: bool = bool::from(EnumPayload(show_related_ptr.to_payload())); + + let mut log: HashMap = HashMap::new(); + + if self.store.contains_key(&entity_type) + && self + .store + .get(&entity_type) + .unwrap() + .contains_key(&entity_id) + { + let entity = self + .store + .get(&entity_type) + .unwrap() + .get(&entity_id) + .unwrap() + .clone(); + + let mut virtual_fields: Vec = Vec::new(); + let has_virtual_fields = self.derived.contains_key(&entity_type); + + // prepare entity's native fields + for (field, value) in entity.iter() { + log.insert(field.clone(), LogEntityValue::Native(value.clone())); + } + + // prepare entity's dervied fields + if show_related && has_virtual_fields { + virtual_fields = self + .derived + .get(&entity_type) + .unwrap() + .clone() + .into_keys() + .collect(); + } + + for virtual_field in virtual_fields.iter() { + // convert from graph entity(vec) to store entity(hashmap) for better print result + let related_entities: Vec> = self + .load_related_entities(&entity_type, &entity_id, &virtual_field) + .into_iter() + .map(|entity: Entity| { + let mut related_entity: HashMap = HashMap::new(); + + entity.into_iter().for_each(|(word, value)| { + related_entity.insert(word.to_string(), value.clone()); + }); + + related_entity + }) + .collect(); + + log.insert( + virtual_field.clone(), + LogEntityValue::Derived(related_entities), + ); + } + } + + logging::debug!( + "{}", + to_string_pretty(&log).unwrap_or_else(|err| logging::critical!(err)), + ); + + Ok(()) + } + /// function clearStore(): void pub fn clear_store(&mut self, _gas: &GasCounter) -> Result<(), HostExportError> { self.store.clear(); @@ -398,37 +485,26 @@ impl MatchstickInstanceContext { Ok(AscPtr::null()) } - /// function store.loadRelated(entity: string, id: string, field: string): Array; - pub fn mock_store_load_related( + fn load_related_entities( &mut self, - _gas: &GasCounter, - entity_type_ptr: AscPtr, - entity_id_ptr: AscPtr, - entity_virtual_field_ptr: AscPtr, - ) -> Result>>, HostExportError> { - let entity_type: String = asc_get(&self.wasm_ctx, entity_type_ptr, &GasCounter::new(), 0)?; - let entity_id: String = asc_get(&self.wasm_ctx, entity_id_ptr, &GasCounter::new(), 0)?; - let entity_virtual_field: String = asc_get( - &self.wasm_ctx, - entity_virtual_field_ptr, - &GasCounter::new(), - 0, - )?; - + entity_type: &String, + entity_id: &String, + entity_virtual_field: &String, + ) -> Vec { let mut related_entities: Vec = Vec::new(); - if self.derived.contains_key(&entity_type) + if self.derived.contains_key(entity_type) && self .derived - .get(&entity_type) + .get(entity_type) .unwrap() - .contains_key(&entity_virtual_field) + .contains_key(entity_virtual_field) { let (derived_from_entity_type, derived_from_entity_field) = self .derived - .get(&entity_type) + .get(entity_type) .unwrap() - .get(&entity_virtual_field) + .get(entity_virtual_field) .unwrap(); if self.store.contains_key(&derived_from_entity_type.clone()) { @@ -457,7 +533,7 @@ impl MatchstickInstanceContext { let no_relation_found: bool = derived_entity_ids .iter() - .filter(|&derived_id| derived_id.to_string().eq(&entity_id)) + .filter(|&derived_id| derived_id.to_string().eq(entity_id)) .count() == 0; @@ -480,17 +556,36 @@ impl MatchstickInstanceContext { } } } - let related_entities_sorted: Vec = related_entities + + related_entities .into_iter() .map(|mut v| v.sorted().clone()) - .collect(); + .collect() + } - let related_entities_ptr: AscPtr>> = asc_new( - &mut self.wasm_ctx, - &related_entities_sorted, + /// function store.loadRelated(entity: string, id: string, field: string): Array; + pub fn mock_store_load_related( + &mut self, + _gas: &GasCounter, + entity_type_ptr: AscPtr, + entity_id_ptr: AscPtr, + entity_virtual_field_ptr: AscPtr, + ) -> Result>>, HostExportError> { + let entity_type: String = asc_get(&self.wasm_ctx, entity_type_ptr, &GasCounter::new(), 0)?; + let entity_id: String = asc_get(&self.wasm_ctx, entity_id_ptr, &GasCounter::new(), 0)?; + let entity_virtual_field: String = asc_get( + &self.wasm_ctx, + entity_virtual_field_ptr, &GasCounter::new(), + 0, )?; + let related_entities: Vec = + self.load_related_entities(&entity_type, &entity_id, &entity_virtual_field); + + let related_entities_ptr: AscPtr>> = + asc_new(&mut self.wasm_ctx, &related_entities, &GasCounter::new())?; + Ok(related_entities_ptr) } diff --git a/src/instance.rs b/src/instance.rs index 421be19..e12275d 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -307,6 +307,14 @@ impl MatchstickInstance { link!("clearStore", clear_store,); link!("clearInBlockStore", clear_cache_store,); link!("logStore", log_store,); + link!( + "logEntity", + log_entity, + entity_type_ptr, + entity_id_ptr, + show_related_ptr + ); + link!( "store.get", mock_store_get, From e9725490dd8d5ffcb894efb7fb1eb410681f1e75 Mon Sep 17 00:00:00 2001 From: Anton Rusev Date: Thu, 7 Sep 2023 16:57:55 +0300 Subject: [PATCH 2/6] chore: fix clippy check Signed-off-by: Anton Rusev --- src/context/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index a2fb26c..8049d71 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -247,13 +247,13 @@ impl MatchstickInstanceContext { for virtual_field in virtual_fields.iter() { // convert from graph entity(vec) to store entity(hashmap) for better print result let related_entities: Vec> = self - .load_related_entities(&entity_type, &entity_id, &virtual_field) + .load_related_entities(&entity_type, &entity_id, virtual_field) .into_iter() .map(|entity: Entity| { let mut related_entity: HashMap = HashMap::new(); entity.into_iter().for_each(|(word, value)| { - related_entity.insert(word.to_string(), value.clone()); + related_entity.insert(word.to_string(), value); }); related_entity From 7e051155d6017cc1c73f9e484f137aff50ea999a Mon Sep 17 00:00:00 2001 From: Anton Rusev Date: Fri, 8 Sep 2023 11:38:18 +0300 Subject: [PATCH 3/6] refactor: remove sorted, add to_entity Signed-off-by: Anton Rusev --- src/context/mod.rs | 137 +++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 86 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index 8049d71..0563ff3 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -65,7 +65,7 @@ lazy_static! { }; } -type Store = HashMap>>; +type Store = HashMap>; /// Type of the store that needs to be accessed pub enum StoreScope { @@ -77,19 +77,22 @@ pub enum StoreScope { #[serde(untagged)] enum LogEntityValue { Native(Value), - Derived(Vec>), + Derived(Vec), } type Entity = Vec<(Word, graph::prelude::Value)>; -trait Sortable { - fn sorted(&mut self) -> &Entity; +type StoreEntity = HashMap; + +trait ConvertableEntity { + fn to_entity(&mut self) -> Entity; } -impl Sortable for Entity { - fn sorted(&mut self) -> &Entity { - self.sort_by(|(k1, _), (k2, _)| k1.cmp(k2)); - self +impl ConvertableEntity for StoreEntity { + fn to_entity(&mut self) -> Entity { + self.iter_mut() + .map(|(k, v)| (Word::from(k.to_string()), v.clone())) + .collect() } } @@ -210,60 +213,36 @@ impl MatchstickInstanceContext { let mut log: HashMap = HashMap::new(); - if self.store.contains_key(&entity_type) - && self - .store - .get(&entity_type) - .unwrap() - .contains_key(&entity_id) - { - let entity = self - .store - .get(&entity_type) - .unwrap() - .get(&entity_id) - .unwrap() - .clone(); + if let Some(entities) = self.store.get(&entity_type) { + if let Some(entity) = entities.get(&entity_id) { + let mut virtual_fields: Vec = Vec::new(); + let has_virtual_fields = self.derived.contains_key(&entity_type); - let mut virtual_fields: Vec = Vec::new(); - let has_virtual_fields = self.derived.contains_key(&entity_type); + // prepare entity's native fields + for (field, value) in entity.iter() { + log.insert(field.clone(), LogEntityValue::Native(value.clone())); + } - // prepare entity's native fields - for (field, value) in entity.iter() { - log.insert(field.clone(), LogEntityValue::Native(value.clone())); - } + // prepare entity's dervied fields + if show_related && has_virtual_fields { + virtual_fields = self + .derived + .get(&entity_type) + .unwrap() + .clone() + .into_keys() + .collect(); + } - // prepare entity's dervied fields - if show_related && has_virtual_fields { - virtual_fields = self - .derived - .get(&entity_type) - .unwrap() - .clone() - .into_keys() - .collect(); - } + for virtual_field in virtual_fields.iter() { + let related_entities: Vec> = + self.load_related_entities(&entity_type, &entity_id, virtual_field); - for virtual_field in virtual_fields.iter() { - // convert from graph entity(vec) to store entity(hashmap) for better print result - let related_entities: Vec> = self - .load_related_entities(&entity_type, &entity_id, virtual_field) - .into_iter() - .map(|entity: Entity| { - let mut related_entity: HashMap = HashMap::new(); - - entity.into_iter().for_each(|(word, value)| { - related_entity.insert(word.to_string(), value); - }); - - related_entity - }) - .collect(); - - log.insert( - virtual_field.clone(), - LogEntityValue::Derived(related_entities), - ); + log.insert( + virtual_field.clone(), + LogEntityValue::Derived(related_entities), + ); + } } } @@ -470,15 +449,9 @@ impl MatchstickInstanceContext { if store.contains_key(&entity_type) && store.get(&entity_type).unwrap().contains_key(&id) { let entities = store.get(&entity_type).unwrap(); - let mut entity: Entity = entities - .get(&id) - .unwrap() - .clone() - .into_iter() - .map(|(k, v)| (Word::from(k), v)) - .collect(); + let entity: Entity = entities.get(&id).unwrap().clone().to_entity(); - let res = asc_new(&mut self.wasm_ctx, &entity.sorted(), &GasCounter::new())?; + let res = asc_new(&mut self.wasm_ctx, &entity, &GasCounter::new())?; return Ok(res); } @@ -490,8 +463,8 @@ impl MatchstickInstanceContext { entity_type: &String, entity_id: &String, entity_virtual_field: &String, - ) -> Vec { - let mut related_entities: Vec = Vec::new(); + ) -> Vec { + let mut related_entities: Vec = Vec::new(); if self.derived.contains_key(entity_type) && self @@ -547,20 +520,13 @@ impl MatchstickInstanceContext { .unwrap() .get(&derived_entity_id.clone()) .unwrap() - .clone() - // convert to Entity - .into_iter() - .map(|(k, v)| (Word::from(k), v)) - .collect(), + .clone(), ); } } } related_entities - .into_iter() - .map(|mut v| v.sorted().clone()) - .collect() } /// function store.loadRelated(entity: string, id: string, field: string): Array; @@ -580,8 +546,12 @@ impl MatchstickInstanceContext { 0, )?; - let related_entities: Vec = - self.load_related_entities(&entity_type, &entity_id, &entity_virtual_field); + let related_entities: Vec = self + .load_related_entities(&entity_type, &entity_id, &entity_virtual_field) + // convert to Entity + .into_iter() + .map(|mut v: StoreEntity| v.to_entity()) + .collect(); let related_entities_ptr: AscPtr>> = asc_new(&mut self.wasm_ctx, &related_entities, &GasCounter::new())?; @@ -619,8 +589,7 @@ impl MatchstickInstanceContext { ) -> Result<(), HostExportError> { let entity_type: String = asc_get(&self.wasm_ctx, entity_type_ptr, &GasCounter::new(), 0)?; let id: String = asc_get(&self.wasm_ctx, id_ptr, &GasCounter::new(), 0)?; - let data: HashMap = - asc_get(&self.wasm_ctx, data_ptr, &GasCounter::new(), 0)?; + let data: StoreEntity = asc_get(&self.wasm_ctx, data_ptr, &GasCounter::new(), 0)?; let required_fields = SCHEMA .definitions @@ -971,13 +940,9 @@ impl MatchstickInstanceContext { let default_context_val: Entity = Vec::new(); let result = match &self.data_source_return_value.2 { Some(value) => { - let mut entity: Entity = value - .clone() - .into_iter() - .map(|(k, v)| (Word::from(k), v)) - .collect(); + let entity: Entity = value.clone().to_entity(); - asc_new(&mut self.wasm_ctx, &entity.sorted(), &GasCounter::new()).unwrap() + asc_new(&mut self.wasm_ctx, &entity, &GasCounter::new()).unwrap() } None => asc_new(&mut self.wasm_ctx, &default_context_val, &GasCounter::new()).unwrap(), }; From f3282a44e733a0bc480d0aa30a552211a357f048 Mon Sep 17 00:00:00 2001 From: Anton Rusev Date: Fri, 8 Sep 2023 12:48:16 +0300 Subject: [PATCH 4/6] feat: check if the entity exists in the schema file Signed-off-by: Anton Rusev --- src/context/mod.rs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index 0563ff3..92a7afe 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -213,17 +213,41 @@ impl MatchstickInstanceContext { let mut log: HashMap = HashMap::new(); + // validates whether the provided entity exists in the schema file + let is_invalid_entity = SCHEMA + .definitions + .iter() + .filter(|def| { + if let schema::Definition::TypeDefinition(schema::TypeDefinition::Object( + entity_def, + )) = def + { + entity_def.name.eq(&entity_type) + } else { + false + } + }) + .count() + == 0; + + if is_invalid_entity { + panic!( + "Entity \"{}\" does not match any of the schema definitions", + &entity_type + ); + } + if let Some(entities) = self.store.get(&entity_type) { if let Some(entity) = entities.get(&entity_id) { let mut virtual_fields: Vec = Vec::new(); let has_virtual_fields = self.derived.contains_key(&entity_type); - // prepare entity's native fields + // prepares entity's native fields for (field, value) in entity.iter() { log.insert(field.clone(), LogEntityValue::Native(value.clone())); } - // prepare entity's dervied fields + // prepares entity's dervied fields if show_related && has_virtual_fields { virtual_fields = self .derived From 3647c4f52f7d43155ecc650ba1c5e2a2279af0ce Mon Sep 17 00:00:00 2001 From: Anton Rusev Date: Fri, 8 Sep 2023 15:13:41 +0300 Subject: [PATCH 5/6] refactor: use ctx schema, rename Entity trait Signed-off-by: Anton Rusev --- src/context/derived_schema.rs | 15 ++-- src/context/mod.rs | 149 +++++++++++++++------------------- 2 files changed, 71 insertions(+), 93 deletions(-) diff --git a/src/context/derived_schema.rs b/src/context/derived_schema.rs index fcf372a..9bbd99b 100644 --- a/src/context/derived_schema.rs +++ b/src/context/derived_schema.rs @@ -1,17 +1,17 @@ use std::collections::HashMap; use graph::data::graphql::ext::DirectiveFinder; -use graph_graphql::graphql_parser::schema; -use crate::context::{MatchstickInstanceContext, SCHEMA}; +use crate::context::MatchstickInstanceContext; pub(crate) fn derive_schema( context: &mut MatchstickInstanceContext, ) { - SCHEMA.definitions.iter().for_each(|def| { - if let schema::Definition::TypeDefinition(schema::TypeDefinition::Object(o)) = def { - let entity_type = &o.name; - let derived_fields = o.fields.iter().filter(|&f| f.is_derived()); + context + .schema + .iter() + .for_each(|(entity_type, entity_object)| { + let derived_fields = entity_object.fields.iter().filter(|&f| f.is_derived()); for virtual_field in derived_fields { // field type is received as: '[ExampleClass!]!' and needs to be reduced to a class string let derived_from_entity_type = virtual_field @@ -49,6 +49,5 @@ pub(crate) fn derive_schema( .insert(entity_type.to_string(), entity_virtual_fields); } } - } - }); + }); } diff --git a/src/context/mod.rs b/src/context/mod.rs index 92a7afe..cd5a035 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -84,11 +84,11 @@ type Entity = Vec<(Word, graph::prelude::Value)>; type StoreEntity = HashMap; -trait ConvertableEntity { +trait ToEntity { fn to_entity(&mut self) -> Entity; } -impl ConvertableEntity for StoreEntity { +impl ToEntity for StoreEntity { fn to_entity(&mut self) -> Entity { self.iter_mut() .map(|(k, v)| (Word::from(k.to_string()), v.clone())) @@ -125,6 +125,8 @@ pub struct MatchstickInstanceContext { /// } /// ``` pub(crate) derived: HashMap>, + /// Holds the graphql schema for easier access + schema: HashMap>, /// Gives guarantee that all derived relations are in order when true store_updated: bool, /// Holds the mocked return values of `dataSource.address()`, `dataSource.network()` and `dataSource.context()` in that order @@ -148,10 +150,23 @@ impl MatchstickInstanceContext { fn_ret_map: HashMap::new(), meta_tests: Vec::new(), derived: HashMap::new(), + schema: HashMap::new(), store_updated: true, data_source_return_value: (None, None, None), ipfs: HashMap::new(), }; + + // reads the graphql schema file and extracts all entities and their object types + SCHEMA.definitions.iter().for_each(|def| { + if let schema::Definition::TypeDefinition(schema::TypeDefinition::Object(entity_def)) = + def + { + context + .schema + .insert(entity_def.name.clone(), entity_def.clone()); + } + }); + derive_schema(&mut context); context } @@ -214,59 +229,43 @@ impl MatchstickInstanceContext { let mut log: HashMap = HashMap::new(); // validates whether the provided entity exists in the schema file - let is_invalid_entity = SCHEMA - .definitions - .iter() - .filter(|def| { - if let schema::Definition::TypeDefinition(schema::TypeDefinition::Object( - entity_def, - )) = def - { - entity_def.name.eq(&entity_type) - } else { - false - } - }) - .count() - == 0; - - if is_invalid_entity { + if !self.schema.contains_key(&entity_type) { panic!( "Entity \"{}\" does not match any of the schema definitions", &entity_type ); } - if let Some(entities) = self.store.get(&entity_type) { - if let Some(entity) = entities.get(&entity_id) { - let mut virtual_fields: Vec = Vec::new(); - let has_virtual_fields = self.derived.contains_key(&entity_type); + let entity = self.store.get(&entity_type).and_then(|x| x.get(&entity_id)); - // prepares entity's native fields - for (field, value) in entity.iter() { - log.insert(field.clone(), LogEntityValue::Native(value.clone())); - } + if let Some(entity) = entity { + let mut virtual_fields: Vec = Vec::new(); + let has_virtual_fields = self.derived.contains_key(&entity_type); - // prepares entity's dervied fields - if show_related && has_virtual_fields { - virtual_fields = self - .derived - .get(&entity_type) - .unwrap() - .clone() - .into_keys() - .collect(); - } + // prepares entity's native fields + for (field, value) in entity.iter() { + log.insert(field.clone(), LogEntityValue::Native(value.clone())); + } - for virtual_field in virtual_fields.iter() { - let related_entities: Vec> = - self.load_related_entities(&entity_type, &entity_id, virtual_field); + // prepares entity's dervied fields + if show_related && has_virtual_fields { + virtual_fields = self + .derived + .get(&entity_type) + .unwrap() + .clone() + .into_keys() + .collect(); + } - log.insert( - virtual_field.clone(), - LogEntityValue::Derived(related_entities), - ); - } + for virtual_field in virtual_fields.iter() { + let related_entities: Vec> = + self.load_related_entities(&entity_type, &entity_id, virtual_field); + + log.insert( + virtual_field.clone(), + LogEntityValue::Derived(related_entities), + ); } } @@ -471,11 +470,16 @@ impl MatchstickInstanceContext { StoreScope::Cache => &self.cache_store, }; - if store.contains_key(&entity_type) && store.get(&entity_type).unwrap().contains_key(&id) { - let entities = store.get(&entity_type).unwrap(); - let entity: Entity = entities.get(&id).unwrap().clone().to_entity(); + let entity = store + .get(&entity_type) + .and_then(|entities| entities.get(&id)); - let res = asc_new(&mut self.wasm_ctx, &entity, &GasCounter::new())?; + if entity.is_some() { + let res = asc_new( + &mut self.wasm_ctx, + &entity.unwrap().clone().to_entity(), + &GasCounter::new(), + )?; return Ok(res); } @@ -490,27 +494,16 @@ impl MatchstickInstanceContext { ) -> Vec { let mut related_entities: Vec = Vec::new(); - if self.derived.contains_key(entity_type) - && self - .derived - .get(entity_type) - .unwrap() - .contains_key(entity_virtual_field) - { - let (derived_from_entity_type, derived_from_entity_field) = self - .derived - .get(entity_type) - .unwrap() - .get(entity_virtual_field) - .unwrap(); - - if self.store.contains_key(&derived_from_entity_type.clone()) { - for (derived_entity_id, derived_entity_fields) in self - .store - .get(&derived_from_entity_type.clone()) - .unwrap() - .iter() - { + let derived_from_entity = self + .derived + .get(entity_type) + .and_then(|fields| fields.get(entity_virtual_field)); + + if let Some((derived_from_entity_type, derived_from_entity_field)) = derived_from_entity { + let derived_entity = self.store.get(&derived_from_entity_type.clone()); + + if let Some(derived_entity) = derived_entity { + for (derived_entity_id, derived_entity_fields) in derived_entity.iter() { if !derived_entity_fields.contains_key(&derived_from_entity_field.clone()) { continue; } @@ -615,21 +608,7 @@ impl MatchstickInstanceContext { let id: String = asc_get(&self.wasm_ctx, id_ptr, &GasCounter::new(), 0)?; let data: StoreEntity = asc_get(&self.wasm_ctx, data_ptr, &GasCounter::new(), 0)?; - let required_fields = SCHEMA - .definitions - .iter() - .find_map(|def| { - if let schema::Definition::TypeDefinition(schema::TypeDefinition::Object(o)) = def { - if o.name == entity_type { - Some(o) - } else { - None - } - } else { - None - } - }) - .unwrap_or_else(|| { + let required_fields = self.schema.get(&entity_type).unwrap_or_else(|| { logging::critical!("Something went wrong! Could not find the entity defined in the GraphQL schema.") }) .fields From cb9226121fa57d34b8da099294f2ddeb07b45332 Mon Sep 17 00:00:00 2001 From: Anton Rusev Date: Fri, 8 Sep 2023 17:34:18 +0300 Subject: [PATCH 6/6] chore: remove redundant refs, add comments Signed-off-by: Anton Rusev --- src/context/mod.rs | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index cd5a035..2f52a4d 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -494,26 +494,31 @@ impl MatchstickInstanceContext { ) -> Vec { let mut related_entities: Vec = Vec::new(); + // gets the derived entity type and derived entity field associated with the parent entity let derived_from_entity = self .derived .get(entity_type) .and_then(|fields| fields.get(entity_virtual_field)); if let Some((derived_from_entity_type, derived_from_entity_field)) = derived_from_entity { - let derived_entity = self.store.get(&derived_from_entity_type.clone()); + let derived_entities = self.store.get(derived_from_entity_type); - if let Some(derived_entity) = derived_entity { - for (derived_entity_id, derived_entity_fields) in derived_entity.iter() { - if !derived_entity_fields.contains_key(&derived_from_entity_field.clone()) { + if let Some(derived_entities) = derived_entities { + // loop through all derived entities from the store to find a relation with the parent entity + // if relation is found, it adds the whole entity to the related entities result + for (derived_entity_id, derived_entity) in derived_entities.iter() { + if !derived_entity.contains_key(derived_from_entity_field) { continue; } - let derived_field_value = derived_entity_fields - .get(&derived_from_entity_field.clone()) + // derived field value could be a single ID or list of IDs + let derived_field_value = derived_entity + .get(derived_from_entity_field) .unwrap() .clone(); - // field value could be a single ID or list of IDs + // converts different value types(string, bytes, list) to a single vector + // that way it would be easier to find relation by entity id let derived_entity_ids: Vec = match derived_field_value { Value::Bytes(id) => vec![Value::from(id)], Value::String(id) => vec![Value::from(id)], @@ -521,24 +526,14 @@ impl MatchstickInstanceContext { _ => vec![], }; - let no_relation_found: bool = derived_entity_ids + let relation_found: bool = derived_entity_ids .iter() - .filter(|&derived_id| derived_id.to_string().eq(entity_id)) - .count() - == 0; + .any(|derived_id| derived_id.to_string().eq(entity_id)); - if no_relation_found { - continue; + if relation_found { + related_entities + .push(derived_entities.get(derived_entity_id).unwrap().clone()); } - - related_entities.push( - self.store - .get(&derived_from_entity_type.clone()) - .unwrap() - .get(&derived_entity_id.clone()) - .unwrap() - .clone(), - ); } } }