Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/src/schema/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Account {
impl Account {
/// Account ID
fn id(&self) -> &str {
&self.entity.id
self.entity.id()
}

/// Ethereum address of the account
Expand Down
141 changes: 83 additions & 58 deletions api/src/schema/entity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use futures::TryStreamExt;
use grc20_sdk::models::property;
use juniper::{graphql_object, Executor, FieldResult, ScalarValue};

use grc20_core::{
Expand All @@ -19,17 +20,24 @@ use super::{AttributeFilter, EntityRelationFilter, EntityVersion};

#[derive(Debug)]
pub struct Entity {
node: EntityNode,
space_id: String,
space_version: Option<String>,
pub node: EntityNode,
pub space_id: String,
pub space_version: Option<String>,
pub strict: bool,
}

impl Entity {
pub fn new(node: EntityNode, space_id: String, space_version: Option<String>) -> Self {
pub fn new(
node: EntityNode,
space_id: String,
space_version: Option<String>,
strict: bool,
) -> Self {
Self {
node,
space_id,
space_version,
strict,
}
}

Expand All @@ -38,14 +46,15 @@ impl Entity {
id: impl Into<String>,
space_id: impl Into<String>,
space_version: Option<String>,
strict: bool,
) -> FieldResult<Option<Self>> {
let id = id.into();
let space_id = space_id.into();

Ok(entity_node::find_one(neo4j, id)
.send()
.await?
.map(|node| Entity::new(node, space_id, space_version)))
.map(|node| Entity::new(node, space_id, space_version, strict)))
}
}

Expand All @@ -54,66 +63,84 @@ impl Entity {
/// Entity object
impl Entity {
/// Entity ID
fn id(&self) -> &str {
pub fn id(&self) -> &str {
&self.node.id
}

/// The space ID of the entity (note: the same entity can exist in multiple spaces)
pub fn space_id(&self) -> &str {
&self.space_id
}

pub fn created_at(&self) -> String {
self.node.system_properties.created_at.to_rfc3339()
}

pub fn created_at_block(&self) -> &str {
&self.node.system_properties.created_at_block
}

pub fn updated_at(&self) -> String {
self.node.system_properties.updated_at.to_rfc3339()
}

pub fn updated_at_block(&self) -> &str {
&self.node.system_properties.updated_at_block
}

/// Entity name (if available)
async fn name<'a, S: ScalarValue>(
pub async fn name<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
) -> Option<String> {
triple::find_one(
) -> FieldResult<Option<String>> {
Ok(property::get_triple(
&executor.context().0,
system_ids::NAME_ATTRIBUTE,
&self.node.id,
&self.space_id,
self.space_version.clone(),
self.strict,
)
.send()
.await
.expect("Failed to find name")
.map(|triple| triple.value.value)
.await?
.map(|triple| triple.value.value))
}

/// Entity description (if available)
async fn description<'a, S: ScalarValue>(
pub async fn description<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
) -> Option<String> {
triple::find_one(
) -> FieldResult<Option<String>> {
Ok(property::get_triple(
&executor.context().0,
system_ids::DESCRIPTION_ATTRIBUTE,
&self.node.id,
&self.space_id,
self.space_version.clone(),
self.strict,
)
.send()
.await
.expect("Failed to find name")
.map(|triple| triple.value.value)
.await?
.map(|triple| triple.value.value))
}

/// Entity cover (if available)
async fn cover<'a, S: ScalarValue>(
pub async fn cover<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
) -> Option<String> {
triple::find_one(
) -> FieldResult<Option<String>> {
Ok(property::get_triple(
&executor.context().0,
system_ids::COVER_ATTRIBUTE,
&self.node.id,
&self.space_id,
self.space_version.clone(),
self.strict,
)
.send()
.await
.expect("Failed to find name")
.map(|triple| triple.value.value)
.await?
.map(|triple| triple.value.value))
}

/// Entity blocks (if available)
async fn blocks<'a, S: ScalarValue>(
pub async fn blocks<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
) -> FieldResult<Vec<Entity>> {
Expand All @@ -136,13 +163,20 @@ impl Entity {
))
.send()
.await?
.map_ok(|node| Entity::new(node, self.space_id.clone(), self.space_version.clone()))
.map_ok(|node| {
Entity::new(
node,
self.space_id.clone(),
self.space_version.clone(),
self.strict,
)
})
.try_collect::<Vec<_>>()
.await?)
}

/// Types of the entity (which are entities themselves)
async fn types<'a, S: ScalarValue>(
pub async fn types<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
) -> FieldResult<Vec<Entity>> {
Expand All @@ -165,38 +199,24 @@ impl Entity {
))
.send()
.await?
.map_ok(|node| Entity::new(node, self.space_id.clone(), self.space_version.clone()))
.map_ok(|node| {
Entity::new(
node,
self.space_id.clone(),
self.space_version.clone(),
self.strict,
)
})
.try_collect::<Vec<_>>()
.await?)
}

