finish renaming target/key/value to entity/attribute/value

feat/vaults
Tomáš Mládek 2021-03-14 10:44:13 +01:00
parent 6e7cdd9887
commit 21e7ee7538
5 changed files with 100 additions and 101 deletions

View File

@ -10,13 +10,13 @@ VALUES ('version', '0.1.0');
CREATE TABLE files
(
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
hash BLOB NOT NULL,
path VARCHAR NOT NULL,
valid BOOLEAN NOT NULL DEFAULT TRUE,
added DATETIME NOT NULL,
size BIGINT NOT NULL,
mtime DATETIME NULL
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
hash BLOB NOT NULL,
path VARCHAR NOT NULL,
valid BOOLEAN NOT NULL DEFAULT TRUE,
added DATETIME NOT NULL,
size BIGINT NOT NULL,
mtime DATETIME NULL
);
CREATE INDEX files_hash ON files (hash);
@ -25,13 +25,13 @@ CREATE INDEX files_valid ON files (valid);
CREATE TABLE data
(
identity BLOB PRIMARY KEY NOT NULL,
target BLOB NOT NULL,
key VARCHAR NOT NULL,
value VARCHAR NOT NULL,
UNIQUE (target, key, value)
identity BLOB PRIMARY KEY NOT NULL,
entity BLOB NOT NULL,
attribute VARCHAR NOT NULL,
value VARCHAR NOT NULL,
UNIQUE (entity, attribute, value)
);
CREATE INDEX data_target ON data (target);
CREATE INDEX data_key ON data (key);
CREATE INDEX data_entity ON data (entity);
CREATE INDEX data_attribute ON data (attribute);
CREATE INDEX data_value ON data (value);

View File

