introduce the concept of a hierarchy root
parent
2944ce3d81
commit
96d0ec3be7
|
@ -12,10 +12,18 @@ use crate::database::constants::{
|
||||||
HIER_ADDR, HIER_HAS_ATTR, HIER_INVARIANT, HIER_LABEL_ATTR, IS_OF_TYPE_ATTR, TYPE_ADDR,
|
HIER_ADDR, HIER_HAS_ATTR, HIER_INVARIANT, HIER_LABEL_ATTR, IS_OF_TYPE_ATTR, TYPE_ADDR,
|
||||||
TYPE_HAS_ATTR, TYPE_ID_ATTR,
|
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::lang::{EntryQuery, Query, QueryComponent, QueryPart};
|
||||||
use crate::database::{bulk_retrieve_objects, insert_entry, query, DbPool};
|
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)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct UNode(String);
|
pub struct UNode(String);
|
||||||
|
|
||||||
|
@ -94,53 +102,49 @@ impl EntryList for Vec<Entry> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_roots<C: Connection<Backend = Sqlite>>(connection: &C) -> Result<Vec<Address>> {
|
// pub fn list_orphans<C: Connection<Backend = Sqlite>>(connection: &C) -> Result<Vec<Address>> {
|
||||||
let all_directories: Vec<Entry> = query(
|
// let all_directories: Vec<Entry> = query(
|
||||||
connection,
|
// connection,
|
||||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
// Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||||
entity: QueryComponent::Any,
|
// entity: QueryComponent::Any,
|
||||||
attribute: QueryComponent::Exact(IS_OF_TYPE_ATTR.to_string()),
|
// attribute: QueryComponent::Exact(IS_OF_TYPE_ATTR.to_string()),
|
||||||
value: QueryComponent::Exact(EntryValue::Address(HIER_ADDR.clone())),
|
// value: QueryComponent::Exact(EntryValue::Address(HIER_ADDR.clone())),
|
||||||
})),
|
// })),
|
||||||
)?;
|
// )?;
|
||||||
|
//
|
||||||
let directories_with_parents: Vec<Address> = query(
|
// let directories_with_parents: Vec<Address> = query(
|
||||||
connection,
|
// connection,
|
||||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
// Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||||
entity: QueryComponent::Any,
|
// entity: QueryComponent::Any,
|
||||||
attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()),
|
// attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()),
|
||||||
value: QueryComponent::Any,
|
// value: QueryComponent::Any,
|
||||||
})),
|
// })),
|
||||||
)?
|
// )?
|
||||||
.extract_addresses();
|
// .extract_addresses();
|
||||||
|
//
|
||||||
Ok(all_directories
|
// Ok(all_directories
|
||||||
.into_iter()
|
// .into_iter()
|
||||||
.filter(|entry| !directories_with_parents.contains(&entry.entity))
|
// .filter(|entry| !directories_with_parents.contains(&entry.entity))
|
||||||
.map(|e| e.entity)
|
// .map(|e| e.entity)
|
||||||
.collect())
|
// .collect())
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub async fn list_node<C: Connection<Backend = Sqlite>>(
|
pub async fn list_node<C: Connection<Backend = Sqlite>>(
|
||||||
connection: &C,
|
connection: &C,
|
||||||
path: &UPath,
|
path: &UPath,
|
||||||
) -> Result<Vec<Entry>> {
|
) -> Result<Vec<Entry>> {
|
||||||
let entry_addresses = if path.0.is_empty() {
|
let resolved_path: Vec<Address> = resolve_path(connection, path, false)?;
|
||||||
list_roots(connection)?
|
let last = resolved_path.last().unwrap();
|
||||||
} else {
|
|
||||||
let resolved_path: Vec<Address> = resolve_path(connection, path, false)?;
|
|
||||||
let last = resolved_path.last().unwrap();
|
|
||||||
|
|
||||||
query(
|
let entry_addresses = query(
|
||||||
connection,
|
connection,
|
||||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||||
entity: QueryComponent::Exact(last.clone()),
|
entity: QueryComponent::Exact(last.clone()),
|
||||||
attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()),
|
attribute: QueryComponent::Exact(HIER_HAS_ATTR.to_string()),
|
||||||
value: QueryComponent::Any,
|
value: QueryComponent::Any,
|
||||||
})),
|
})),
|
||||||
)?
|
)?
|
||||||
.extract_addresses()
|
.extract_addresses();
|
||||||
};
|
|
||||||
|
|
||||||
Ok(bulk_retrieve_objects(connection, entry_addresses)?
|
Ok(bulk_retrieve_objects(connection, entry_addresses)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -159,6 +163,8 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
||||||
None => trace!("FETCHING/CREATING /{:#}", directory),
|
None => trace!("FETCHING/CREATING /{:#}", directory),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let parent = parent.unwrap_or_else(|| HIER_ROOT_INVARIANT_ADDR.clone());
|
||||||
|
|
||||||
let matching_directories: Vec<Address> = query(
|
let matching_directories: Vec<Address> = query(
|
||||||
connection,
|
connection,
|
||||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||||
|
@ -173,31 +179,20 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
||||||
.map(|e: Entry| e.entity)
|
.map(|e: Entry| e.entity)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let valid_directories: Vec<Address> = match parent.clone() {
|
let parent_has: Vec<Address> = query(
|
||||||
Some(address) => {
|
connection,
|
||||||
let parent_has: Vec<Address> = query(
|
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||||
connection,
|
entity: QueryComponent::Exact(parent.clone()),
|
||||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
attribute: QueryComponent::Exact(String::from(HIER_HAS_ATTR)),
|
||||||
entity: QueryComponent::Exact(address),
|
value: QueryComponent::Any,
|
||||||
attribute: QueryComponent::Exact(String::from(HIER_HAS_ATTR)),
|
})),
|
||||||
value: QueryComponent::Any,
|
)?
|
||||||
})),
|
.extract_addresses();
|
||||||
)?
|
|
||||||
.extract_addresses();
|
|
||||||
|
|
||||||
matching_directories
|
let valid_directories: Vec<Address> = matching_directories
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|a| parent_has.contains(a))
|
.filter(|a| parent_has.contains(a))
|
||||||
.collect()
|
.collect();
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let roots = list_roots(connection)?;
|
|
||||||
matching_directories
|
|
||||||
.into_iter()
|
|
||||||
.filter(|a| roots.contains(a))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match valid_directories.len() {
|
match valid_directories.len() {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -217,14 +212,12 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
||||||
};
|
};
|
||||||
insert_entry(connection, directory_entry)?;
|
insert_entry(connection, directory_entry)?;
|
||||||
|
|
||||||
if let Some(parent_addr) = parent {
|
let has_entry = Entry {
|
||||||
let has_entry = Entry {
|
entity: parent,
|
||||||
entity: parent_addr,
|
attribute: String::from(HIER_HAS_ATTR),
|
||||||
attribute: String::from(HIER_HAS_ATTR),
|
value: EntryValue::Address(new_directory_address.clone()),
|
||||||
value: EntryValue::Address(new_directory_address.clone()),
|
};
|
||||||
};
|
insert_entry(connection, has_entry)?;
|
||||||
insert_entry(connection, has_entry)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(new_directory_address)
|
Ok(new_directory_address)
|
||||||
} else {
|
} else {
|
||||||
|
@ -243,7 +236,7 @@ pub fn resolve_path<C: Connection<Backend = Sqlite>>(
|
||||||
path: &UPath,
|
path: &UPath,
|
||||||
create: bool,
|
create: bool,
|
||||||
) -> Result<Vec<Address>> {
|
) -> Result<Vec<Address>> {
|
||||||
let mut result: Vec<Address> = vec![];
|
let mut result: Vec<Address> = vec![HIER_ROOT_INVARIANT_ADDR.clone()];
|
||||||
let mut path_stack = path.0.to_vec();
|
let mut path_stack = path.0.to_vec();
|
||||||
|
|
||||||
path_stack.reverse();
|
path_stack.reverse();
|
||||||
|
|
Loading…
Reference in New Issue