0.7.0 release (#2575)

* WIP preparing 0.7.0 release

* fix: re-enable examples

* fix doctests in `sqlx-core`

* cherry-pick CHANGELOG entry for 0.6.3

* add actions workflow for examples

* fix(cli): close connection after running migrations

* fix examples

* fix(sqlite): fix parsing of URLs via `Any`

* fix(example): don't let Postgres `listen` example run forever

* fix Postgres `transaction` example
This commit is contained in:
Austin Bonander
2023-07-03 14:37:37 -07:00
committed by GitHub
parent 1bdbedabdc
commit dcb58b0e2c
26 changed files with 1392 additions and 107 deletions

View File

@@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
# Primary crates
axum = { version = "0.5.13", features = ["macros"] }
sqlx = { version = "0.6.2", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }
sqlx = { path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }
tokio = { version = "1.20.1", features = ["rt-multi-thread", "macros"] }
# Important secondary crates

View File

@@ -1,5 +1,5 @@
[package]
name = "files"
name = "sqlx-example-postgres-files"
version = "0.1.0"
edition = "2021"
@@ -8,5 +8,5 @@ edition = "2021"
[dependencies]
anyhow = "1.0"
sqlx = { path = "../../../", features = ["postgres", "runtime-tokio-native-tls"] }
tokio = { version = "1.20.0", features = ["macros"]}
tokio = { version = "1.20.0", features = ["rt", "macros"]}
dotenvy = "0.15.0"

View File

@@ -26,7 +26,7 @@ impl Display for PostWithAuthorQuery {
}
}
#[tokio::main]
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let pool = PgPool::connect(&dotenvy::var("DATABASE_URL")?).await?;

View File

@@ -1,5 +1,5 @@
[package]
name = "json"
name = "sqlx-example-postgres-json"
version = "0.1.0"
edition = "2021"
workspace = "../../../"
@@ -10,6 +10,6 @@ dotenvy = "0.15.0"
futures = "0.3"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sqlx = { path = "../../../", features = ["postgres", "json"] }
sqlx = { path = "../../../", features = ["runtime-tokio", "postgres", "json"] }
structopt = "0.3"
tokio = { version = "1.20.0", features = ["macros"]}
tokio = { version = "1.20.0", features = ["rt", "macros"]}

View File

@@ -30,7 +30,7 @@ struct Row {
person: Json<Person>,
}
#[tokio::main]
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let args = Args::from_args_safe()?;
let pool = PgPool::connect(&dotenvy::var("DATABASE_URL")?).await?;

View File

@@ -5,6 +5,6 @@ edition = "2021"
workspace = "../../../"
[dependencies]
sqlx = { path = "../../../", features = [ "postgres" ] }
sqlx = { path = "../../../", features = [ "runtime-tokio", "postgres" ] }
futures = "0.3.1"
tokio = { version = "1.20.0", features = ["macros"]}
tokio = { version = "1.20.0", features = ["rt-multi-thread", "macros", "time"]}

View File

@@ -2,9 +2,16 @@ use futures::StreamExt;
use futures::TryStreamExt;
use sqlx::postgres::PgListener;
use sqlx::{Executor, PgPool};
use std::pin;
use std::pin::pin;
use std::sync::atomic::{AtomicI64, Ordering};
use std::time::Duration;
/// How long to sit in the listen loop before exiting.
///
/// This ensures the example eventually exits, which is required for automated testing.
const LISTEN_DURATION: Duration = Duration::from_secs(5);
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Building PG pool.");
@@ -12,13 +19,16 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
std::env::var("DATABASE_URL").expect("Env var DATABASE_URL is required for this example.");
let pool = sqlx::PgPool::connect(&conn_str).await?;
let mut listener = PgListener::connect(&conn_str).await?;
let mut listener = PgListener::connect_with(&pool).await?;
// let notify_pool = pool.clone();
let _t = async_std::task::spawn(async move {
stream::interval(Duration::from_secs(2))
.for_each(|_| notify(&pool))
.await
let notify_pool = pool.clone();
let _t = tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(2));
while !notify_pool.is_closed() {
interval.tick().await;
notify(&notify_pool).await;
}
});
println!("Starting LISTEN loop.");
@@ -40,10 +50,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
listener.execute("SELECT pg_sleep(6)").await?;
let mut stream = listener.into_stream();
while let Some(notification) = stream.try_next().await? {
println!("[from stream]: {:?}", notification);
// `Sleep` must be pinned
let mut timeout = pin!(tokio::time::sleep(LISTEN_DURATION));
loop {
tokio::select! {
res = stream.try_next() => {
if let Some(notification) = res? {
println!("[from stream]: {:?}", notification);
} else {
break;
}
},
_ = timeout.as_mut() => {
// Don't run forever
break;
}
}
}
pool.close().await;
Ok(())
}

View File

@@ -9,7 +9,7 @@ anyhow = "1.0"
futures = "0.3"
sqlx = { path = "../../../", features = ["postgres", "runtime-tokio-native-tls"] }
structopt = "0.3"
tokio = { version = "1.20.0", features = ["macros"]}
tokio = { version = "1.20.0", features = ["rt", "macros"]}
dotenvy = "0.15.0"
async-trait = "0.1.41"
mockall = "0.11"

View File

@@ -15,7 +15,7 @@ enum Command {
Done { id: i64 },
}
#[tokio::main]
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
dotenvy::dotenv().ok();
let args = Args::from_args_safe()?;

View File

@@ -9,5 +9,5 @@ anyhow = "1.0"
futures = "0.3"
sqlx = { path = "../../../", features = ["postgres", "runtime-tokio-native-tls"] }
structopt = "0.3"
tokio = { version = "1.20.0", features = ["macros"]}
tokio = { version = "1.20.0", features = ["rt", "macros"]}
dotenvy = "0.15.0"

View File

@@ -14,7 +14,7 @@ enum Command {
Done { id: i64 },
}
#[tokio::main]
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let args = Args::from_args_safe()?;
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;

View File

@@ -7,4 +7,4 @@ workspace = "../../../"
[dependencies]
sqlx = { path = "../../../", features = [ "postgres", "runtime-tokio-native-tls" ] }
futures = "0.3.1"
tokio = { version = "1.20.0", features = ["macros"]}
tokio = { version = "1.20.0", features = ["rt-multi-thread", "macros"]}

View File

@@ -11,12 +11,14 @@ async fn insert_and_verify(
test_id,
"test todo"
)
.execute(&mut *transaction)
// In 0.7, `Transaction` can no longer implement `Executor` directly,
// so it must be dereferenced to the internal connection type.
.execute(&mut **transaction)
.await?;
// check that inserted todo can be fetched inside the uncommitted transaction
let _ = query!(r#"SELECT FROM todos WHERE id = $1"#, test_id)
.fetch_one(transaction)
.fetch_one(&mut **transaction)
.await?;
Ok(())