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)