feat(db): 🚧 #key expressions in lang
ci/woodpecker/push/woodpecker Pipeline failed Details

feat/lang-upgrades-keys
Tomáš Mládek 2023-10-21 22:55:20 +02:00
parent de8d6b1c59
commit c50681e7b6
3 changed files with 31 additions and 2 deletions

View File

@ -24,6 +24,7 @@ where
In(Vec<T>), In(Vec<T>),
Contains(String), Contains(String),
Variable(Option<String>), Variable(Option<String>),
Key(String),
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -180,6 +181,16 @@ impl TryFrom<&lexpr::Value> for Query {
Some(var_name.into()) Some(var_name.into())
})) }))
} }
lexpr::Value::Symbol(symbol) if symbol.starts_with('#') => {
let var_name = symbol.strip_prefix('#').unwrap();
if var_name.is_empty() {
return Err(UpEndError::QueryParseError(
"Malformed expression: Key cannot be empty.".into(),
));
} else {
return Ok(QueryComponent::Key(var_name.into()));
}
}
_ => Ok(QueryComponent::Exact(T::try_from(value.clone())?)), _ => Ok(QueryComponent::Exact(T::try_from(value.clone())?)),
} }
} }

View File

@ -262,12 +262,18 @@ fn to_sqlite_predicates(query: Query) -> Result<SqlResult, QueryExecutionError>
data::entity_searchable.like(format!("%{}%", q_entity)), data::entity_searchable.like(format!("%{}%", q_entity)),
)), )),
QueryComponent::Variable(_) => {} QueryComponent::Variable(_) => {}
QueryComponent::Key(_) => {
subqueries.push(Box::new)
}
}; };
match &eq.attribute { match &eq.attribute {
QueryComponent::Exact(q_attribute) => { QueryComponent::Exact(q_attribute) => {
subqueries.push(Box::new(data::attribute.eq(q_attribute.0.clone()))) subqueries.push(Box::new(data::attribute.eq(q_attribute.0.clone())))
} }
QueryComponent::Key(q_attribute) => {
subqueries.push(Box::new(data::attribute.eq(q_attribute.clone())))
}
QueryComponent::In(q_attributes) => subqueries.push(Box::new( QueryComponent::In(q_attributes) => subqueries.push(Box::new(
data::attribute.eq_any(q_attributes.iter().map(|a| &a.0).cloned()), data::attribute.eq_any(q_attributes.iter().map(|a| &a.0).cloned()),
)), )),
@ -337,6 +343,9 @@ fn to_sqlite_predicates(query: Query) -> Result<SqlResult, QueryExecutionError>
subqueries.push(Box::new(data::value_str.like(format!("S%{}%", q_value)))) subqueries.push(Box::new(data::value_str.like(format!("S%{}%", q_value))))
} }
QueryComponent::Variable(_) => {} QueryComponent::Variable(_) => {}
QueryComponent::Key(key) => {
subqueries.push(Box::new(data::value_str.like(format!("K%{}%", key))))
}
}; };
match subqueries.len() { match subqueries.len() {

View File

@ -432,7 +432,7 @@ impl UpEndConnection {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use upend_base::constants::{ATTR_LABEL, ATTR_IN}; use upend_base::constants::{ATTR_IN, ATTR_KEY, ATTR_LABEL};
use super::*; use super::*;
use tempfile::TempDir; use tempfile::TempDir;
@ -542,6 +542,15 @@ mod test {
let result = connection.query(query).unwrap(); let result = connection.query(query).unwrap();
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
assert_eq!(result[0].entity, edge_entity); assert_eq!(result[0].entity, edge_entity);
assert_eq!(result[0].value, EntryValue::Address(random_entity)); assert_eq!(result[0].value, EntryValue::Address(random_entity.clone()));
upend_insert_val!(connection, random_entity, ATTR_KEY, "FOO").unwrap();
let query = format!(r#"(matches #FOO "{ATTR_LABEL}" ?)"#)
.parse()
.unwrap();
let result = connection.query(query).unwrap();
assert_eq!(result.len(), 1);
assert_eq!(result[0].entity, random_entity);
assert_eq!(result[0].value, EntryValue::String("FOOBAR".to_string()));
} }
} }