Skip to content

Commit 1e18b37

Browse files
authored
Merge pull request #109 from DevLazio/main
Add a From<AsyncConnection> for AsyncConnectionWrapper
2 parents e3c3511 + 1122763 commit 1e18b37

File tree

7 files changed

+92
-2
lines changed

7 files changed

+92
-2
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ jobs:
117117
run: cargo +${{ matrix.rust }} test --manifest-path Cargo.toml --no-default-features --features "${{ matrix.backend }} deadpool bb8 mobc"
118118
- name: Run examples
119119
if: matrix.backend == 'postgres'
120-
run: cargo +${{ matrix.rust }} check --manifest-path examples/postgres/pooled-with-rustls/Cargo.toml
120+
run: |
121+
cargo +${{ matrix.rust }} check --manifest-path examples/postgres/pooled-with-rustls/Cargo.toml
122+
cargo +${{ matrix.rust }} check --manifest-path examples/postgres/run-pending-migrations-with-rustls/Cargo.toml
121123
122124
rustfmt_and_clippy:
123125
name: Check rustfmt style && run clippy

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ rustdoc-args = ["--cfg", "doc_cfg"]
5555
[workspace]
5656
members = [
5757
".",
58-
"examples/postgres/pooled-with-rustls"
58+
"examples/postgres/pooled-with-rustls",
59+
"examples/postgres/run-pending-migrations-with-rustls",
5960
]
6061

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "run-pending-migrations-with-rustls"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
diesel = { version = "2.1.0", default-features = false, features = ["postgres"] }
10+
diesel-async = { version = "0.4.0", path = "../../../", features = ["bb8", "postgres", "async-connection-wrapper"] }
11+
diesel_migrations = "2.1.0"
12+
futures-util = "0.3.21"
13+
rustls = "0.20.8"
14+
rustls-native-certs = "0.6.2"
15+
tokio = { version = "1.2.0", default-features = false, features = ["macros", "rt-multi-thread"] }
16+
tokio-postgres = "0.7.7"
17+
tokio-postgres-rustls = "0.9.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SELECT 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SELECT 1;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use diesel::{ConnectionError, ConnectionResult};
2+
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
3+
use diesel_async::AsyncPgConnection;
4+
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
5+
use futures_util::future::BoxFuture;
6+
use futures_util::FutureExt;
7+
8+
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
9+
10+
#[tokio::main]
11+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
12+
// Should be in the form of postgres://user:password@localhost/database?sslmode=require
13+
let db_url = std::env::var("DATABASE_URL").expect("Env var `DATABASE_URL` not set");
14+
15+
let async_connection = establish_connection(db_url.as_str()).await?;
16+
17+
let mut async_wrapper: AsyncConnectionWrapper<AsyncPgConnection> =
18+
AsyncConnectionWrapper::from(async_connection);
19+
20+
tokio::task::spawn_blocking(move || {
21+
async_wrapper.run_pending_migrations(MIGRATIONS).unwrap();
22+
})
23+
.await?;
24+
25+
Ok(())
26+
}
27+
28+
fn establish_connection(config: &str) -> BoxFuture<ConnectionResult<AsyncPgConnection>> {
29+
let fut = async {
30+
// We first set up the way we want rustls to work.
31+
let rustls_config = rustls::ClientConfig::builder()
32+
.with_safe_defaults()
33+
.with_root_certificates(root_certs())
34+
.with_no_client_auth();
35+
let tls = tokio_postgres_rustls::MakeRustlsConnect::new(rustls_config);
36+
let (client, conn) = tokio_postgres::connect(config, tls)
37+
.await
38+
.map_err(|e| ConnectionError::BadConnection(e.to_string()))?;
39+
tokio::spawn(async move {
40+
if let Err(e) = conn.await {
41+
eprintln!("Database connection: {e}");
42+
}
43+
});
44+
AsyncPgConnection::try_from(client).await
45+
};
46+
fut.boxed()
47+
}
48+
49+
fn root_certs() -> rustls::RootCertStore {
50+
let mut roots = rustls::RootCertStore::empty();
51+
let certs = rustls_native_certs::load_native_certs().expect("Certs not loadable!");
52+
let certs: Vec<_> = certs.into_iter().map(|cert| cert.0).collect();
53+
roots.add_parsable_certificates(&certs);
54+
roots
55+
}

src/async_connection_wrapper.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ mod implementation {
109109
runtime: B,
110110
}
111111

112+
impl<C, B> From<C> for AsyncConnectionWrapper<C, B>
113+
where
114+
C: crate::AsyncConnection,
115+
B: BlockOn + Send,
116+
{
117+
fn from(inner: C) -> Self {
118+
Self {
119+
inner,
120+
runtime: B::get_runtime(),
121+
}
122+
}
123+
}
124+
112125
impl<C, B> diesel::connection::SimpleConnection for AsyncConnectionWrapper<C, B>
113126
where
114127
C: crate::SimpleAsyncConnection,

0 commit comments

Comments
 (0)