Skip to content

Commit c790c26

Browse files
committed
Improve SyncConnectionWrapper documentation and tests
1 parent 0ff4fbb commit c790c26

File tree

6 files changed

+121
-6
lines changed

6 files changed

+121
-6
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ path = "tests/lib.rs"
4949
harness = true
5050

5151
[package.metadata.docs.rs]
52-
features = ["postgres", "mysql", "deadpool", "bb8", "mobc", "async-connection-wrapper", "r2d2"]
52+
features = ["postgres", "mysql", "sqlite", "deadpool", "bb8", "mobc", "async-connection-wrapper", "sync-connection-wrapper", "r2d2"]
5353
no-default-features = true
5454
rustc-args = ["--cfg", "doc_cfg"]
5555
rustdoc-args = ["--cfg", "doc_cfg"]

examples/sync-wrapper/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type InnerConnection = SqliteConnection;
2828
type InnerDB = Sqlite;
2929

3030
async fn establish(db_url: &str) -> ConnectionResult<SyncConnectionWrapper<InnerConnection>> {
31+
// It is necessary to specify the specific inner connection type because of inference issues
3132
SyncConnectionWrapper::<SqliteConnection>::establish(db_url).await
3233
}
3334

src/doctest_setup.rs

+75
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,81 @@ cfg_if::cfg_if! {
160160
create_tables(&mut connection).await;
161161

162162

163+
connection
164+
}
165+
} else if #[cfg(feature = "sqlite")] {
166+
use diesel_async::sync_connection_wrapper::SyncConnectionWrapper;
167+
use diesel::sqlite::SqliteConnection;
168+
#[allow(dead_code)]
169+
type DB = diesel::sqlite::Sqlite;
170+
#[allow(dead_code)]
171+
type DbConnection = SyncConnectionWrapper<SqliteConnection>;
172+
173+
fn database_url() -> String {
174+
database_url_from_env("SQLITE_DATABASE_URL")
175+
}
176+
177+
async fn connection_no_data() -> SyncConnectionWrapper<SqliteConnection> {
178+
use diesel_async::AsyncConnection;
179+
let connection_url = database_url();
180+
SyncConnectionWrapper::<SqliteConnection>::establish(&connection_url).await.unwrap()
181+
}
182+
183+
async fn create_tables(connection: &mut SyncConnectionWrapper<SqliteConnection>) {
184+
use diesel_async::RunQueryDsl;
185+
use diesel_async::AsyncConnection;
186+
diesel::sql_query("CREATE TEMPORARY TABLE IF NOT EXISTS users (
187+
id INTEGER PRIMARY KEY,
188+
name TEXT NOT NULL
189+
)").execute(connection).await.unwrap();
190+
191+
192+
diesel::sql_query("CREATE TEMPORARY TABLE IF NOT EXISTS animals (
193+
id INTEGER PRIMARY KEY,
194+
species TEXT NOT NULL,
195+
legs INTEGER NOT NULL,
196+
name TEXT
197+
)").execute(connection).await.unwrap();
198+
199+
diesel::sql_query("CREATE TEMPORARY TABLE IF NOT EXISTS posts (
200+
id INTEGER PRIMARY KEY,
201+
user_id INTEGER NOT NULL,
202+
title TEXT NOT NULL
203+
)").execute(connection).await.unwrap();
204+
205+
diesel::sql_query("CREATE TEMPORARY TABLE IF NOT EXISTS comments (
206+
id INTEGER PRIMARY KEY,
207+
post_id INTEGER NOT NULL,
208+
body TEXT NOT NULL
209+
)").execute(connection).await.unwrap();
210+
diesel::sql_query("CREATE TEMPORARY TABLE IF NOT EXISTS brands (
211+
id INTEGER PRIMARY KEY,
212+
color VARCHAR(255) NOT NULL DEFAULT 'Green',
213+
accent VARCHAR(255) DEFAULT 'Blue'
214+
)").execute(connection).await.unwrap();
215+
216+
connection.begin_test_transaction().await.unwrap();
217+
diesel::sql_query("INSERT INTO users (name) VALUES ('Sean'), ('Tess')").execute(connection).await.unwrap();
218+
diesel::sql_query("INSERT INTO posts (user_id, title) VALUES
219+
(1, 'My first post'),
220+
(1, 'About Rust'),
221+
(2, 'My first post too')").execute(connection).await.unwrap();
222+
diesel::sql_query("INSERT INTO comments (post_id, body) VALUES
223+
(1, 'Great post'),
224+
(2, 'Yay! I am learning Rust'),
225+
(3, 'I enjoyed your post')").execute(connection).await.unwrap();
226+
diesel::sql_query("INSERT INTO animals (species, legs, name) VALUES
227+
('dog', 4, 'Jack'),
228+
('spider', 8, null)").execute(connection).await.unwrap();
229+
230+
}
231+
232+
#[allow(dead_code)]
233+
async fn establish_connection() -> SyncConnectionWrapper<SqliteConnection> {
234+
let mut connection = connection_no_data().await;
235+
create_tables(&mut connection).await;
236+
237+
163238
connection
164239
}
165240
} else {

src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
//!
1515
//! These traits closely mirror their diesel counter parts while providing async functionality.
1616
//!
17-
//! In addition to these core traits 2 fully async connection implementations are provided
17+
//! In addition to these core traits 3 fully async connection implementations are provided
1818
//! by diesel-async:
1919
//!
2020
//! * [`AsyncMysqlConnection`] (enabled by the `mysql` feature)
2121
//! * [`AsyncPgConnection`] (enabled by the `postgres` feature)
22+
//! * [`SyncConnectionWrapper`] (enabled by the `sync-connection-wrapper` feature)
2223
//!
2324
//! Ordinary usage of `diesel-async` assumes that you just replace the corresponding sync trait
2425
//! method calls and connections with their async counterparts.

src/run_query_dsl/mod.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,12 @@ pub trait RunQueryDsl<Conn>: Sized {
208208
/// .await?;
209209
/// assert_eq!(1, inserted_rows);
210210
///
211+
/// # #[cfg(not(feature = "sqlite"))]
211212
/// let inserted_rows = insert_into(users)
212213
/// .values(&vec![name.eq("Jim"), name.eq("James")])
213214
/// .execute(connection)
214215
/// .await?;
216+
/// # #[cfg(not(feature = "sqlite"))]
215217
/// assert_eq!(2, inserted_rows);
216218
/// # Ok(())
217219
/// # }
@@ -604,10 +606,12 @@ pub trait RunQueryDsl<Conn>: Sized {
604606
/// # async fn run_test() -> QueryResult<()> {
605607
/// # use schema::users::dsl::*;
606608
/// # let connection = &mut establish_connection().await;
607-
/// diesel::insert_into(users)
608-
/// .values(&vec![name.eq("Sean"), name.eq("Pascal")])
609-
/// .execute(connection)
610-
/// .await?;
609+
/// for n in &["Sean", "Pascal"] {
610+
/// diesel::insert_into(users)
611+
/// .values(name.eq(n))
612+
/// .execute(connection)
613+
/// .await?;
614+
/// }
611615
///
612616
/// let first_name = users.order(id)
613617
/// .select(name)
@@ -678,13 +682,15 @@ impl<T, Conn> RunQueryDsl<Conn> for T {}
678682
/// # use self::animals::dsl::*;
679683
/// # let connection = &mut establish_connection().await;
680684
/// let form = AnimalForm { id: 2, name: "Super scary" };
685+
/// # #[cfg(not(feature = "sqlite"))]
681686
/// let changed_animal = form.save_changes(connection).await?;
682687
/// let expected_animal = Animal {
683688
/// id: 2,
684689
/// species: String::from("spider"),
685690
/// legs: 8,
686691
/// name: Some(String::from("Super scary")),
687692
/// };
693+
/// # #[cfg(not(feature = "sqlite"))]
688694
/// assert_eq!(expected_animal, changed_animal);
689695
/// # Ok(())
690696
/// # }

src/sync_connection_wrapper.rs

+32
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,38 @@ fn from_tokio_join_error(join_error: JoinError) -> diesel::result::Error {
3737
/// * it's a [`diesel::connection::LoadConnection`]
3838
/// * its [`diesel::connection::Connection::Backend`] has a [`diesel::query_builder::BindCollector`] implementing [`diesel::query_builder::MoveableBindCollector`]
3939
/// * its [`diesel::connection::LoadConnection::Row`] implements [`diesel::row::IntoOwnedRow`]
40+
///
41+
/// Internally this wrapper type will use `spawn_blocking` on tokio
42+
/// to execute the request on the inner connection. This implies a
43+
/// dependency on tokio and that the runtime is running.
44+
///
45+
/// Note that only SQLite is supported at the moment.
46+
///
47+
/// # Examples
48+
///
49+
/// ```rust
50+
/// # include!("doctest_setup.rs");
51+
/// use diesel_async::RunQueryDsl;
52+
/// use schema::users;
53+
///
54+
/// async fn some_async_fn() {
55+
/// # let database_url = database_url();
56+
/// use diesel_async::AsyncConnection;
57+
/// use diesel::sqlite::SqliteConnection;
58+
/// let mut conn =
59+
/// SyncConnectionWrapper::<SqliteConnection>::establish(&database_url).await.unwrap();
60+
/// # create_tables(&mut conn).await;
61+
///
62+
/// let all_users = users::table.load::<(i32, String)>(&mut conn).await.unwrap();
63+
/// # assert_eq!(all_users.len(), 2);
64+
/// }
65+
///
66+
/// # #[cfg(feature = "sqlite")]
67+
/// # #[tokio::main]
68+
/// # async fn main() {
69+
/// # some_async_fn().await;
70+
/// # }
71+
/// ```
4072
pub struct SyncConnectionWrapper<C> {
4173
inner: Arc<Mutex<C>>,
4274
}

0 commit comments

Comments
 (0)