@ -27,8 +27,8 @@ use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry {
pub target: Address,
pub key: String,
pub entity: Address,
pub attribute: String,
pub value: EntryValue,
}
@ -45,8 +45,8 @@ impl TryFrom<&models::Entry> for Entry {
fn try_from(e: &models::Entry) -> Result<Self, Self::Error> {
Ok(Entry {
target: Address::decode(&e.target)?,
key: e.key.clone(),
entity: Address::decode(&e.entity)?,
attribute: e.attribute.clone(),
value: e.value.parse().unwrap(),
})
}
@ -54,15 +54,15 @@ impl TryFrom<&models::Entry> for Entry {
impl std::fmt::Display for Entry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} | {} | {}", self.target, self.key, self.value)
write!(f, "{} | {} | {}", self.entity, self.attribute, self.value)
}
}
impl Hashable for Entry {
fn hash(self: &Entry) -> Result<Hash> {
let mut result = Cursor::new(vec![0u8; 0]);
result.write_all(self.target.encode()?.as_slice())?;
result.write_all(self.key.as_bytes())?;
result.write_all(self.entity.encode()?.as_slice())?;
result.write_all(self.attribute.as_bytes())?;
result.write_all(self.value.to_string()?.as_bytes())?;
Ok(hash(result.get_ref()))
}
@ -203,7 +203,7 @@ pub fn retrieve_object<C: Connection<Backend = Sqlite>>(
use crate::schema::data::dsl::*;
let matches = data
.filter(target.eq(object_address.encode()?))
.filter(entity.eq(object_address.encode()?))
.or_filter(value.eq(EntryValue::Address(object_address).to_string()?))
.load::<models::Entry>(connection)?;
let entries = matches
@ -223,7 +223,7 @@ pub fn bulk_retrieve_objects<C: Connection<Backend = Sqlite>>(
let matches = data
.filter(
target.eq_any(
entity.eq_any(
object_addresses
.iter()
.filter_map(|addr| addr.encode().ok()),
@ -250,7 +250,7 @@ pub fn remove_object<C: Connection<Backend = Sqlite>>(
let matches = data
.filter(identity.eq(object_address.encode()?))
.or_filter(target.eq(object_address.encode()?))
.or_filter(entity.eq(object_address.encode()?))
.or_filter(value.eq(EntryValue::Address(object_address).to_string()?));
Ok(diesel::delete(matches).execute(connection)?)
@ -462,68 +462,67 @@ impl TryFrom<&lexpr::Value> for Query {
impl Query {
fn to_sqlite_predicates(&self) -> Result<Box<Predicate>> {
match self {
Query::SingleQuery(qp) => match qp {
QueryPart::Matches(eq) => {
let mut subqueries: Vec<Box<Predicate>> = vec![];
Query::SingleQuery(qp) => {
match qp {
QueryPart::Matches(eq) => {
let mut subqueries: Vec<Box<Predicate>> = vec![];
match &eq.entity {
QueryComponent::Exact(q_target) => {
subqueries.push(Box::new(data::target.eq(q_target.encode()?)))
}
QueryComponent::In(q_targets) => {
let targets: Result<Vec<_>, _> =
q_targets.iter().map(|t| t.encode()).collect();
subqueries.push(Box::new(data::target.eq_any(targets?)))
}
QueryComponent::Contains(_) => {
return Err(anyhow!("Addresses cannot be queried alike."))
}
QueryComponent::Any => {}
};
match &eq.attribute {
QueryComponent::Exact(q_key) => {
subqueries.push(Box::new(data::key.eq(q_key.clone())))
}
QueryComponent::In(q_keys) => {
subqueries.push(Box::new(data::key.eq_any(q_keys.clone())))
}
QueryComponent::Contains(q_key) => {
subqueries.push(Box::new(data::key.like(format!("%{}%", q_key))))
}
QueryComponent::Any => {}
};
match &eq.value {
QueryComponent::Exact(q_value) => {
subqueries.push(Box::new(data::value.eq(q_value.to_string()?)))
}
QueryComponent::In(q_values) => {
let values: Result<Vec<_>, _> =
q_values.iter().map(|v| v.to_string()).collect();
subqueries.push(Box::new(data::value.eq_any(values?)))
}
QueryComponent::Contains(q_value) => {
subqueries.push(Box::new(data::value.like(format!("%{}%", q_value))))
}
QueryComponent::Any => {}
};
match subqueries.len() {
0 => Ok(Box::new(true.into_sql::<Bool>())),
1 => Ok(subqueries.remove(0)),
_ => {
let mut result: Box<And<Box<Predicate>, Box<Predicate>>> =
Box::new(And::new(subqueries.remove(0), subqueries.remove(0)));
while !subqueries.is_empty() {
result = Box::new(And::new(result, subqueries.remove(0)));
match &eq.entity {
QueryComponent::Exact(q_entity) => {
subqueries.push(Box::new(data::entity.eq(q_entity.encode()?)))
}
QueryComponent::In(q_entities) => {
let entities: Result<Vec<_>, _> =
q_entities.iter().map(|t| t.encode()).collect();
subqueries.push(Box::new(data::entity.eq_any(entities?)))
}
QueryComponent::Contains(_) => {
return Err(anyhow!("Addresses cannot be queried alike."))
}
QueryComponent::Any => {}
};
match &eq.attribute {
QueryComponent::Exact(q_attribute) => {
subqueries.push(Box::new(data::attribute.eq(q_attribute.clone())))
}
QueryComponent::In(q_attributes) => subqueries
.push(Box::new(data::attribute.eq_any(q_attributes.clone()))),
QueryComponent::Contains(q_attribute) => subqueries
.push(Box::new(data::attribute.like(format!("%{}%", q_attribute)))),
QueryComponent::Any => {}
};
match &eq.value {
QueryComponent::Exact(q_value) => {
subqueries.push(Box::new(data::value.eq(q_value.to_string()?)))
}
QueryComponent::In(q_values) => {
let values: Result<Vec<_>, _> =
q_values.iter().map(|v| v.to_string()).collect();
subqueries.push(Box::new(data::value.eq_any(values?)))
}
QueryComponent::Contains(q_value) => subqueries
.push(Box::new(data::value.like(format!("%{}%", q_value)))),
QueryComponent::Any => {}
};
match subqueries.len() {
0 => Ok(Box::new(true.into_sql::<Bool>())),
1 => Ok(subqueries.remove(0)),
_ => {
let mut result: Box<And<Box<Predicate>, Box<Predicate>>> =
Box::new(And::new(subqueries.remove(0), subqueries.remove(0)));
while !subqueries.is_empty() {
result = Box::new(And::new(result, subqueries.remove(0)));
}
Ok(Box::new(result))
}
Ok(Box::new(result))
}
}
QueryPart::Type(_) => unimplemented!("Type queries are not yet implemented."),
}
QueryPart::Type(_) => unimplemented!("Type queries are not yet implemented."),
},
}
Query::MultiQuery(mq) => {
let subqueries: Result<Vec<Box<Predicate>>> = mq
.queries
@ -584,8 +583,8 @@ pub fn insert_entry<C: Connection<Backend = Sqlite>>(
let insert_entry = models::Entry {
identity: entry.address()?.encode()?,
target: entry.target.encode()?,
key: entry.key,
entity: entry.entity.encode()?,
attribute: entry.attribute,
value: entry.value.to_string()?,
};

View File

@ -151,7 +151,7 @@ pub fn list_roots<C: Connection<Backend = Sqlite>>(connection: &C) -> Result<Vec
Ok(all_directories
.into_iter()
.filter(|entry| !directories_with_parents.contains(&entry.target))
.filter(|entry| !directories_with_parents.contains(&entry.entity))
.collect())
}
@ -162,7 +162,7 @@ pub async fn list_directory<C: Connection<Backend = Sqlite>>(
let entry_addresses = match path.0.len() {
0 => list_roots(connection)?
.into_iter()
.map(|e| e.target)
.map(|e| e.entity)
.collect(),
_ => {
let resolved_path: Vec<Address> = resolve_path(connection, path, false)?;
@ -182,7 +182,7 @@ pub async fn list_directory<C: Connection<Backend = Sqlite>>(
Ok(bulk_retrieve_objects(connection, entry_addresses)?
.into_iter()
.filter(|e| [DIR_KEY, FILENAME_KEY, FILE_IDENTITY_KEY].contains(&e.key.as_str()))
.filter(|e| [DIR_KEY, FILENAME_KEY, FILE_IDENTITY_KEY].contains(&e.attribute.as_str()))
.collect::<Vec<Entry>>())
}
@ -207,7 +207,7 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
})),
)?
.into_iter()
.map(|e: Entry| e.target)
.map(|e: Entry| e.entity)
.collect();
let valid_directories: Vec<Address> = match parent.clone() {
@ -235,16 +235,16 @@ pub fn fetch_or_create_dir<C: Connection<Backend = Sqlite>>(
if create {
let new_directory_address = Address::UUID(Uuid::new_v4());
let directory_entry = Entry {
target: new_directory_address.clone(),
key: String::from(DIR_KEY),
entity: new_directory_address.clone(),
attribute: String::from(DIR_KEY),
value: dir_value,
};
let _ = insert_entry(connection, directory_entry)?;
if let Some(parent_addr) = parent {
let has_entry = Entry {
target: parent_addr,
key: String::from(DIR_HAS_KEY),
entity: parent_addr,
attribute: String::from(DIR_HAS_KEY),
value: EntryValue::Address(new_directory_address.clone()),
};
let _ = insert_entry(connection, has_entry)?;
@ -456,8 +456,8 @@ fn _process_directory_entry<P: AsRef<Path>>(
let file_address = Address::UUID(Uuid::new_v4());
let name_entry = Entry {
target: file_address.clone(),
key: FILENAME_KEY.to_string(),
entity: file_address.clone(),
attribute: FILENAME_KEY.to_string(),
value: EntryValue::Value(Value::String(
filename.as_os_str().to_string_lossy().to_string(),
)),
@ -465,16 +465,16 @@ fn _process_directory_entry<P: AsRef<Path>>(
let _ = insert_entry(&connection, name_entry)?;
let identity_entry = Entry {
target: file_address.clone(),
key: FILE_IDENTITY_KEY.to_string(),
entity: file_address.clone(),
attribute: FILE_IDENTITY_KEY.to_string(),
value: EntryValue::Address(Address::Hash(digest.clone())),
};
let _ = insert_entry(&connection, identity_entry)?;
let dir_has_entry = Entry {
target: parent_dir.clone(),
key: DIR_HAS_KEY.to_string(),
entity: parent_dir.clone(),
attribute: DIR_HAS_KEY.to_string(),
value: EntryValue::Address(file_address),
};
let _ = insert_entry(&connection, dir_has_entry)?;

View File

@ -29,7 +29,7 @@ pub struct NewFile {
#[table_name = "data"]
pub struct Entry {
pub identity: Vec<u8>,
pub target: Vec<u8>,
pub key: String,
pub entity: Vec<u8>,
pub attribute: String,
pub value: String,
}

View File

@ -1,8 +1,8 @@
table! {
data (identity) {
identity -> Binary,
target -> Binary,
key -> Text,
entity -> Binary,
attribute -> Text,
value -> Text,
}
}