commit | 4b87e64a1fdd0163c9c05652de7a5921345f51da | [log] [tgz] |
---|---|---|
author | Siân Griffin <sean@seantheprogrammer.com> | Tue Sep 01 10:46:46 2020 -0600 |
committer | Siân Griffin <sean@seantheprogrammer.com> | Tue Sep 01 11:13:33 2020 -0600 |
tree | cf1db5f56533778fc3008188b15b24e20dd6244d | |
parent | 44d0096ae99d135a644a2cb26da11b6a5135de90 [diff] |
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.
API Documentation: latest release – master branch
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:
You can configure the database backend in Cargo.toml
:
[dependencies] diesel = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }
Find our extensive Getting Started tutorial at https://diesel.rs/guides/getting-started. Guides on more specific features are coming soon.
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.
Anyone who interacts with Diesel in any space, including but not limited to this GitHub repository, must follow our code of conduct.
Licensed under either of these:
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.