Add PgBindIter for encoding and use it as the implementation encoding &[T] (#3651)

* Add PgBindIter for encoding and use it as the implementation encoding &[T]

* Implement suggestions from review

* Add docs to PgBindIter and test to ensure it works for owned and borrowed types

* Use extension trait for iterators to allow code to flow better. Make struct private. Don't reference unneeded generic T. Make doc tests compile.

* Fix doc function

* Fix doc test to actually compile

* Use Cell<Option<I>> instead of Clone bound
This commit is contained in:
Tyler Hawkes
2025-07-04 18:59:38 -06:00
committed by GitHub
parent 60f67dbc39
commit 97de03482c
4 changed files with 215 additions and 29 deletions

View File

@@ -2069,6 +2069,62 @@ async fn test_issue_3052() {
}
#[sqlx_macros::test]
async fn test_bind_iter() -> anyhow::Result<()> {
use sqlx::postgres::PgBindIterExt;
use sqlx::types::chrono::{DateTime, Utc};
let mut conn = new::<Postgres>().await?;
#[derive(sqlx::FromRow, PartialEq, Debug)]
struct Person {
id: i64,
name: String,
birthdate: DateTime<Utc>,
}
let people: Vec<Person> = vec![
Person {
id: 1,
name: "Alice".into(),
birthdate: "1984-01-01T00:00:00Z".parse().unwrap(),
},
Person {
id: 2,
name: "Bob".into(),
birthdate: "2000-01-01T00:00:00Z".parse().unwrap(),
},
];
sqlx::query(
r#"
create temporary table person(
id int8 primary key,
name text not null,
birthdate timestamptz not null
)"#,
)
.execute(&mut conn)
.await?;
let rows_affected =
sqlx::query("insert into person(id, name, birthdate) select * from unnest($1, $2, $3)")
// owned value
.bind(people.iter().map(|p| p.id).bind_iter())
// borrowed value
.bind(people.iter().map(|p| &p.name).bind_iter())
.bind(people.iter().map(|p| &p.birthdate).bind_iter())
.execute(&mut conn)
.await?
.rows_affected();
assert_eq!(rows_affected, 2);
let p_query = sqlx::query_as::<_, Person>("select * from person order by id")
.fetch_all(&mut conn)
.await?;
assert_eq!(people, p_query);
Ok(())
}
async fn test_pg_copy_chunked() -> anyhow::Result<()> {
let mut conn = new::<Postgres>().await?;