TYPE_ID attr, type of TYPE

(todo: clean up, deduplicate code...)
feat/vaults
Tomáš Mládek 2021-03-18 23:59:55 +01:00
parent 0f006ea32c
commit b773dbc49c
2 changed files with 99 additions and 36 deletions

View File

@ -25,9 +25,19 @@ use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
pub const TYPE_ATTR: &str = "TYPE"; pub const TYPE_TYPE: &str = "TYPE";
pub const TYPE_HAS_ATTR: &str = "TYPE_HAS"; pub const TYPE_IS_ATTR: &str = "TYPE";
pub const IS_TYPE_ATTR: &str = "IS"; pub const TYPE_REQUIRES_ATTR: &str = "TYPE_REQUIRES";
pub const TYPE_ID_ATTR: &str = "TYPE_ID";
pub const IS_OF_TYPE_ATTR: &str = "IS";
lazy_static! {
static ref TYPE_INVARIANT: InvariantEntry = InvariantEntry {
attribute: String::from(TYPE_IS_ATTR),
value: EntryValue::Value(serde_json::Value::from(TYPE_TYPE)),
};
pub static ref TYPE_ADDR: Address = TYPE_INVARIANT.entity().unwrap();
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry { pub struct Entry {
@ -712,5 +722,29 @@ pub fn open_upend<P: AsRef<Path>>(dirpath: P, reinitialize: bool) -> Result<Open
}, },
)?; )?;
initialize_types(&pool)?;
Ok(OpenResult { pool, new }) Ok(OpenResult { pool, new })
} }
fn initialize_types(pool: &DbPool) -> Result<()> {
insert_entry(&pool.get()?, Entry::try_from(&*TYPE_INVARIANT)?)?;
insert_entry(
&pool.get()?,
Entry {
entity: TYPE_ADDR.clone(),
attribute: String::from(IS_OF_TYPE_ATTR),
value: EntryValue::Address(TYPE_ADDR.clone()),
},
)?;
insert_entry(
&pool.get()?,
Entry {
entity: TYPE_ADDR.clone(),
attribute: String::from(TYPE_ID_ATTR),
value: EntryValue::Value(serde_json::Value::from(TYPE_IS_ATTR)),
},
)?;
Ok(())
}

View File

