Make `Statement::prepare` async

I really *really* don't want to have to maintain two copies of the PG
backend. For `Statement::prepare`, this means at minimum having it call
`PQsendPrepare` and `PQgetResult` instead of `PQprepare`. The only
difference between the sync and async versions is whether or not we do
the `PQflush`, `PQconsumeInput`, and `PQisBusy` loop before calling
`PQgetResult`.

I've gone back and forth on this a ton, and I think the best option is
to just have the async version be canonical, and provide a really shitty
form of `block_on` that the blocking connection uses. There's a few
reasons for this, but the biggest is that I want to prevent
`RawConnection` from being misused. Any time a command is sent, we need
to grab all the results from that command, or otherwise have some form
of multiplexing which isn't reasonable to implement. So if we exposed
`send_prepare` and `get_result` on `RawConnection` separately, it's easy
for callers to misuse. These functions are internal and unsafe, so maybe
it's fine, but Rust is capable of encoding this, so I'd prefer to do so
if possible.

The second reason is that I don't want to have to maintain a second
version of `StatementCache`, which means it will need to be aware of the
fact that the function to get the value is async. This commit does not
yet implement that, but starts to move in that direction.

If we're going to make `StatementCache` async, that's going to affect
all backends, async or not, so we *really* need to make sure it's zero
cost. I care more about compile time than runtime here, but I think the
impact is relatively negligible as long as we don't pull in `tokio` or
something.

As far as I'm aware, the actual implementation of `async`/`await` itself
for functions that never yield is zero cost now that TLS is no longer
used. So I think that if we combine this with the worlds worst
implementation of `block_on` that specifically knows our futures never
yield, we can share most of the code with a negligible impact on compile
times or run times for sync users.

The main cost here is that `RawConnection` now needs a `RefCell`, but we
need to move a `RefCell` for `StatementCache` up a level anyway, so I
think we'll end up having a "this is the real connection" struct that
just gets a `RefCell` around the whole thing for PG.
3 files changed
tree: cf1db5f56533778fc3008188b15b24e20dd6244d
  1. .github/
  2. bin/
  3. diesel/
  4. diesel_cli/
  5. diesel_compile_tests/
  6. diesel_derives/
  7. diesel_dynamic_schema/
  8. diesel_migrations/
  9. diesel_tests/
  10. docker/
  11. examples/
  12. guide_drafts/
  13. migrations/
  14. .editorconfig
  15. .env.sample
  16. .gitignore
  17. Cargo.toml
  18. CHANGELOG.md
  19. clippy.toml
  20. code_of_conduct.md
  21. CONTRIBUTING.md
  22. docker-compose.yml
  23. LICENSE-APACHE
  24. LICENSE-MIT
  25. README.md
  26. rust-toolchain
README.md

A safe, extensible ORM and Query Builder for Rust

Build Status Gitter Crates.io

API Documentation: latest releasemaster branch

Homepage

Diesel gets rid of the boilerplate for database interaction and eliminates runtime errors without sacrificing performance. It takes full advantage of Rust's type system to create a low overhead query builder that “feels like Rust.”

Supported databases:

  1. PostgreSQL
  2. MySQL
  3. SQLite

You can configure the database backend in Cargo.toml:

[dependencies]
diesel = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }

Getting Started

Find our extensive Getting Started tutorial at https://diesel.rs/guides/getting-started. Guides on more specific features are coming soon.

Getting help

If you run into problems, Diesel has a very active Gitter room. You can come ask for help at gitter.im/diesel-rs/diesel. For help with longer questions and discussion about the future of Diesel, visit our discourse forum.

Code of conduct

Anyone who interacts with Diesel in any space, including but not limited to this GitHub repository, must follow our code of conduct.

License

Licensed under either of these:

Contributing

Before contributing, please read the contributors guide for useful information about setting up Diesel locally, coding style and common abbreviations.

Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.