refer to types via address, not identifier
also rework invariant entries, add addressable traitfeat/vaults
parent
2c5a824d4a
commit
2ffbd4934b
|
@ -1444,9 +1444,9 @@ checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.5.2"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
|
@ -2261,6 +2261,7 @@ dependencies = [
|
|||
"env_logger",
|
||||
"filebuffer",
|
||||
"futures-util",
|
||||
"lazy_static",
|
||||
"lexpr",
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
|
|
|
@ -17,6 +17,7 @@ thiserror = "1.0"
|
|||
|
||||
rayon = "1.4.0"
|
||||
futures-util = "~0.3.12"
|
||||
lazy_static = "1.4.0"
|
||||
|
||||
diesel = { version = "1.4", features = ["sqlite", "r2d2", "chrono", "serde_json"] }
|
||||
diesel_migrations = "1.4"
|
||||
|
|
|
@ -36,6 +36,12 @@ pub struct Entry {
|
|||
pub value: EntryValue,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct InvariantEntry {
|
||||
pub attribute: String,
|
||||
pub value: EntryValue,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "t", content = "c")]
|
||||
pub enum EntryValue {
|
||||
|
@ -69,6 +75,22 @@ impl TryFrom<&Entry> for models::Entry {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&InvariantEntry> for Entry {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(invariant: &InvariantEntry) -> Result<Self, Self::Error> {
|
||||
let mut entity = Cursor::new(vec![0u8; 0]);
|
||||
entity.write_all(invariant.attribute.as_bytes())?;
|
||||
entity.write_all(invariant.value.to_string()?.as_bytes())?;
|
||||
|
||||
Ok(Entry {
|
||||
entity: Address::Hash(Hash(entity.into_inner())),
|
||||
attribute: invariant.attribute.clone(),
|
||||
value: invariant.value.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Entry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} | {} | {}", self.entity, self.attribute, self.value)
|
||||
|
@ -85,12 +107,21 @@ impl Hashable for Entry {
|
|||
}
|
||||
}
|
||||
|
||||
impl Entry {
|
||||
pub fn address(&self) -> Result<Address> {
|
||||
impl Hashable for InvariantEntry {
|
||||
fn hash(&self) -> Result<Hash> {
|
||||
Entry::try_from(self)?.hash()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Addressable: Hashable {
|
||||
fn address(&self) -> Result<Address> {
|
||||
Ok(Address::Hash(self.hash()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Addressable for Entry {}
|
||||
impl Addressable for InvariantEntry {}
|
||||
|
||||
impl EntryValue {
|
||||
pub fn to_string(&self) -> Result<String> {
|
||||
let (type_char, content) = match self {
|
||||
|
@ -618,20 +649,9 @@ pub fn insert_entry<C: Connection<Backend = Sqlite>>(
|
|||
|
||||
pub fn ensure_invariant<C: Connection<Backend = Sqlite>>(
|
||||
connection: &C,
|
||||
attribute: String,
|
||||
value: EntryValue,
|
||||
invariant: &InvariantEntry,
|
||||
) -> Result<Address> {
|
||||
let mut entity = Cursor::new(vec![0u8; 0]);
|
||||
entity.write_all(attribute.as_bytes())?;
|
||||
entity.write_all(value.to_string()?.as_bytes())?;
|
||||
|
||||
let entry = Entry {
|
||||
entity: Address::Hash(Hash(entity.into_inner())),
|
||||
attribute,
|
||||
value,
|
||||
};
|
||||
|
||||
insert_entry(connection, entry)
|
||||
insert_entry(connection, Entry::try_from(invariant)?)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::addressing::Address;
|
||||
use crate::database::{
|
||||
bulk_retrieve_objects, ensure_invariant, file_set_valid, insert_entry, insert_file, query,
|
||||
retrieve_all_files, DbPool, Entry, EntryQuery, EntryValue, Query, QueryComponent, QueryPart,
|
||||
DATABASE_FILENAME, IS_TYPE_ATTR, TYPE_ATTR, TYPE_HAS_ATTR,
|
||||
retrieve_all_files, Addressable, DbPool, Entry, EntryQuery, EntryValue, InvariantEntry, Query,
|
||||
QueryComponent, QueryPart, DATABASE_FILENAME, IS_TYPE_ATTR, TYPE_ATTR, TYPE_HAS_ATTR,
|
||||
};
|
||||
use crate::hash::Hashable;
|
||||
use crate::jobs::{Job, JobContainer, JobId};
|
||||
|
@ -25,10 +25,24 @@ use walkdir::WalkDir;
|
|||
const DIR_TYPE: &str = "FS_DIR";
|
||||
const DIR_KEY: &str = "DIR";
|
||||
const DIR_HAS_KEY: &str = "DIR_HAS";
|
||||
lazy_static! {
|
||||
static ref DIR_TYPE_INVARIANT: InvariantEntry = InvariantEntry {
|
||||
attribute: String::from(TYPE_ATTR),
|
||||
value: EntryValue::Value(Value::from(DIR_TYPE)),
|
||||
};
|
||||
static ref DIR_TYPE_ADDR: Address = DIR_TYPE_INVARIANT.address().unwrap();
|
||||
}
|
||||
|
||||
const FILE_TYPE: &str = "FS_FILE";
|
||||
const FILE_IDENTITY_KEY: &str = "FILE_IS";
|
||||
const FILENAME_KEY: &str = "FILE_NAME";
|
||||
lazy_static! {
|
||||
static ref FILE_TYPE_INVARIANT: InvariantEntry = InvariantEntry {
|
||||
attribute: String::from(TYPE_ATTR),
|
||||
value: EntryValue::Value(Value::from(FILE_TYPE)),
|
||||
};
|
||||
static ref FILE_TYPE_ADDR: Address = FILE_TYPE_INVARIANT.address().unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct UDirectory {
|
||||
|
@ -240,7 +254,7 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
|
|||
let type_entry = Entry {
|
||||
entity: new_directory_address.clone(),
|
||||
attribute: String::from(IS_TYPE_ATTR),
|
||||
value: EntryValue::Value(Value::from(DIR_TYPE)),
|
||||
value: EntryValue::Address(DIR_TYPE_ADDR.clone()),
|
||||
};
|
||||
insert_entry(connection, type_entry)?;
|
||||
|
||||
|
@ -330,11 +344,7 @@ fn _rescan_vault<T: AsRef<Path>>(
|
|||
let start = Instant::now();
|
||||
|
||||
// Initialize types, etc...
|
||||
let file_type = ensure_invariant(
|
||||
&pool.get()?,
|
||||
String::from(TYPE_ATTR),
|
||||
EntryValue::Value(Value::from(FILE_TYPE)),
|
||||
)?;
|
||||
let file_type = ensure_invariant(&pool.get()?, &FILE_TYPE_INVARIANT)?;
|
||||
for attr in &[FILE_IDENTITY_KEY, FILENAME_KEY] {
|
||||
insert_entry(
|
||||
&pool.get()?,
|
||||
|
@ -346,11 +356,7 @@ fn _rescan_vault<T: AsRef<Path>>(
|
|||
)?;
|
||||
}
|
||||
|
||||
let dir_type = ensure_invariant(
|
||||
&pool.get()?,
|
||||
String::from(TYPE_ATTR),
|
||||
EntryValue::Value(Value::from(DIR_TYPE)),
|
||||
)?;
|
||||
let dir_type = ensure_invariant(&pool.get()?, &DIR_TYPE_INVARIANT)?;
|
||||
insert_entry(
|
||||
&pool.get()?,
|
||||
Entry {
|
||||
|
@ -501,7 +507,7 @@ fn _process_directory_entry<P: AsRef<Path>>(
|
|||
let type_entry = Entry {
|
||||
entity: file_address.clone(),
|
||||
attribute: String::from(IS_TYPE_ATTR),
|
||||
value: EntryValue::Value(Value::from(FILE_TYPE)),
|
||||
value: EntryValue::Address(FILE_TYPE_ADDR.clone()),
|
||||
};
|
||||
insert_entry(&connection, type_entry)?;
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
extern crate diesel;
|
||||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use std::env;
|
||||
use std::net::SocketAddr;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::addressing::Address;
|
||||
use crate::database::{
|
||||
get_latest_files, insert_entry, query, remove_object, retrieve_file, retrieve_object, DbPool,
|
||||
Entry, Query,
|
||||
get_latest_files, insert_entry, query, remove_object, retrieve_file, retrieve_object,
|
||||
Addressable, DbPool, Entry, Query,
|
||||
};
|
||||
use crate::filesystem::{list_directory, UPath};
|
||||
use crate::hash::{decode, encode};
|
||||
|
|
Loading…
Reference in New Issue