DEV Community

Romans Malinovskis
Romans Malinovskis

Posted on

Arc and Mutex for SQL Expression parameters

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,
}
Enter fullscreen mode Exit fullscreen mode

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))
    }
}
Enter fullscreen mode Exit fullscreen mode

Lets construct our struct:

let greeting = Arc::new(Mutex::new(GreetingQuery {
    name: "world".to_string(),
}));
Enter fullscreen mode Exit fullscreen mode

this can now be cloned and shared all throughout the app. Some expressions may rely on it:

let expr = expr!("select {}", &greeting);
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Top comments (0)