From 00cac1bca120b84b29fa0b9fe6648bb886c2b5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Ml=C3=A1dek?= Date: Fri, 29 Oct 2021 18:05:03 +0200 Subject: [PATCH] [db/ui] remove instantiations, use plain relations with aliases instead --- src/filesystem.rs | 81 +++++++---------------------------- ui/src/components/Address.vue | 4 +- ui/src/lib/entity.ts | 36 +++++++++++++++- ui/src/views/Inspect.vue | 22 ---------- 4 files changed, 52 insertions(+), 91 deletions(-) diff --git a/src/filesystem.rs b/src/filesystem.rs index 36eaf9a..f5a6c62 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -24,7 +24,6 @@ use log::{error, info, warn}; use once_cell::unsync::Lazy; use rayon::prelude::*; use serde_json::Value; -use uuid::Uuid; use walkdir::WalkDir; const DIR_TYPE: &str = "FS_DIR"; @@ -38,9 +37,7 @@ lazy_static! { } const BLOB_TYPE: &str = "BLOB"; -const FILE_TYPE: &str = "FS_FILE"; -const FILE_IDENTITY_KEY: &str = "FILE_IS"; -const FILENAME_KEY: &str = "FILE_NAME"; +const ALIAS_KEY: &str = "ALIAS"; const FILE_MIME_KEY: &str = "FILE_MIME"; const FILE_MTIME_KEY: &str = "FILE_MTIME"; const FILE_SIZE_KEY: &str = "FILE_SIZE"; @@ -50,11 +47,6 @@ lazy_static! { value: EntryValue::Value(Value::from(BLOB_TYPE)), }; static ref BLOB_TYPE_ADDR: Address = BLOB_TYPE_INVARIANT.entity().unwrap(); - static ref FILE_TYPE_INVARIANT: InvariantEntry = InvariantEntry { - attribute: String::from(TYPE_IS_ATTR), - value: EntryValue::Value(Value::from(FILE_TYPE)), - }; - static ref FILE_TYPE_ADDR: Address = FILE_TYPE_INVARIANT.entity().unwrap(); } fn initialize_types(pool: &DbPool) -> Result<()> { @@ -65,24 +57,6 @@ fn initialize_types(pool: &DbPool) -> Result<()> { upend_insert_val!(&pool.get()?, BLOB_TYPE_ADDR, TYPE_HAS_ATTR, FILE_SIZE_KEY); upend_insert_val!(&pool.get()?, BLOB_TYPE_ADDR, TYPE_HAS_ATTR, FILE_MIME_KEY); - // FILE_TYPE - insert_entry(&pool.get()?, Entry::try_from(&*FILE_TYPE_INVARIANT)?)?; - upend_insert_addr!(&pool.get()?, FILE_TYPE_ADDR, IS_OF_TYPE_ATTR, TYPE_ADDR); - upend_insert_val!( - &pool.get()?, - FILE_TYPE_ADDR, - TYPE_INSTANCES_ATTR, - FILE_IDENTITY_KEY - ); - upend_insert_val!(&pool.get()?, FILE_TYPE_ADDR, TYPE_ID_ATTR, FILENAME_KEY); - upend_insert_val!( - &pool.get()?, - FILE_TYPE_ADDR, - TYPE_REQUIRES_ATTR, - FILE_IDENTITY_KEY - ); - upend_insert_val!(&pool.get()?, FILE_TYPE_ADDR, TYPE_HAS_ATTR, FILE_MIME_KEY); - // DIR_TYPE insert_entry(&pool.get()?, Entry::try_from(&*DIR_TYPE_INVARIANT)?)?; upend_insert_addr!(&pool.get()?, DIR_TYPE_ADDR, IS_OF_TYPE_ATTR, TYPE_ADDR); @@ -240,7 +214,7 @@ fn _process_directory_entry>( let normalized_path = path.strip_prefix(&directory_path)?; let normalized_path_str = normalized_path.to_str().expect("path not valid unicode?!"); - let digest = Lazy::new(|| path.hash()); + let file_hash = Lazy::new(|| path.hash()); // Get size & mtime for quick comparison let metadata = fs::metadata(&path)?; @@ -267,7 +241,7 @@ fn _process_directory_entry>( if let Some((idx, existing_file)) = maybe_existing_file { if (size == existing_file.size && mtime == existing_file.mtime) - || ((*digest).is_ok() && &existing_file.hash == (*digest).as_ref().unwrap()) + || ((*file_hash).is_ok() && &existing_file.hash == (*file_hash).as_ref().unwrap()) { if !existing_file.valid { file_set_valid(&db_pool.write().unwrap().get()?, existing_file.id, true)?; @@ -279,14 +253,14 @@ fn _process_directory_entry>( } // If not, add it! - if let Err(err) = &*digest { + if let Err(err) = &*file_hash { return Err(anyhow!(format!("Error hashing: {}", err))); } - let digest = (*digest).as_ref().unwrap().clone(); + let file_hash = (*file_hash).as_ref().unwrap().clone(); let new_file = models::NewFile { path: normalized_path_str.to_string(), - hash: (digest.clone()).0, + hash: (file_hash.clone()).0, added: NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0), size, mtime, @@ -296,29 +270,21 @@ fn _process_directory_entry>( // Insert metadata let type_entry = Entry { - entity: Address::Hash(digest.clone()), + entity: Address::Hash(file_hash.clone()), attribute: String::from(IS_OF_TYPE_ATTR), value: EntryValue::Address(BLOB_TYPE_ADDR.clone()), }; insert_entry(&db_pool.write().unwrap().get()?, type_entry)?; let size_entry = Entry { - entity: Address::Hash(digest.clone()), + entity: Address::Hash(file_hash.clone()), attribute: FILE_SIZE_KEY.to_string(), value: EntryValue::Value(Value::from(size)), }; insert_entry(&db_pool.write().unwrap().get()?, size_entry)?; - if let Some(mtime) = mtime { - let mtime_entry = Entry { - entity: Address::Hash(digest.clone()), - attribute: FILE_MTIME_KEY.to_string(), - value: EntryValue::Value(Value::from(mtime.timestamp())), - }; - insert_entry(&db_pool.write().unwrap().get()?, mtime_entry)?; - } let mime_entry = Entry { - entity: Address::Hash(digest.clone()), + entity: Address::Hash(file_hash.clone()), attribute: FILE_MIME_KEY.to_string(), value: EntryValue::Value(Value::String(tree_magic::from_filepath(&path))), }; @@ -341,37 +307,22 @@ fn _process_directory_entry>( let _pool = &db_pool.write().unwrap(); let connection = _pool.get()?; connection.transaction::<_, Error, _>(|| { - let file_address = Address::Uuid(Uuid::new_v4()); - let type_entry = Entry { - entity: file_address.clone(), - attribute: String::from(IS_OF_TYPE_ATTR), - value: EntryValue::Address(FILE_TYPE_ADDR.clone()), + let dir_has_entry = Entry { + entity: parent_dir.clone(), + attribute: HIER_HAS_ATTR.to_string(), + value: EntryValue::Address(Address::Hash(file_hash.clone())), }; - insert_entry(&connection, type_entry)?; + let dir_has_entry_addr = insert_entry(&connection, dir_has_entry)?; let name_entry = Entry { - entity: file_address.clone(), - attribute: FILENAME_KEY.to_string(), + entity: dir_has_entry_addr, + attribute: ALIAS_KEY.to_string(), value: EntryValue::Value(Value::String( filename.as_os_str().to_string_lossy().to_string(), )), }; insert_entry(&connection, name_entry)?; - let identity_entry = Entry { - entity: file_address.clone(), - attribute: FILE_IDENTITY_KEY.to_string(), - value: EntryValue::Address(Address::Hash(digest.clone())), - }; - insert_entry(&connection, identity_entry)?; - - let dir_has_entry = Entry { - entity: parent_dir.clone(), - attribute: HIER_HAS_ATTR.to_string(), - value: EntryValue::Address(file_address), - }; - insert_entry(&connection, dir_has_entry)?; - Ok(UpdatePathOutcome::Added(path.clone())) }) } diff --git a/ui/src/components/Address.vue b/ui/src/components/Address.vue index edec674..84cd717 100644 --- a/ui/src/components/Address.vue +++ b/ui/src/components/Address.vue @@ -47,8 +47,8 @@ export default defineComponent({ }, setup(props) { // Identification - const { attributes } = useEntity(props.address, () => props.resolve); - const inferredEntries = identify(attributes); + const { attributes, backlinks } = useEntity(props.address, () => props.resolve); + const inferredEntries = identify(attributes, backlinks); const inferredIds: ComputedRef = computed(() => { return inferredEntries.value.map((eid) => eid.value); }); diff --git a/ui/src/lib/entity.ts b/ui/src/lib/entity.ts index a73fa1f..d6c630b 100644 --- a/ui/src/lib/entity.ts +++ b/ui/src/lib/entity.ts @@ -87,8 +87,32 @@ interface EntityIdentification { } export function identify( - attributes: ComputedRef<[string, IEntry][]> + attributes: ComputedRef<[string, IEntry][]>, + backlinks: ComputedRef<[string, IEntry][]> ): ComputedRef { + // Get all entries where the object is linked + const hasEntries = computed(() => { + return backlinks.value + .filter(([_, entry]) => entry.attribute === "HAS") + .map(([addr, _]) => addr); + }); + + // Out of those relations, retrieve their ALIAS attrs + const { data: hasListing } = query(() => { + return ( + hasEntries.value && + `(matches (in ${hasEntries.value + .map(e => `"${e}"`) + .join(" ")}) "ALIAS" ?)` + ); + }); + + const aliasValues: ComputedRef = computed(() => { + return Object.values(hasListing.value || {}).map(entry => { + return entry.value.c; + }); + }); + // Get all identities of the object const isEntries = computed(() => { return attributes.value @@ -128,7 +152,15 @@ export function identify( }; }); }) - .flat(); + .flat() + .concat( + aliasValues.value.map(value => { + return { + type: "ALIAS", + value + }; + }) + ); }); } diff --git a/ui/src/views/Inspect.vue b/ui/src/views/Inspect.vue index e4951c2..e396a76 100644 --- a/ui/src/views/Inspect.vue +++ b/ui/src/views/Inspect.vue @@ -36,17 +36,6 @@
{{ error }}
- @@ -158,16 +147,6 @@ export default defineComponent({ ); }); - const referredAddress = computed(() => { - const fileIsAttr = attributes.value.find( - ([_, entry]) => entry.attribute === "FILE_IS" - )?.[1]; - - if (fileIsAttr) { - return fileIsAttr.value.c; - } - }); - return { typedAttributes, untypedAttributes: filteredUntypedAttributes, @@ -175,7 +154,6 @@ export default defineComponent({ error, mutate, types: allTypes, - referredAddress, }; }, });