From 96d0ec3be753830e63c37d70f2981c5639971bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Wed, 18 Aug 2021 11:06:39 +0200 Subject: [PATCH] introduce the concept of a hierarchy root --- src/database/hierarchies.rs | 143 +++++++++++++++++------------------- 1 file changed, 68 insertions(+), 75 deletions(-) diff --git a/src/database/hierarchies.rs b/src/database/hierarchies.rs index e752478..b79f668 100644 --- a/src/database/hierarchies.rs +++ b/src/database/hierarchies.rs @@ -12,10 +12,18 @@ use crate::database::constants::{ HIER_ADDR, HIER_HAS_ATTR, HIER_INVARIANT, HIER_LABEL_ATTR, IS_OF_TYPE_ATTR, TYPE_ADDR, TYPE_HAS_ATTR, TYPE_ID_ATTR, }; -use crate::database::entry::{Entry, EntryValue}; +use crate::database::entry::{Entry, EntryValue, InvariantEntry}; use crate::database::lang::{EntryQuery, Query, QueryComponent, QueryPart}; use crate::database::{bulk_retrieve_objects, insert_entry, query, DbPool}; +lazy_static! { + static ref HIER_ROOT_INVARIANT: InvariantEntry = InvariantEntry { + attribute: String::from(HIER_LABEL_ATTR), + value: EntryValue::Value(Value::from("/")), + }; + static ref HIER_ROOT_INVARIANT_ADDR: Address = HIER_ROOT_INVARIANT.entity().unwrap(); +} + #[derive(Debug, Clone, PartialEq)] pub struct UNode(String); @@ -94,53 +102,49 @@ impl EntryList for Vec { } } -pub fn list_roots>(connection: &C) -> Result> { - let all_directories: Vec = query( - connection, - Query::SingleQuery(QueryPart::Matches(EntryQuery { - entity: QueryComponent::Any, - attribute: QueryComponent::Exact(IS_OF_TYPE_ATTR.to_string()), - value: QueryComponent::Exact(EntryValue::Address(HIER_ADDR.clone())), - })), - )?; - - let directories_with_parents: Vec
= query( - connection, - Query::SingleQuery(QueryPart::Matches(EntryQuery { - entity: QueryComponent::Any, - attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()), - value: QueryComponent::Any, - })), - )? - .extract_addresses(); - - Ok(all_directories - .into_iter() - .filter(|entry| !directories_with_parents.contains(&entry.entity)) - .map(|e| e.entity) - .collect()) -} +// pub fn list_orphans>(connection: &C) -> Result> { +// let all_directories: Vec = query( +// connection, +// Query::SingleQuery(QueryPart::Matches(EntryQuery { +// entity: QueryComponent::Any, +// attribute: QueryComponent::Exact(IS_OF_TYPE_ATTR.to_string()), +// value: QueryComponent::Exact(EntryValue::Address(HIER_ADDR.clone())), +// })), +// )?; +// +// let directories_with_parents: Vec
= query( +// connection, +// Query::SingleQuery(QueryPart::Matches(EntryQuery { +// entity: QueryComponent::Any, +// attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()), +// value: QueryComponent::Any, +// })), +// )? +// .extract_addresses(); +// +// Ok(all_directories +// .into_iter() +// .filter(|entry| !directories_with_parents.contains(&entry.entity)) +// .map(|e| e.entity) +// .collect()) +// } pub async fn list_node>( connection: &C, path: &UPath, ) -> Result> { - let entry_addresses = if path.0.is_empty() { - list_roots(connection)? - } else { - let resolved_path: Vec
= resolve_path(connection, path, false)?; - let last = resolved_path.last().unwrap(); + let resolved_path: Vec
= resolve_path(connection, path, false)?; + let last = resolved_path.last().unwrap(); - query( - connection, - Query::SingleQuery(QueryPart::Matches(EntryQuery { - entity: QueryComponent::Exact(last.clone()), - attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()), - value: QueryComponent::Any, - })), - )? - .extract_addresses() - }; + let entry_addresses = query( + connection, + Query::SingleQuery(QueryPart::Matches(EntryQuery { + entity: QueryComponent::Exact(last.clone()), + attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()), + value: QueryComponent::Any, + })), + )? + .extract_addresses(); Ok(bulk_retrieve_objects(connection, entry_addresses)? .into_iter() @@ -159,6 +163,8 @@ pub fn fetch_or_create_dir>( None => trace!("FETCHING/CREATING /{:#}", directory), } + let parent = parent.unwrap_or_else(|| HIER_ROOT_INVARIANT_ADDR.clone()); + let matching_directories: Vec
= query( connection, Query::SingleQuery(QueryPart::Matches(EntryQuery { @@ -173,31 +179,20 @@ pub fn fetch_or_create_dir>( .map(|e: Entry| e.entity) .collect(); - let valid_directories: Vec
= match parent.clone() { - Some(address) => { - let parent_has: Vec
= query( - connection, - Query::SingleQuery(QueryPart::Matches(EntryQuery { - entity: QueryComponent::Exact(address), - attribute: QueryComponent::Exact(String::from(HIER_HAS_ATTR)), - value: QueryComponent::Any, - })), - )? - .extract_addresses(); + let parent_has: Vec
= query( + connection, + Query::SingleQuery(QueryPart::Matches(EntryQuery { + entity: QueryComponent::Exact(parent.clone()), + attribute: QueryComponent::Exact(String::from(HIER_HAS_ATTR)), + value: QueryComponent::Any, + })), + )? + .extract_addresses(); - matching_directories - .into_iter() - .filter(|a| parent_has.contains(a)) - .collect() - } - None => { - let roots = list_roots(connection)?; - matching_directories - .into_iter() - .filter(|a| roots.contains(a)) - .collect() - } - }; + let valid_directories: Vec
= matching_directories + .into_iter() + .filter(|a| parent_has.contains(a)) + .collect(); match valid_directories.len() { 0 => { @@ -217,14 +212,12 @@ pub fn fetch_or_create_dir>( }; insert_entry(connection, directory_entry)?; - if let Some(parent_addr) = parent { - let has_entry = Entry { - entity: parent_addr, - attribute: String::from(HIER_HAS_ATTR), - value: EntryValue::Address(new_directory_address.clone()), - }; - insert_entry(connection, has_entry)?; - } + let has_entry = Entry { + entity: parent, + attribute: String::from(HIER_HAS_ATTR), + value: EntryValue::Address(new_directory_address.clone()), + }; + insert_entry(connection, has_entry)?; Ok(new_directory_address) } else { @@ -243,7 +236,7 @@ pub fn resolve_path>( path: &UPath, create: bool, ) -> Result> { - let mut result: Vec
= vec![]; + let mut result: Vec
= vec![HIER_ROOT_INVARIANT_ADDR.clone()]; let mut path_stack = path.0.to_vec(); path_stack.reverse();