cornucopia-rs / cornucopia

Generate type-checked Rust from your PostgreSQL.
Other
755 stars 31 forks source link

Why does client_async cache statements? #218

Closed seogrady closed 10 months ago

seogrady commented 10 months ago

In the examples, it looks like you invoke insert_book().bind(&transaction, &"The Great Gatsby") multiple times. Doesn't this call prepare statement every query?

Would it be preferred to do something like this to reuse the prepared statement?

let stmt = insert_book();
stmt.bind(&transaction, &"The Great Gatsby").await.unwrap();
stmt.bind(&transaction, &String::from("Moby Dick")).await.unwrap();

Wondering what the best approach is. Should I cache insert_book(), invoke every time or cache once on db connection?

Virgiel commented 10 months ago

It depends. Some clients like deadpool cache prepared statements, so calling prepare twice actually prepares only once. We want to give more control over caching while still taking advantage of client caching, see #198.

In fact, in your code, insert_book doesn't prepare the statement, that happens in bind and relies on the client cache. There's no way to explicitly prepare in the current API.

seogrady commented 10 months ago

Thanks for the PR link @Virgiel . insert_book doesn't prepare the statement but looks like it creates a new instance of cornucopia_async::private::Stmt every call to insert_book, which internally caches the Statement. In that case, doesn't the cache doing nothing?

With your changes it looks like you can optionally call prepare, or if the client supports caching it will happen there. PR looks good 👍

Virgiel commented 10 months ago

Thanks for the PR link @Virgiel . insert_book doesn't prepare the statement but looks like it creates a new instance of cornucopia_async::private::Stmt every call to insert_book, which internally caches the Statement. In that case, doesn't the cache doing nothing?

Yes you are right 😅