allow searching in entities (URLs, attrs)

feat/vaults
Tomáš Mládek 2022-02-07 18:33:57 +01:00
parent 0f2fa6836f
commit 25bc14e3b4
No known key found for this signature in database
GPG Key ID: ED21612889E75EC5
5 changed files with 45 additions and 10 deletions

View File

@ -25,15 +25,17 @@ CREATE INDEX files_valid ON files (valid);
CREATE TABLE data
(
identity BLOB PRIMARY KEY NOT NULL,
entity BLOB NOT NULL,
attribute VARCHAR NOT NULL,
value_str VARCHAR,
value_num NUMERIC,
immutable BOOLEAN NOT NULL
identity BLOB PRIMARY KEY NOT NULL,
entity BLOB NOT NULL,
entity_searchable VARCHAR,
attribute VARCHAR NOT NULL,
value_str VARCHAR,
value_num NUMERIC,
immutable BOOLEAN NOT NULL
);
CREATE INDEX data_entity ON data (entity);
CREATE INDEX data_entity_searchable ON data (entity_searchable);
CREATE INDEX data_attribute ON data (attribute);
CREATE INDEX data_value_str ON data (value_str);
CREATE INDEX data_value_num ON data (value_num);

View File

@ -68,6 +68,11 @@ impl TryFrom<&Entry> for models::Entry {
fn try_from(e: &Entry) -> Result<Self, Self::Error> {
let base_entry = models::Entry {
identity: e.address()?.encode()?,
entity_searchable: match &e.entity {
Address::Attribute(attr) => Some(attr.clone()),
Address::Url(url) => Some(url.clone()),
_ => None,
},
entity: e.entity.encode()?,
attribute: e.attribute.clone(),
value_str: None,

View File

@ -44,6 +44,7 @@ pub struct NewFile {
pub struct Entry {
pub identity: Vec<u8>,
pub entity: Vec<u8>,
pub entity_searchable: Option<String>,
pub attribute: String,
pub value_str: Option<String>,
pub value_num: Option<f64>,

View File

@ -2,6 +2,7 @@ table! {
data (identity) {
identity -> Binary,
entity -> Binary,
entity_searchable -> Nullable<Text>,
attribute -> Text,
value_str -> Nullable<Text>,
value_num -> Nullable<Double>,
@ -29,4 +30,8 @@ table! {
}
}
allow_tables_to_appear_in_same_query!(data, files, meta,);
allow_tables_to_appear_in_same_query!(
data,
files,
meta,
);

View File

@ -260,9 +260,9 @@ impl Query {
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::Contains(q_entity) => subqueries.push(Box::new(
data::entity_searchable.like(format!("%{}%", q_entity)),
)),
QueryComponent::Any => {}
};
@ -553,6 +553,28 @@ mod test {
#[test]
fn test_contains() -> Result<()> {
let query = "(matches (contains \"foo\") ? ?)".parse::<Query>()?;
assert_eq!(
query,
Query::SingleQuery(QueryPart::Matches(EntryQuery {
entity: QueryComponent::Contains("foo".to_string()),
attribute: QueryComponent::Any,
value: QueryComponent::Any
}))
);
query.to_sqlite_predicates()?;
let query = "(matches ? (contains \"foo\") ?)".parse::<Query>()?;
assert_eq!(
query,
Query::SingleQuery(QueryPart::Matches(EntryQuery {
entity: QueryComponent::Any,
attribute: QueryComponent::Contains("foo".to_string()),
value: QueryComponent::Any,
}))
);
query.to_sqlite_predicates()?;
let query = "(matches ? ? (contains \"foo\"))".parse::<Query>()?;
assert_eq!(
query,