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)