I have now converted OwnedExpression to use Expressive protocol and started to think about "LazyExpression".
It's not really an expression that's lazy - it is a parameter to the expression that is lazy.
So I ditched LazyExpression entirely, and instead implemented support for Arc and Arc
https://github.com/romaninsh/vantage/pull/61
Before, a parameter to Expression engine could be either a value or a nested expression.
Now, a parameter to Expression can also be Arc or Mutex holding a value or a nested expression.
In other words a query builder (which is mutable) can now be used inside another query. Of course we can still defer things too, which does give us a lot of flexibility:
Suppose you have a custom struct:
struct GreetingQuery {
name: String,
}
a struct would generate a custom query with current name if it is part of a template:
impl From<&GreetingQuery> for OwnedExpression {
fn from(greeting: &GreetingQuery) -> OwnedExpression {
expr!("Hello {}", greeting.name.clone())
}
}
impl From<GreetingQuery> for IntoExpressive<OwnedExpression> {
fn from(greeting: GreetingQuery) -> Self {
IntoExpressive::nested(OwnedExpression::from(&greeting))
}
}
Lets construct our struct:
let greeting = Arc::new(Mutex::new(GreetingQuery {
name: "world".to_string(),
}));
this can now be cloned and shared all throughout the app. Some expressions may rely on it:
let expr = expr!("select {}", &greeting);
now every time expression is executed it will acquire a value from a mutex:
let result1 = db.execute(&expr).await;
// select hello "world"
{
let mut guard = greeting.lock().unwrap();
guard.name = "vantage".to_string();
}
let result2 = db.execute(&expr).await;
// select helo "vantage"
Top comments (0)