introduce the concept of a hierarchy root
This commit is contained in:
parent
2944ce3d81
commit
96d0ec3be7
1 changed files with 68 additions and 75 deletions
|
@ -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,44 +102,41 @@ impl EntryList for Vec<Entry> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn list_roots<C: Connection<Backend = Sqlite>>(connection: &C) -> Result<Vec<Address>> {
|
||||
let all_directories: Vec<Entry> = 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<Address> = 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<C: Connection<Backend = Sqlite>>(connection: &C) -> Result<Vec<Address>> {
|
||||
// let all_directories: Vec<Entry> = 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<Address> = 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<C: Connection<Backend = Sqlite>>(
|
||||
connection: &C,
|
||||
path: &UPath,
|
||||
) -> Result<Vec<Entry>> {
|
||||
let entry_addresses = if path.0.is_empty() {
|
||||
list_roots(connection)?
|
||||
} else {
|
||||
let resolved_path: Vec<Address> = resolve_path(connection, path, false)?;
|
||||
let last = resolved_path.last().unwrap();
|
||||
|
||||
query(
|
||||
let entry_addresses = query(
|
||||
connection,
|
||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||
entity: QueryComponent::Exact(last.clone()),
|
||||
|
@ -139,8 +144,7 @@ pub async fn list_node<C: Connection<Backend = Sqlite>>(
|
|||
value: QueryComponent::Any,
|
||||
})),
|
||||
)?
|
||||
.extract_addresses()
|
||||
};
|
||||
.extract_addresses();
|
||||
|
||||
Ok(bulk_retrieve_objects(connection, entry_addresses)?
|
||||
.into_iter()
|
||||
|
@ -159,6 +163,8 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
|||
None => trace!("FETCHING/CREATING /{:#}", directory),
|
||||
}
|
||||
|
||||
let parent = parent.unwrap_or_else(|| HIER_ROOT_INVARIANT_ADDR.clone());
|
||||
|
||||
let matching_directories: Vec<Address> = query(
|
||||
connection,
|
||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||
|
@ -173,31 +179,20 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
|||
.map(|e: Entry| e.entity)
|
||||
.collect();
|
||||
|
||||
let valid_directories: Vec<Address> = match parent.clone() {
|
||||
Some(address) => {
|
||||
let parent_has: Vec<Address> = query(
|
||||
connection,
|
||||
Query::SingleQuery(QueryPart::Matches(EntryQuery {
|
||||
entity: QueryComponent::Exact(address),
|
||||
entity: QueryComponent::Exact(parent.clone()),
|
||||
attribute: QueryComponent::Exact(String::from(HIER_HAS_ATTR)),
|
||||
value: QueryComponent::Any,
|
||||
})),
|
||||
)?
|
||||
.extract_addresses();
|
||||
|
||||
matching_directories
|
||||
let valid_directories: Vec<Address> = 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()
|
||||
}
|
||||
};
|
||||
.collect();
|
||||
|
||||
match valid_directories.len() {
|
||||
0 => {
|
||||
|
@ -217,14 +212,12 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
|||
};
|
||||
insert_entry(connection, directory_entry)?;
|
||||
|
||||
if let Some(parent_addr) = parent {
|
||||
let has_entry = Entry {
|
||||
entity: parent_addr,
|
||||
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<C: Connection<Backend = Sqlite>>(
|
|||
path: &UPath,
|
||||
create: bool,
|
||||
) -> 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();
|
||||
|
||||
path_stack.reverse();
|
||||
|
|
Loading…
Reference in a new issue