@ -1,9 +1,3 @@
use std::convert::TryFrom;
use std::path::{Component, Path, PathBuf};
use std::sync::{Arc, RwLock};
use std::time::{Instant, UNIX_EPOCH};
use std::{fs, iter};
use anyhow::{anyhow, Error, Result}; use anyhow::{anyhow, Error, Result};
use chrono::prelude::*; use chrono::prelude::*;
use diesel::sqlite::Sqlite; use diesel::sqlite::Sqlite;
@ -11,14 +5,19 @@ use diesel::Connection;
use log::{error, info, trace}; use log::{error, info, trace};
use rayon::prelude::*; use rayon::prelude::*;
use serde_json::Value; use serde_json::Value;
use std::convert::TryFrom;
use std::path::{Component, Path, PathBuf};
use std::sync::{Arc, RwLock};
use std::time::{Instant, UNIX_EPOCH};
use std::{fs, iter};
use uuid::Uuid; use uuid::Uuid;
use walkdir::WalkDir; use walkdir::WalkDir;
use crate::addressing::Address; use crate::addressing::Address;
use crate::database::{ use crate::database::{
bulk_retrieve_objects, file_set_valid, insert_entry, insert_file, query, retrieve_all_files, bulk_retrieve_objects, file_set_valid, insert_entry, insert_file, query, retrieve_all_files,
Addressable, DbPool, Entry, EntryQuery, EntryValue, InvariantEntry, Query, QueryComponent, DbPool, Entry, EntryQuery, EntryValue, InvariantEntry, Query, QueryComponent, QueryPart,
QueryPart, DATABASE_FILENAME, IS_TYPE_ATTR, TYPE_ATTR, TYPE_HAS_ATTR, DATABASE_FILENAME, IS_OF_TYPE_ATTR, TYPE_ADDR, TYPE_ID_ATTR, TYPE_IS_ATTR, TYPE_REQUIRES_ATTR,
}; };
use crate::hash::Hashable; use crate::hash::Hashable;
use crate::jobs::{Job, JobContainer, JobId}; use crate::jobs::{Job, JobContainer, JobId};
@ -30,7 +29,7 @@ const DIR_KEY: &str = "DIR";
const DIR_HAS_KEY: &str = "DIR_HAS"; const DIR_HAS_KEY: &str = "DIR_HAS";
lazy_static! { lazy_static! {
static ref DIR_TYPE_INVARIANT: InvariantEntry = InvariantEntry { static ref DIR_TYPE_INVARIANT: InvariantEntry = InvariantEntry {
attribute: String::from(TYPE_ATTR), attribute: String::from(TYPE_IS_ATTR),
value: EntryValue::Value(Value::from(DIR_TYPE)), value: EntryValue::Value(Value::from(DIR_TYPE)),
}; };
static ref DIR_TYPE_ADDR: Address = DIR_TYPE_INVARIANT.entity().unwrap(); static ref DIR_TYPE_ADDR: Address = DIR_TYPE_INVARIANT.entity().unwrap();
@ -41,12 +40,62 @@ const FILE_IDENTITY_KEY: &str = "FILE_IS";
const FILENAME_KEY: &str = "FILE_NAME"; const FILENAME_KEY: &str = "FILE_NAME";
lazy_static! { lazy_static! {
static ref FILE_TYPE_INVARIANT: InvariantEntry = InvariantEntry { static ref FILE_TYPE_INVARIANT: InvariantEntry = InvariantEntry {
attribute: String::from(TYPE_ATTR), attribute: String::from(TYPE_IS_ATTR),
value: EntryValue::Value(Value::from(FILE_TYPE)), value: EntryValue::Value(Value::from(FILE_TYPE)),
}; };
static ref FILE_TYPE_ADDR: Address = FILE_TYPE_INVARIANT.entity().unwrap(); static ref FILE_TYPE_ADDR: Address = FILE_TYPE_INVARIANT.entity().unwrap();
} }
fn initialize_types(pool: &DbPool) -> Result<()> {
// FILE_TYPE
insert_entry(&pool.get()?, Entry::try_from(&*FILE_TYPE_INVARIANT)?)?;
insert_entry(
&pool.get()?,
Entry {
entity: FILE_TYPE_ADDR.clone(),
attribute: String::from(IS_OF_TYPE_ATTR),
value: EntryValue::Address(TYPE_ADDR.clone()),
},
)?;
insert_entry(
&pool.get()?,
Entry {
entity: FILE_TYPE_ADDR.clone(),
attribute: String::from(TYPE_ID_ATTR),
value: EntryValue::Value(Value::from(FILENAME_KEY)),
},
)?;
insert_entry(
&pool.get()?,
Entry {
entity: FILE_TYPE_ADDR.clone(),
attribute: String::from(TYPE_REQUIRES_ATTR),
value: EntryValue::Value(Value::from(FILE_IDENTITY_KEY)),
},
)?;
// DIR_TYPE
insert_entry(&pool.get()?, Entry::try_from(&*DIR_TYPE_INVARIANT)?)?;
insert_entry(
&pool.get()?,
Entry {
entity: DIR_TYPE_ADDR.clone(),
attribute: String::from(IS_OF_TYPE_ATTR),
value: EntryValue::Address(TYPE_ADDR.clone()),
},
)?;
insert_entry(
&pool.get()?,
Entry {
entity: DIR_TYPE_ADDR.clone(),
attribute: String::from(TYPE_ID_ATTR),
value: EntryValue::Value(Value::from(DIR_KEY)),
},
)?;
Ok(())
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct UDirectory { pub struct UDirectory {
name: String, name: String,
@ -256,7 +305,7 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
let new_directory_address = Address::UUID(Uuid::new_v4()); let new_directory_address = Address::UUID(Uuid::new_v4());
let type_entry = Entry { let type_entry = Entry {
entity: new_directory_address.clone(), entity: new_directory_address.clone(),
attribute: String::from(IS_TYPE_ATTR), attribute: String::from(IS_OF_TYPE_ATTR),
value: EntryValue::Address(DIR_TYPE_ADDR.clone()), value: EntryValue::Address(DIR_TYPE_ADDR.clone()),
}; };
insert_entry(connection, type_entry)?; insert_entry(connection, type_entry)?;
@ -347,27 +396,7 @@ fn _rescan_vault<T: AsRef<Path>>(
let start = Instant::now(); let start = Instant::now();
// Initialize types, etc... // Initialize types, etc...
insert_entry(&pool.get()?, Entry::try_from(&*FILE_TYPE_INVARIANT)?)?; initialize_types(&pool)?;
for attr in &[FILE_IDENTITY_KEY, FILENAME_KEY] {
insert_entry(
&pool.get()?,
Entry {
entity: FILE_TYPE_ADDR.clone(),
attribute: String::from(TYPE_HAS_ATTR),
value: EntryValue::Value(Value::from(*attr)),
},
)?;
}
insert_entry(&pool.get()?, Entry::try_from(&*DIR_TYPE_INVARIANT)?)?;
insert_entry(
&pool.get()?,
Entry {
entity: DIR_TYPE_ADDR.clone(),
attribute: String::from(TYPE_HAS_ATTR),
value: EntryValue::Value(Value::from(DIR_KEY)),
},
)?;
// Walk through the vault, find all paths // Walk through the vault, find all paths
let path_entries: Vec<PathBuf> = WalkDir::new(&directory) let path_entries: Vec<PathBuf> = WalkDir::new(&directory)
@ -509,7 +538,7 @@ fn _process_directory_entry<P: AsRef<Path>>(
let file_address = Address::UUID(Uuid::new_v4()); let file_address = Address::UUID(Uuid::new_v4());
let type_entry = Entry { let type_entry = Entry {
entity: file_address.clone(), entity: file_address.clone(),
attribute: String::from(IS_TYPE_ATTR), attribute: String::from(IS_OF_TYPE_ATTR),
value: EntryValue::Address(FILE_TYPE_ADDR.clone()), value: EntryValue::Address(FILE_TYPE_ADDR.clone()),
}; };
insert_entry(&connection, type_entry)?; insert_entry(&connection, type_entry)?;