/// The space ID of the entity (note: the same entity can exist in multiple spaces)
fn space_id(&self) -> &str {
&self.space_id
}

fn created_at(&self) -> String {
self.node.system_properties.created_at.to_rfc3339()
}

fn created_at_block(&self) -> &str {
&self.node.system_properties.created_at_block
}

fn updated_at(&self) -> String {
self.node.system_properties.updated_at.to_rfc3339()
}

fn updated_at_block(&self) -> &str {
&self.node.system_properties.updated_at_block
}

// TODO: Add entity attributes filtering
/// Attributes of the entity
async fn attributes<S: ScalarValue>(
pub async fn attributes<S: ScalarValue>(
&self,
_filter: Option<AttributeFilter>,
executor: &'_ Executor<'_, '_, KnowledgeGraph, S>,
_filter: Option<AttributeFilter>,
) -> FieldResult<Vec<Triple>> {
let mut query = triple::find_many(&executor.context().0)
.entity_id(prop_filter::value(&self.node.id))
Expand All @@ -215,10 +235,10 @@ impl Entity {
}

/// Relations outgoing from the entity
async fn relations<'a, S: ScalarValue>(
pub async fn relations<'a, S: ScalarValue>(
&'a self,
r#where: Option<EntityRelationFilter>,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
r#where: Option<EntityRelationFilter>,
) -> FieldResult<Vec<Relation>> {
let mut base_query = self.node.get_outbound_relations(
&executor.context().0,
Expand All @@ -234,15 +254,20 @@ impl Entity {
.send()
.await?
.map_ok(|relation| {
Relation::new(relation, self.space_id.clone(), self.space_version.clone())
Relation::new(
relation,
self.space_id.clone(),
self.space_version.clone(),
self.strict,
)
})
.try_collect::<Vec<_>>()
.await?)
}

// TODO: Add version filtering (e.g.: time range, edit author)
/// Versions of the entity, ordered chronologically
async fn versions<'a, S: ScalarValue>(
pub async fn versions<'a, S: ScalarValue>(
&'a self,
executor: &'a Executor<'_, '_, KnowledgeGraph, S>,
) -> FieldResult<Vec<EntityVersion>> {
Expand Down
10 changes: 5 additions & 5 deletions api/src/schema/entity_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use juniper::GraphQLInputObject;

use grc20_core::{
mapping::{
entity_node::{self},
self,
query_utils::{edge_filter::EdgeFilter, prop_filter, PropFilter},
relation_node,
},
Expand Down Expand Up @@ -65,8 +65,8 @@ impl EntityFilter {
filter
}

fn types_filter(&self) -> entity_node::EntityRelationFilter {
let mut filter = entity_node::EntityRelationFilter::default();
fn types_filter(&self) -> mapping::EntityRelationFilter {
let mut filter = mapping::EntityRelationFilter::default();

// if let Some(types) = &self.types {
// filter = filter.to_id(EdgeFilter::default().to_id(prop_filter::value_in(types.clone())));
Expand Down Expand Up @@ -97,10 +97,10 @@ impl EntityFilter {
}
}

impl From<EntityFilter> for entity_node::EntityFilter {
impl From<EntityFilter> for mapping::EntityFilter {
fn from(filter: EntityFilter) -> Self {
// TODO: Add types filter
entity_node::EntityFilter::default()
mapping::EntityFilter::default()
.id(filter.id_filter())
.relations(filter.types_filter())
.attributes(
Expand Down
5 changes: 5 additions & 0 deletions api/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,27 @@ pub mod entity;
pub mod entity_filter;
pub mod entity_order_by;
pub mod entity_version;
pub mod property;
pub mod query;
pub mod relation;
pub mod relation_filter;
pub mod schema_type;
pub mod space;
pub mod space_filter;
pub mod triple;
pub mod triple_filter;

pub use account::Account;
pub use account_filter::AccountFilter;
pub use attribute_filter::EntityAttributeFilter;
pub use entity::Entity;
pub use entity_filter::{AttributeFilter, EntityFilter, EntityRelationFilter};
pub use entity_version::EntityVersion;
pub use property::Property;
pub use query::RootQuery;
pub use relation::Relation;
pub use relation_filter::RelationFilter;
pub use schema_type::SchemaType;
pub use space::Space;
pub use space_filter::SpaceFilter;
pub use triple::Triple;
Loading