diff --git a/benches/execution/cornucopia_benches.rs b/benches/execution/cornucopia_benches.rs index 46343a75..cbfd7010 100644 --- a/benches/execution/cornucopia_benches.rs +++ b/benches/execution/cornucopia_benches.rs @@ -12,12 +12,12 @@ use self::generated::queries::bench::{ mod generated; pub fn bench_trivial_query(b: &mut Bencher, client: &Client) { - let mut stmt = users(); + let stmt = block_on(async { users().prepare(client).await.unwrap() }); b.iter(|| block_on(async { stmt.bind(client).all().await.unwrap() })) } pub fn bench_medium_complex_query(b: &mut Bencher, client: &Client) { - let mut stmt = select_complex(); + let stmt = block_on(async { select_complex().prepare(client).await.unwrap() }); b.iter(|| { block_on(async { stmt.bind(client) @@ -44,7 +44,7 @@ pub fn bench_medium_complex_query(b: &mut Bencher, client: &Client) { } pub fn bench_insert(b: &mut Bencher, client: &mut Client, size: usize) { - let mut stmt = insert_user(); + let stmt = block_on(async { insert_user().prepare(client).await.unwrap() }); b.iter(|| { block_on(async { let tx = client.transaction().await.unwrap(); @@ -59,9 +59,9 @@ pub fn bench_insert(b: &mut Bencher, client: &mut Client, size: usize) { } pub fn loading_associations_sequentially(b: &mut Bencher, client: &Client) { - let mut user_stmt = users(); - let mut post_stmt = post_by_user_ids(); - let mut comment_stmt = comments_by_post_id(); + let user_stmt = block_on(async { users().prepare(client).await.unwrap() }); + let post_stmt = block_on(async { post_by_user_ids().prepare(client).await.unwrap() }); + let comment_stmt = block_on(async { comments_by_post_id().prepare(client).await.unwrap() }); b.iter(|| { block_on(async { let users = user_stmt.bind(client).all().await.unwrap(); @@ -118,12 +118,12 @@ pub mod sync { Comment, Post, User, }; pub fn bench_trivial_query(b: &mut Bencher, client: &mut Client) { - let mut stmt = users(); + let stmt = users().prepare(client).unwrap(); b.iter(|| stmt.bind(client).all().unwrap()) } pub fn bench_medium_complex_query(b: &mut Bencher, client: &mut Client) { - let mut stmt = select_complex(); + let stmt = select_complex().prepare(client).unwrap(); b.iter(|| { stmt.bind(client) .map(|it| { @@ -147,7 +147,7 @@ pub mod sync { } pub fn bench_insert(b: &mut Bencher, client: &mut Client, size: usize) { - let mut stmt = insert_user(); + let stmt = insert_user().prepare(client).unwrap(); b.iter(|| { let mut tx = client.transaction().unwrap(); for x in 0..size { @@ -159,9 +159,9 @@ pub mod sync { } pub fn loading_associations_sequentially(b: &mut Bencher, client: &mut Client) { - let mut user_stmt = users(); - let mut post_stmt = post_by_user_ids(); - let mut comment_stmt = comments_by_post_id(); + let user_stmt = users().prepare(client).unwrap(); + let post_stmt = post_by_user_ids().prepare(client).unwrap(); + let comment_stmt = comments_by_post_id().prepare(client).unwrap(); b.iter(|| { let users = user_stmt.bind(client).all().unwrap(); diff --git a/benches/execution/cornucopia_benches/generated.rs b/benches/execution/cornucopia_benches/generated.rs index 33f68dd2..efe2e69a 100644 --- a/benches/execution/cornucopia_benches/generated.rs +++ b/benches/execution/cornucopia_benches/generated.rs @@ -138,11 +138,13 @@ pub mod queries { } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct UserQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::UserBorrowed, mapper: fn(super::UserBorrowed) -> T, } @@ -157,43 +159,54 @@ pub mod queries { UserQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct PostQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::PostBorrowed, mapper: fn(super::PostBorrowed) -> T, } @@ -208,43 +221,54 @@ pub mod queries { PostQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct CommentQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::CommentBorrowed, mapper: fn(super::CommentBorrowed) -> T, } @@ -259,43 +283,54 @@ pub mod queries { CommentQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct SelectComplexQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::SelectComplexBorrowed, mapper: fn(super::SelectComplexBorrowed) -> T, } @@ -310,52 +345,70 @@ pub mod queries { SelectComplexQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn users() -> UsersStmt { - UsersStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM users")) + UsersStmt("SELECT * FROM users", None) } - pub struct UsersStmt(cornucopia_sync::private::Stmt); + pub struct UsersStmt(&'static str, Option); impl UsersStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> UserQuery<'a, C, super::User, 0> { UserQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::UserBorrowed { id: row.get(0), name: row.get(1), @@ -366,25 +419,29 @@ pub mod queries { } } pub fn insert_user() -> InsertUserStmt { - InsertUserStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO users (name, hair_color) VALUES ($1, $2)", - )) + InsertUserStmt("INSERT INTO users (name, hair_color) VALUES ($1, $2)", None) } - pub struct InsertUserStmt(cornucopia_sync::private::Stmt); + pub struct InsertUserStmt(&'static str, Option); impl InsertUserStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, T1: cornucopia_sync::StringSql, T2: cornucopia_sync::StringSql, >( - &'a mut self, + &'a self, client: &'a mut C, name: &'a T1, hair_color: &'a Option, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[name, hair_color]) + client.execute(self.0, &[name, hair_color]) } } impl< @@ -401,7 +458,7 @@ pub mod queries { > for InsertUserStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::InsertUserParams, ) -> Result { @@ -409,18 +466,26 @@ pub mod queries { } } pub fn posts() -> PostsStmt { - PostsStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM posts")) + PostsStmt("SELECT * FROM posts", None) } - pub struct PostsStmt(cornucopia_sync::private::Stmt); + pub struct PostsStmt(&'static str, Option); impl PostsStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> PostQuery<'a, C, super::Post, 0> { PostQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::PostBorrowed { id: row.get(0), user_id: row.get(1), @@ -432,21 +497,27 @@ pub mod queries { } } pub fn post_by_user_ids() -> PostByUserIdsStmt { - PostByUserIdsStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM posts WHERE user_id = ANY($1)", - )) + PostByUserIdsStmt("SELECT * FROM posts WHERE user_id = ANY($1)", None) } - pub struct PostByUserIdsStmt(cornucopia_sync::private::Stmt); + pub struct PostByUserIdsStmt(&'static str, Option); impl PostByUserIdsStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::ArraySql>( - &'a mut self, + &'a self, client: &'a mut C, ids: &'a T1, ) -> PostQuery<'a, C, super::Post, 1> { PostQuery { client, params: [ids], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::PostBorrowed { id: row.get(0), user_id: row.get(1), @@ -458,20 +529,26 @@ pub mod queries { } } pub fn comments() -> CommentsStmt { - CommentsStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM comments", - )) + CommentsStmt("SELECT * FROM comments", None) } - pub struct CommentsStmt(cornucopia_sync::private::Stmt); + pub struct CommentsStmt(&'static str, Option); impl CommentsStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> CommentQuery<'a, C, super::Comment, 0> { CommentQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::CommentBorrowed { id: row.get(0), post_id: row.get(1), @@ -482,21 +559,27 @@ pub mod queries { } } pub fn comments_by_post_id() -> CommentsByPostIdStmt { - CommentsByPostIdStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM comments WHERE post_id = ANY($1)", - )) + CommentsByPostIdStmt("SELECT * FROM comments WHERE post_id = ANY($1)", None) } - pub struct CommentsByPostIdStmt(cornucopia_sync::private::Stmt); + pub struct CommentsByPostIdStmt(&'static str, Option); impl CommentsByPostIdStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::ArraySql>( - &'a mut self, + &'a self, client: &'a mut C, ids: &'a T1, ) -> CommentQuery<'a, C, super::Comment, 1> { CommentQuery { client, params: [ids], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::CommentBorrowed { id: row.get(0), post_id: row.get(1), @@ -507,18 +590,26 @@ pub mod queries { } } pub fn select_complex() -> SelectComplexStmt { - SelectComplexStmt(cornucopia_sync :: private :: Stmt :: new("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id")) + SelectComplexStmt("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id", None) } - pub struct SelectComplexStmt(cornucopia_sync::private::Stmt); + pub struct SelectComplexStmt(&'static str, Option); impl SelectComplexStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> SelectComplexQuery<'a, C, super::SelectComplex, 0> { SelectComplexQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectComplexBorrowed { myuser_id: row.get(0), name: row.get(1), @@ -540,7 +631,8 @@ pub mod queries { pub struct UserQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::UserBorrowed, mapper: fn(super::UserBorrowed) -> T, } @@ -555,26 +647,34 @@ pub mod queries { UserQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -582,20 +682,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct PostQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::PostBorrowed, mapper: fn(super::PostBorrowed) -> T, } @@ -610,26 +714,34 @@ pub mod queries { PostQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -637,20 +749,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct CommentQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::CommentBorrowed, mapper: fn(super::CommentBorrowed) -> T, } @@ -665,26 +781,34 @@ pub mod queries { CommentQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -692,20 +816,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct SelectComplexQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::SelectComplexBorrowed, mapper: fn(super::SelectComplexBorrowed) -> T, } @@ -720,26 +848,34 @@ pub mod queries { SelectComplexQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -747,29 +883,40 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn users() -> UsersStmt { - UsersStmt(cornucopia_async::private::Stmt::new("SELECT * FROM users")) + UsersStmt("SELECT * FROM users", None) } - pub struct UsersStmt(cornucopia_async::private::Stmt); + pub struct UsersStmt(&'static str, Option); impl UsersStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> UserQuery<'a, C, super::User, 0> { UserQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::UserBorrowed { id: row.get(0), name: row.get(1), @@ -780,25 +927,29 @@ pub mod queries { } } pub fn insert_user() -> InsertUserStmt { - InsertUserStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO users (name, hair_color) VALUES ($1, $2)", - )) + InsertUserStmt("INSERT INTO users (name, hair_color) VALUES ($1, $2)", None) } - pub struct InsertUserStmt(cornucopia_async::private::Stmt); + pub struct InsertUserStmt(&'static str, Option); impl InsertUserStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind< 'a, C: GenericClient, T1: cornucopia_async::StringSql, T2: cornucopia_async::StringSql, >( - &'a mut self, + &'a self, client: &'a C, name: &'a T1, hair_color: &'a Option, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[name, hair_color]).await + client.execute(self.0, &[name, hair_color]).await } } impl< @@ -821,7 +972,7 @@ pub mod queries { > for InsertUserStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::InsertUserParams, ) -> std::pin::Pin< @@ -835,18 +986,26 @@ pub mod queries { } } pub fn posts() -> PostsStmt { - PostsStmt(cornucopia_async::private::Stmt::new("SELECT * FROM posts")) + PostsStmt("SELECT * FROM posts", None) } - pub struct PostsStmt(cornucopia_async::private::Stmt); + pub struct PostsStmt(&'static str, Option); impl PostsStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> PostQuery<'a, C, super::Post, 0> { PostQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::PostBorrowed { id: row.get(0), user_id: row.get(1), @@ -858,21 +1017,27 @@ pub mod queries { } } pub fn post_by_user_ids() -> PostByUserIdsStmt { - PostByUserIdsStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM posts WHERE user_id = ANY($1)", - )) + PostByUserIdsStmt("SELECT * FROM posts WHERE user_id = ANY($1)", None) } - pub struct PostByUserIdsStmt(cornucopia_async::private::Stmt); + pub struct PostByUserIdsStmt(&'static str, Option); impl PostByUserIdsStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::ArraySql>( - &'a mut self, + &'a self, client: &'a C, ids: &'a T1, ) -> PostQuery<'a, C, super::Post, 1> { PostQuery { client, params: [ids], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::PostBorrowed { id: row.get(0), user_id: row.get(1), @@ -884,20 +1049,26 @@ pub mod queries { } } pub fn comments() -> CommentsStmt { - CommentsStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM comments", - )) + CommentsStmt("SELECT * FROM comments", None) } - pub struct CommentsStmt(cornucopia_async::private::Stmt); + pub struct CommentsStmt(&'static str, Option); impl CommentsStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> CommentQuery<'a, C, super::Comment, 0> { CommentQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::CommentBorrowed { id: row.get(0), post_id: row.get(1), @@ -908,21 +1079,27 @@ pub mod queries { } } pub fn comments_by_post_id() -> CommentsByPostIdStmt { - CommentsByPostIdStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM comments WHERE post_id = ANY($1)", - )) + CommentsByPostIdStmt("SELECT * FROM comments WHERE post_id = ANY($1)", None) } - pub struct CommentsByPostIdStmt(cornucopia_async::private::Stmt); + pub struct CommentsByPostIdStmt(&'static str, Option); impl CommentsByPostIdStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::ArraySql>( - &'a mut self, + &'a self, client: &'a C, ids: &'a T1, ) -> CommentQuery<'a, C, super::Comment, 1> { CommentQuery { client, params: [ids], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::CommentBorrowed { id: row.get(0), post_id: row.get(1), @@ -933,18 +1110,26 @@ pub mod queries { } } pub fn select_complex() -> SelectComplexStmt { - SelectComplexStmt(cornucopia_async :: private :: Stmt :: new("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id")) + SelectComplexStmt("SELECT u.id as myuser_id, u.name, u.hair_color, p.id as post_id, p.user_id, p.title, p.body FROM users as u LEFT JOIN posts as p on u.id = p.user_id", None) } - pub struct SelectComplexStmt(cornucopia_async::private::Stmt); + pub struct SelectComplexStmt(&'static str, Option); impl SelectComplexStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> SelectComplexQuery<'a, C, super::SelectComplex, 0> { SelectComplexQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectComplexBorrowed { myuser_id: row.get(0), name: row.get(1), diff --git a/benches/execution/main.rs b/benches/execution/main.rs index 64d07a86..6db5f5be 100644 --- a/benches/execution/main.rs +++ b/benches/execution/main.rs @@ -126,8 +126,8 @@ fn prepare_full(client: &mut Client) { } fn bench(c: &mut Criterion) { - cornucopia::container::cleanup(false).ok(); - cornucopia::container::setup(false).unwrap(); + cornucopia::container::cleanup(true).ok(); + cornucopia::container::setup(true).unwrap(); let client = &mut cornucopia_conn().unwrap(); let rt: &'static Runtime = Box::leak(Box::new(Runtime::new().unwrap())); let async_client = &mut rt.block_on(async { @@ -144,7 +144,7 @@ fn bench(c: &mut Criterion) { &mut PgConnection::establish("postgresql://postgres:postgres@127.0.0.1:5435/postgres") .unwrap(); - cornucopia::load_schema(client, &["usage/cornucopia_benches/schema.sql"]).unwrap(); + cornucopia::load_schema(client, &["execution/cornucopia_benches/schema.sql"]).unwrap(); { let mut group = c.benchmark_group("bench_trivial_query"); for size in QUERY_SIZE { @@ -237,7 +237,7 @@ fn bench(c: &mut Criterion) { group.finish(); } - cornucopia::container::cleanup(false).unwrap(); + cornucopia::container::cleanup(true).unwrap(); } criterion::criterion_group!(benches, bench); criterion::criterion_main!(benches); diff --git a/crates/client_async/src/deadpool.rs b/crates/client_async/src/deadpool.rs index 8d0a78cd..acd45d01 100644 --- a/crates/client_async/src/deadpool.rs +++ b/crates/client_async/src/deadpool.rs @@ -15,6 +15,10 @@ impl GenericClient for DeadpoolClient { ClientWrapper::prepare_cached(self, query).await } + fn stmt_cache() -> bool { + true + } + async fn execute( &self, query: &T, @@ -76,6 +80,10 @@ impl GenericClient for DeadpoolTransaction<'_> { DeadpoolTransaction::prepare_cached(self, query).await } + fn stmt_cache() -> bool { + true + } + async fn execute( &self, query: &T, diff --git a/crates/client_async/src/generic_client.rs b/crates/client_async/src/generic_client.rs index e0042c9b..b44fea5d 100644 --- a/crates/client_async/src/generic_client.rs +++ b/crates/client_async/src/generic_client.rs @@ -1,6 +1,7 @@ use async_trait::async_trait; use tokio_postgres::{ - types::BorrowToSql, Client, Error, RowStream, Statement, ToStatement, Transaction, + types::{BorrowToSql, ToSql}, + Client, Error, Row, RowStream, Statement, ToStatement, Transaction, }; /// Abstraction over multiple types of asynchronous clients. @@ -11,34 +12,29 @@ use tokio_postgres::{ #[async_trait] pub trait GenericClient: Send + Sync { async fn prepare(&self, query: &str) -> Result; - async fn execute( - &self, - query: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result + fn stmt_cache() -> bool { + false + } + async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + T: ?Sized + ToStatement + Sync + Send; async fn query_one( &self, statement: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result + params: &[&(dyn ToSql + Sync)], + ) -> Result where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + T: ?Sized + ToStatement + Sync + Send; async fn query_opt( &self, statement: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result, Error> + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send; - async fn query( - &self, - query: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result, Error> + T: ?Sized + ToStatement + Sync + Send; + async fn query(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send; + T: ?Sized + ToStatement + Sync + Send; async fn query_raw(&self, statement: &T, params: I) -> Result where @@ -54,13 +50,9 @@ impl GenericClient for Transaction<'_> { Transaction::prepare(self, query).await } - async fn execute( - &self, - query: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result + async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Transaction::execute(self, query, params).await } @@ -68,10 +60,10 @@ impl GenericClient for Transaction<'_> { async fn query_one( &self, statement: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result + params: &[&(dyn ToSql + Sync)], + ) -> Result where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Transaction::query_one(self, statement, params).await } @@ -79,21 +71,17 @@ impl GenericClient for Transaction<'_> { async fn query_opt( &self, statement: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result, Error> + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Transaction::query_opt(self, statement, params).await } - async fn query( - &self, - query: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result, Error> + async fn query(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Transaction::query(self, query, params).await } @@ -115,13 +103,9 @@ impl GenericClient for Client { Client::prepare(self, query).await } - async fn execute( - &self, - query: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result + async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Client::execute(self, query, params).await } @@ -129,10 +113,10 @@ impl GenericClient for Client { async fn query_one( &self, statement: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result + params: &[&(dyn ToSql + Sync)], + ) -> Result where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Client::query_one(self, statement, params).await } @@ -140,21 +124,17 @@ impl GenericClient for Client { async fn query_opt( &self, statement: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result, Error> + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Client::query_opt(self, statement, params).await } - async fn query( - &self, - query: &T, - params: &[&(dyn tokio_postgres::types::ToSql + Sync)], - ) -> Result, Error> + async fn query(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> where - T: ?Sized + tokio_postgres::ToStatement + Sync + Send, + T: ?Sized + ToStatement + Sync + Send, { Client::query(self, query, params).await } diff --git a/crates/client_async/src/lib.rs b/crates/client_async/src/lib.rs index ddded593..f2368e3f 100644 --- a/crates/client_async/src/lib.rs +++ b/crates/client_async/src/lib.rs @@ -1,8 +1,8 @@ #[doc(hidden)] pub mod private; -pub use crate::generic_client::GenericClient; pub use cornucopia_client_core::{ArrayIterator, ArraySql, BytesSql, IterSql, StringSql}; +pub use generic_client::GenericClient; #[cfg(feature = "with-serde_json-1")] pub use cornucopia_client_core::JsonSql; @@ -14,5 +14,5 @@ mod generic_client; /// This trait allows you to bind parameters to a query using a single /// struct, rather than passing each bind parameter as a function parameter. pub trait Params<'a, P, O, C> { - fn params(&'a mut self, client: &'a C, params: &'a P) -> O; + fn params(&'a self, client: &'a C, params: &'a P) -> O; } diff --git a/crates/client_async/src/private.rs b/crates/client_async/src/private.rs index 5ab675d9..f05d59c7 100644 --- a/crates/client_async/src/private.rs +++ b/crates/client_async/src/private.rs @@ -1,32 +1,60 @@ pub use cornucopia_client_core::{slice_iter, Domain, DomainArray}; +use tokio_postgres::{ + types::{BorrowToSql, ToSql}, + Error, Row, RowStream, Statement, +}; -use crate::generic_client::GenericClient; -use tokio_postgres::{Error, Statement}; +use crate::GenericClient; -/// Cached statement -pub struct Stmt { - query: &'static str, - cached: Option, +pub async fn one( + client: &C, + query: &str, + params: &[&(dyn ToSql + Sync)], + cached: Option<&Statement>, +) -> Result { + if let Some(cached) = cached { + client.query_one(cached, params).await + } else if C::stmt_cache() { + let cached = client.prepare(query).await?; + client.query_one(&cached, params).await + } else { + client.query_one(query, params).await + } } -impl Stmt { - #[must_use] - pub fn new(query: &'static str) -> Self { - Self { - query, - cached: None, - } +pub async fn opt( + client: &C, + query: &str, + params: &[&(dyn ToSql + Sync)], + cached: Option<&Statement>, +) -> Result, Error> { + if let Some(cached) = cached { + client.query_opt(cached, params).await + } else if C::stmt_cache() { + let cached = client.prepare(query).await?; + client.query_opt(&cached, params).await + } else { + client.query_opt(query, params).await } +} - pub async fn prepare<'a, C: GenericClient>( - &'a mut self, - client: &C, - ) -> Result<&'a Statement, Error> { - if self.cached.is_none() { - let stmt = client.prepare(self.query).await?; - self.cached = Some(stmt); - } - // the statement is always prepared at this point - Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) +pub async fn raw( + client: &C, + query: &str, + params: I, + cached: Option<&Statement>, +) -> Result +where + P: BorrowToSql, + I: IntoIterator + Sync + Send, + I::IntoIter: ExactSizeIterator, +{ + if let Some(cached) = cached { + client.query_raw(cached, params).await + } else if C::stmt_cache() { + let cached = client.prepare(query).await?; + client.query_raw(&cached, params).await + } else { + client.query_raw(query, params).await } } diff --git a/crates/client_sync/src/generic_client.rs b/crates/client_sync/src/generic_client.rs new file mode 100644 index 00000000..eeb764c5 --- /dev/null +++ b/crates/client_sync/src/generic_client.rs @@ -0,0 +1,132 @@ +use postgres::{ + types::{BorrowToSql, ToSql}, + Client, Error, Row, RowIter, Statement, ToStatement, Transaction, +}; + +/// Abstraction over multiple types of synchronous clients. +/// This allows you to use postgres clients and transactions interchangeably. +pub trait GenericClient { + fn prepare(&mut self, query: &str) -> Result; + fn stmt_cache() -> bool { + false + } + fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement; + fn query_one(&mut self, statement: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement; + fn query_opt( + &mut self, + statement: &T, + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + ToStatement; + fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> + where + T: ?Sized + ToStatement; + + fn query_raw(&mut self, statement: &T, params: I) -> Result, Error> + where + T: ?Sized + ToStatement, + P: BorrowToSql, + I: IntoIterator, + I::IntoIter: ExactSizeIterator; +} + +impl GenericClient for Transaction<'_> { + fn prepare(&mut self, query: &str) -> Result { + Transaction::prepare(self, query) + } + + fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + Transaction::execute(self, query, params) + } + + fn query_one(&mut self, statement: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + Transaction::query_one(self, statement, params) + } + + fn query_opt( + &mut self, + statement: &T, + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + ToStatement, + { + Transaction::query_opt(self, statement, params) + } + + fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> + where + T: ?Sized + ToStatement, + { + Transaction::query(self, query, params) + } + + fn query_raw(&mut self, statement: &T, params: I) -> Result, Error> + where + T: ?Sized + ToStatement, + P: BorrowToSql, + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + Transaction::query_raw(self, statement, params) + } +} + +impl GenericClient for Client { + fn prepare(&mut self, query: &str) -> Result { + Client::prepare(self, query) + } + + fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + Client::execute(self, query, params) + } + + fn query_one(&mut self, statement: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + Client::query_one(self, statement, params) + } + + fn query_opt( + &mut self, + statement: &T, + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + ToStatement, + { + Client::query_opt(self, statement, params) + } + + fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> + where + T: ?Sized + ToStatement, + { + Client::query(self, query, params) + } + + fn query_raw(&mut self, statement: &T, params: I) -> Result, Error> + where + T: ?Sized + ToStatement, + P: BorrowToSql, + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + Client::query_raw(self, statement, params) + } +} diff --git a/crates/client_sync/src/lib.rs b/crates/client_sync/src/lib.rs index 84c4c7f5..042ce5a1 100644 --- a/crates/client_sync/src/lib.rs +++ b/crates/client_sync/src/lib.rs @@ -2,12 +2,15 @@ pub mod private; pub use cornucopia_client_core::{ArrayIterator, ArraySql, BytesSql, IterSql, StringSql}; +pub use generic_client::GenericClient; #[cfg(feature = "with-serde_json-1")] pub use cornucopia_client_core::JsonSql; +mod generic_client; + /// This trait allows you to bind parameters to a query using a single /// struct, rather than passing each bind parameter as a function parameter. pub trait Params<'a, P, O, C> { - fn params(&'a mut self, client: &'a mut C, params: &'a P) -> O; + fn params(&'a self, client: &'a mut C, params: &'a P) -> O; } diff --git a/crates/client_sync/src/private.rs b/crates/client_sync/src/private.rs index fa01d7c8..1bb8e005 100644 --- a/crates/client_sync/src/private.rs +++ b/crates/client_sync/src/private.rs @@ -1,31 +1,60 @@ pub use cornucopia_client_core::{slice_iter, Domain, DomainArray}; +use postgres::{ + types::{BorrowToSql, ToSql}, + Error, Row, RowIter, Statement, +}; -use postgres::Statement; +use crate::GenericClient; -/// Cached statement -pub struct Stmt { - query: &'static str, - cached: Option, +pub fn one( + client: &mut C, + query: &str, + params: &[&(dyn ToSql + Sync)], + cached: Option<&Statement>, +) -> Result { + if let Some(cached) = cached { + client.query_one(cached, params) + } else if C::stmt_cache() { + let cached = client.prepare(query)?; + client.query_one(&cached, params) + } else { + client.query_one(query, params) + } } -impl Stmt { - #[must_use] - pub fn new(query: &'static str) -> Self { - Self { - query, - cached: None, - } +pub fn opt( + client: &mut C, + query: &str, + params: &[&(dyn ToSql + Sync)], + cached: Option<&Statement>, +) -> Result, Error> { + if let Some(cached) = cached { + client.query_opt(cached, params) + } else if C::stmt_cache() { + let cached = client.prepare(query)?; + client.query_opt(&cached, params) + } else { + client.query_opt(query, params) } +} - pub fn prepare<'a, C: postgres::GenericClient>( - &'a mut self, - client: &mut C, - ) -> Result<&'a Statement, postgres::Error> { - if self.cached.is_none() { - let stmt = client.prepare(self.query)?; - self.cached = Some(stmt); - } - // the statement is always prepared at this point - Ok(unsafe { self.cached.as_ref().unwrap_unchecked() }) +pub fn raw<'a, C: GenericClient, P, I>( + client: &'a mut C, + query: &str, + params: I, + cached: Option<&Statement>, +) -> Result, Error> +where + P: BorrowToSql, + I: IntoIterator, + I::IntoIter: ExactSizeIterator, +{ + if let Some(cached) = cached { + client.query_raw(cached, params) + } else if C::stmt_cache() { + let cached = client.prepare(query)?; + client.query_raw(&cached, params) + } else { + client.query_raw(query, params) } } diff --git a/crates/cornucopia/src/codegen.rs b/crates/cornucopia/src/codegen.rs index af6c4b8a..10798c98 100644 --- a/crates/cornucopia/src/codegen.rs +++ b/crates/cornucopia/src/codegen.rs @@ -425,7 +425,8 @@ fn gen_row_query(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { pub struct ${name}Query<'a, C: GenericClient, T, const N: usize> { client: &'a $client_mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut $client::private::Stmt, + query: &'static str, + cached: Option<&'a $backend::Statement>, extractor: fn(&$backend::Row) -> $row_struct, mapper: fn($row_struct) -> T, } @@ -434,15 +435,15 @@ fn gen_row_query(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { ${name}Query { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub $fn_async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)$fn_await?; - let row = self.client.query_one(stmt, &self.params)$fn_await?; + let row = $client::private::one(self.client, self.query, &self.params, self.cached)$fn_await?; Ok((self.mapper)((self.extractor)(&row))) } @@ -451,26 +452,19 @@ fn gen_row_query(w: &mut impl Write, row: &PreparedItem, ctx: &GenCtx) { } pub $fn_async fn opt(self) -> Result, $backend::Error> { - let stmt = self.stmt.prepare(self.client)$fn_await?; - Ok(self - .client - .query_opt(stmt, &self.params) - $fn_await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = $client::private::opt(self.client, self.query, &self.params, self.cached)$fn_await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub $fn_async fn iter( self, ) -> Result> + 'a, $backend::Error> { - let stmt = self.stmt.prepare(self.client)$fn_await?; - let it = self - .client - .query_raw(stmt, $client::private::slice_iter(&self.params)) - $fn_await? + let stream = $client::private::raw(self.client, self.query, $client::private::slice_iter(&self.params), self.cached)$fn_await?; + let mapped = stream $raw_pre .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) $raw_post; - Ok(it) + Ok(mapped) } }); } @@ -547,11 +541,12 @@ fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQu ) }; code!(w => - pub fn bind<'a, C: GenericClient,$($traits_idx: $traits,)>(&'a mut self, client: &'a $client_mut C, $($params_name: &'a $params_ty,) ) -> ${row_name}Query<'a,C, $row_struct_name, $nb_params> { + pub fn bind<'a, C: GenericClient, $($traits_idx: $traits,)>(&'a self, client: &'a $client_mut C, $($params_name: &'a $params_ty,) ) -> ${row_name}Query<'a,C, $row_struct_name, $nb_params> { ${row_name}Query { client, params: [$($params_name,)], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| { $!extractor }, mapper: |it| { $mapper }, } @@ -564,9 +559,8 @@ fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQu p.ty.sql_wrapped(&p.ident.rs, ctx) }); code!(w => - pub $fn_async fn bind<'a, C: GenericClient,$($traits_idx: $traits,)>(&'a mut self, client: &'a $client_mut C, $($params_name: &'a $params_ty,)) -> Result { - let stmt = self.0.prepare(client)$fn_await?; - client.execute(stmt, &[ $($params_wrap,) ])$fn_await + pub $fn_async fn bind<'a, C: GenericClient, $($traits_idx: $traits,)>(&'a self, client: &'a $client_mut C, $($params_name: &'a $params_ty,)) -> Result { + client.execute(self.0, &[ $($params_wrap,) ])$fn_await } ); } @@ -577,10 +571,15 @@ fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQu let name = &ident.rs; code!(w => pub fn $name() -> ${struct_name}Stmt { - ${struct_name}Stmt($client::private::Stmt::new("$sql")) + ${struct_name}Stmt("$sql", None) } - pub struct ${struct_name}Stmt($client::private::Stmt); + pub struct ${struct_name}Stmt(&'static str, Option<$backend::Statement>); impl ${struct_name}Stmt { + pub $fn_async fn prepare<'a, C: GenericClient>(mut self, client: &'a $client_mut C) -> Result { + self.1 = Some(client.prepare(self.0)$fn_await?); + Ok(self) + } + $!lazy_impl } ); @@ -606,7 +605,7 @@ fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQu let nb_params = param_field.len(); code!(w => impl <'a, C: GenericClient,$($traits_idx: $traits,)> $client::Params<'a, $param_path<$lifetime $($traits_idx,)>, ${name}Query<'a, C, $query_row_struct, $nb_params>, C> for ${struct_name}Stmt { - fn params(&'a mut self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> ${name}Query<'a, C, $query_row_struct, $nb_params> { + fn params(&'a self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> ${name}Query<'a, C, $query_row_struct, $nb_params> { self.bind(client, $(¶ms.$params_name,)) } } @@ -625,7 +624,7 @@ fn gen_query_fn(w: &mut W, module: &PreparedModule, query: &PreparedQu }; code!(w => impl <'a, C: GenericClient $send_sync, $($traits_idx: $traits,)> $client::Params<'a, $param_path<$lifetime $($traits_idx,)>, $pre_ty$post_ty_lf, C> for ${struct_name}Stmt { - fn params(&'a mut self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> $pre_ty$post_ty_lf { + fn params(&'a self, client: &'a $client_mut C, params: &'a $param_path<$lifetime $($traits_idx,)>) -> $pre_ty$post_ty_lf { $pre.bind(client, $(¶ms.$params_name,))$post } } @@ -778,7 +777,7 @@ pub(crate) fn generate(preparation: Preparation, settings: CodegenSettings) -> S let import = if is_async { "use futures::{StreamExt, TryStreamExt};use futures; use cornucopia_async::GenericClient;" } else { - "use postgres::{fallible_iterator::FallibleIterator,GenericClient};" + "use postgres::{fallible_iterator::FallibleIterator}; use cornucopia_sync::GenericClient;" }; let rows_query_string = module .rows diff --git a/examples/auto_build/src/cornucopia.rs b/examples/auto_build/src/cornucopia.rs index 7645821c..4b184292 100644 --- a/examples/auto_build/src/cornucopia.rs +++ b/examples/auto_build/src/cornucopia.rs @@ -17,7 +17,8 @@ pub mod queries { pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> &str, mapper: fn(&str) -> T, } @@ -29,26 +30,34 @@ pub mod queries { StringQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -56,34 +65,46 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn example_query() -> ExampleQueryStmt { - ExampleQueryStmt(cornucopia_async::private::Stmt::new( + ExampleQueryStmt( "SELECT * FROM example_table", - )) + None, + ) } - pub struct ExampleQueryStmt(cornucopia_async::private::Stmt); + pub struct ExampleQueryStmt(&'static str, Option); impl ExampleQueryStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> StringQuery<'a, C, String, 0> { StringQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } diff --git a/examples/basic_async/src/cornucopia.rs b/examples/basic_async/src/cornucopia.rs index 36941dc5..782f9bb4 100644 --- a/examples/basic_async/src/cornucopia.rs +++ b/examples/basic_async/src/cornucopia.rs @@ -213,20 +213,27 @@ pub mod queries { use futures; use futures::{StreamExt, TryStreamExt}; pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_async::private::Stmt::new( + InsertBookStmt( "INSERT INTO Book (title) VALUES ($1)", - )) + None, + ) } - pub struct InsertBookStmt(cornucopia_async::private::Stmt); + pub struct InsertBookStmt(&'static str, Option); impl InsertBookStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, title: &'a T1, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[title]).await + client.execute(self.0, &[title]).await } } } @@ -313,7 +320,8 @@ pub mod queries { pub struct AuthorsQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> AuthorsBorrowed, mapper: fn(AuthorsBorrowed) -> T, } @@ -325,26 +333,34 @@ pub mod queries { AuthorsQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -352,20 +368,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> &str, mapper: fn(&str) -> T, } @@ -377,26 +397,34 @@ pub mod queries { StringQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -404,20 +432,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct AuthorNameStartingWithQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> AuthorNameStartingWithBorrowed, mapper: fn(AuthorNameStartingWithBorrowed) -> T, } @@ -432,26 +464,34 @@ pub mod queries { AuthorNameStartingWithQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -459,20 +499,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct PublicVoiceactorQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::super::types::public::VoiceactorBorrowed, mapper: fn(super::super::types::public::VoiceactorBorrowed) -> T, } @@ -487,26 +531,34 @@ pub mod queries { PublicVoiceactorQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -514,20 +566,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct SelectTranslationsQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> SelectTranslationsBorrowed, mapper: fn(SelectTranslationsBorrowed) -> T, } @@ -542,26 +598,34 @@ pub mod queries { SelectTranslationsQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -569,34 +633,46 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn authors() -> AuthorsStmt { - AuthorsStmt(cornucopia_async::private::Stmt::new( + AuthorsStmt( "SELECT * FROM Author", - )) + None, + ) } - pub struct AuthorsStmt(cornucopia_async::private::Stmt); + pub struct AuthorsStmt(&'static str, Option); impl AuthorsStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> AuthorsQuery<'a, C, Authors, 0> { AuthorsQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| AuthorsBorrowed { id: row.get(0), name: row.get(1), @@ -607,56 +683,74 @@ FROM } } pub fn books() -> BooksStmt { - BooksStmt(cornucopia_async::private::Stmt::new( + BooksStmt( "SELECT Title FROM Book", - )) + None, + ) } - pub struct BooksStmt(cornucopia_async::private::Stmt); + pub struct BooksStmt(&'static str, Option); impl BooksStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> StringQuery<'a, C, String, 0> { StringQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn author_name_by_id() -> AuthorNameByIdStmt { - AuthorNameByIdStmt(cornucopia_async::private::Stmt::new( + AuthorNameByIdStmt( "SELECT Author.Name FROM Author WHERE Author.Id = $1", - )) + None, + ) } - pub struct AuthorNameByIdStmt(cornucopia_async::private::Stmt); + pub struct AuthorNameByIdStmt(&'static str, Option); impl AuthorNameByIdStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, id: &'a i32, ) -> StringQuery<'a, C, String, 1> { StringQuery { client, params: [id], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn author_name_starting_with() -> AuthorNameStartingWithStmt { - AuthorNameStartingWithStmt(cornucopia_async::private::Stmt::new( + AuthorNameStartingWithStmt( "SELECT BookAuthor.AuthorId, Author.Name, @@ -668,19 +762,28 @@ FROM INNER JOIN Book ON Book.Id = BookAuthor.BookId WHERE Author.Name LIKE CONCAT($1::text, '%')", - )) + None, + ) } - pub struct AuthorNameStartingWithStmt(cornucopia_async::private::Stmt); + pub struct AuthorNameStartingWithStmt(&'static str, Option); impl AuthorNameStartingWithStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, start_str: &'a T1, ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { AuthorNameStartingWithQuery { client, params: [start_str], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| AuthorNameStartingWithBorrowed { authorid: row.get(0), name: row.get(1), @@ -700,7 +803,7 @@ WHERE > for AuthorNameStartingWithStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a AuthorNameStartingWithParams, ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { @@ -708,19 +811,30 @@ WHERE } } pub fn select_voice_actor_with_character() -> SelectVoiceActorWithCharacterStmt { - SelectVoiceActorWithCharacterStmt(cornucopia_async::private::Stmt::new( + SelectVoiceActorWithCharacterStmt( "SELECT voice_actor FROM SpongeBobVoiceActor WHERE character = $1", - )) + None, + ) } - pub struct SelectVoiceActorWithCharacterStmt(cornucopia_async::private::Stmt); + pub struct SelectVoiceActorWithCharacterStmt( + &'static str, + Option, + ); impl SelectVoiceActorWithCharacterStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, spongebob_character: &'a super::super::types::public::SpongeBobCharacter, ) -> PublicVoiceactorQuery<'a, C, super::super::types::public::Voiceactor, 1> @@ -728,31 +842,41 @@ WHERE PublicVoiceactorQuery { client, params: [spongebob_character], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn select_translations() -> SelectTranslationsStmt { - SelectTranslationsStmt(cornucopia_async::private::Stmt::new( + SelectTranslationsStmt( "SELECT Title, Translations FROM Book", - )) + None, + ) } - pub struct SelectTranslationsStmt(cornucopia_async::private::Stmt); + pub struct SelectTranslationsStmt(&'static str, Option); impl SelectTranslationsStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> SelectTranslationsQuery<'a, C, SelectTranslations, 0> { SelectTranslationsQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| SelectTranslationsBorrowed { title: row.get(0), translations: row.get(1), diff --git a/examples/basic_sync/src/cornucopia.rs b/examples/basic_sync/src/cornucopia.rs index 55e9cea0..955a90d3 100644 --- a/examples/basic_sync/src/cornucopia.rs +++ b/examples/basic_sync/src/cornucopia.rs @@ -209,22 +209,30 @@ pub mod types { #[allow(dead_code)] pub mod queries { pub mod module_1 { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_sync::private::Stmt::new( + InsertBookStmt( "INSERT INTO Book (title) VALUES ($1)", - )) + None, + ) } - pub struct InsertBookStmt(cornucopia_sync::private::Stmt); + pub struct InsertBookStmt(&'static str, Option); impl InsertBookStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, title: &'a T1, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[title]) + client.execute(self.0, &[title]) } } } @@ -305,11 +313,13 @@ pub mod queries { } } } - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct AuthorsQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> AuthorsBorrowed, mapper: fn(AuthorsBorrowed) -> T, } @@ -321,43 +331,54 @@ pub mod queries { AuthorsQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct StringQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> &str, mapper: fn(&str) -> T, } @@ -369,43 +390,54 @@ pub mod queries { StringQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct AuthorNameStartingWithQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> AuthorNameStartingWithBorrowed, mapper: fn(AuthorNameStartingWithBorrowed) -> T, } @@ -420,43 +452,54 @@ pub mod queries { AuthorNameStartingWithQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct PublicVoiceactorQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::super::types::public::VoiceactorBorrowed, mapper: fn(super::super::types::public::VoiceactorBorrowed) -> T, } @@ -471,43 +514,54 @@ pub mod queries { PublicVoiceactorQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct SelectTranslationsQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> SelectTranslationsBorrowed, mapper: fn(SelectTranslationsBorrowed) -> T, } @@ -522,57 +576,76 @@ pub mod queries { SelectTranslationsQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn authors() -> AuthorsStmt { - AuthorsStmt(cornucopia_sync::private::Stmt::new( + AuthorsStmt( "SELECT * FROM Author", - )) + None, + ) } - pub struct AuthorsStmt(cornucopia_sync::private::Stmt); + pub struct AuthorsStmt(&'static str, Option); impl AuthorsStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> AuthorsQuery<'a, C, Authors, 0> { AuthorsQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| AuthorsBorrowed { id: row.get(0), name: row.get(1), @@ -583,56 +656,74 @@ FROM } } pub fn books() -> BooksStmt { - BooksStmt(cornucopia_sync::private::Stmt::new( + BooksStmt( "SELECT Title FROM Book", - )) + None, + ) } - pub struct BooksStmt(cornucopia_sync::private::Stmt); + pub struct BooksStmt(&'static str, Option); impl BooksStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> StringQuery<'a, C, String, 0> { StringQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn author_name_by_id() -> AuthorNameByIdStmt { - AuthorNameByIdStmt(cornucopia_sync::private::Stmt::new( + AuthorNameByIdStmt( "SELECT Author.Name FROM Author WHERE Author.Id = $1", - )) + None, + ) } - pub struct AuthorNameByIdStmt(cornucopia_sync::private::Stmt); + pub struct AuthorNameByIdStmt(&'static str, Option); impl AuthorNameByIdStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, id: &'a i32, ) -> StringQuery<'a, C, String, 1> { StringQuery { client, params: [id], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn author_name_starting_with() -> AuthorNameStartingWithStmt { - AuthorNameStartingWithStmt(cornucopia_sync::private::Stmt::new( + AuthorNameStartingWithStmt( "SELECT BookAuthor.AuthorId, Author.Name, @@ -644,19 +735,28 @@ FROM INNER JOIN Book ON Book.Id = BookAuthor.BookId WHERE Author.Name LIKE CONCAT($1::text, '%')", - )) + None, + ) } - pub struct AuthorNameStartingWithStmt(cornucopia_sync::private::Stmt); + pub struct AuthorNameStartingWithStmt(&'static str, Option); impl AuthorNameStartingWithStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, start_str: &'a T1, ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { AuthorNameStartingWithQuery { client, params: [start_str], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| AuthorNameStartingWithBorrowed { authorid: row.get(0), name: row.get(1), @@ -676,7 +776,7 @@ WHERE > for AuthorNameStartingWithStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a AuthorNameStartingWithParams, ) -> AuthorNameStartingWithQuery<'a, C, AuthorNameStartingWith, 1> { @@ -684,19 +784,27 @@ WHERE } } pub fn select_voice_actor_with_character() -> SelectVoiceActorWithCharacterStmt { - SelectVoiceActorWithCharacterStmt(cornucopia_sync::private::Stmt::new( + SelectVoiceActorWithCharacterStmt( "SELECT voice_actor FROM SpongeBobVoiceActor WHERE character = $1", - )) + None, + ) } - pub struct SelectVoiceActorWithCharacterStmt(cornucopia_sync::private::Stmt); + pub struct SelectVoiceActorWithCharacterStmt(&'static str, Option); impl SelectVoiceActorWithCharacterStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, spongebob_character: &'a super::super::types::public::SpongeBobCharacter, ) -> PublicVoiceactorQuery<'a, C, super::super::types::public::Voiceactor, 1> @@ -704,31 +812,41 @@ WHERE PublicVoiceactorQuery { client, params: [spongebob_character], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn select_translations() -> SelectTranslationsStmt { - SelectTranslationsStmt(cornucopia_sync::private::Stmt::new( + SelectTranslationsStmt( "SELECT Title, Translations FROM Book", - )) + None, + ) } - pub struct SelectTranslationsStmt(cornucopia_sync::private::Stmt); + pub struct SelectTranslationsStmt(&'static str, Option); impl SelectTranslationsStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> SelectTranslationsQuery<'a, C, SelectTranslations, 0> { SelectTranslationsQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| SelectTranslationsBorrowed { title: row.get(0), translations: row.get(1), diff --git a/test_codegen/src/cornucopia.rs b/test_codegen/src/cornucopia.rs index 38df419d..f2c796d9 100644 --- a/test_codegen/src/cornucopia.rs +++ b/test_codegen/src/cornucopia.rs @@ -1264,11 +1264,13 @@ pub mod types { pub mod queries { pub mod copy { pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn( &postgres::Row, ) @@ -1286,43 +1288,54 @@ pub mod queries { PublicCloneCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct PublicCopyCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::super::super::types::public::CopyComposite, mapper: fn(super::super::super::types::public::CopyComposite) -> T, } @@ -1337,62 +1350,83 @@ pub mod queries { PublicCopyCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn insert_clone() -> InsertCloneStmt { - InsertCloneStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO clone (composite) VALUES ($1)", - )) + InsertCloneStmt("INSERT INTO clone (composite) VALUES ($1)", None) } - pub struct InsertCloneStmt(cornucopia_sync::private::Stmt); + pub struct InsertCloneStmt(&'static str, Option); impl InsertCloneStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, composite: &'a super::super::super::types::public::CloneCompositeBorrowed<'a>, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[composite]) + client.execute(self.0, &[composite]) } } pub fn select_clone() -> SelectCloneStmt { - SelectCloneStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM clone")) + SelectCloneStmt("SELECT * FROM clone", None) } - pub struct SelectCloneStmt(cornucopia_sync::private::Stmt); + pub struct SelectCloneStmt(&'static str, Option); impl SelectCloneStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> PublicCloneCompositeQuery< 'a, @@ -1403,35 +1437,47 @@ pub mod queries { PublicCloneCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn insert_copy() -> InsertCopyStmt { - InsertCopyStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO copy (composite) VALUES ($1)", - )) + InsertCopyStmt("INSERT INTO copy (composite) VALUES ($1)", None) } - pub struct InsertCopyStmt(cornucopia_sync::private::Stmt); + pub struct InsertCopyStmt(&'static str, Option); impl InsertCopyStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, composite: &'a super::super::super::types::public::CopyComposite, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[composite]) + client.execute(self.0, &[composite]) } } pub fn select_copy() -> SelectCopyStmt { - SelectCopyStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM copy")) + SelectCopyStmt("SELECT * FROM copy", None) } - pub struct SelectCopyStmt(cornucopia_sync::private::Stmt); + pub struct SelectCopyStmt(&'static str, Option); impl SelectCopyStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> PublicCopyCompositeQuery< 'a, @@ -1442,7 +1488,8 @@ pub mod queries { PublicCopyCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it, } @@ -1456,7 +1503,8 @@ pub mod queries { pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn( &tokio_postgres::Row, ) @@ -1474,26 +1522,34 @@ pub mod queries { PublicCloneCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -1501,20 +1557,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct PublicCopyCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::super::super::types::public::CopyComposite, mapper: fn(super::super::super::types::public::CopyComposite) -> T, @@ -1530,26 +1590,34 @@ pub mod queries { PublicCopyCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -1557,39 +1625,53 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn insert_clone() -> InsertCloneStmt { - InsertCloneStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO clone (composite) VALUES ($1)", - )) + InsertCloneStmt("INSERT INTO clone (composite) VALUES ($1)", None) } - pub struct InsertCloneStmt(cornucopia_async::private::Stmt); + pub struct InsertCloneStmt(&'static str, Option); impl InsertCloneStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, composite: &'a super::super::super::types::public::CloneCompositeBorrowed<'a>, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[composite]).await + client.execute(self.0, &[composite]).await } } pub fn select_clone() -> SelectCloneStmt { - SelectCloneStmt(cornucopia_async::private::Stmt::new("SELECT * FROM clone")) + SelectCloneStmt("SELECT * FROM clone", None) } - pub struct SelectCloneStmt(cornucopia_async::private::Stmt); + pub struct SelectCloneStmt(&'static str, Option); impl SelectCloneStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> PublicCloneCompositeQuery< 'a, @@ -1600,35 +1682,47 @@ pub mod queries { PublicCloneCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn insert_copy() -> InsertCopyStmt { - InsertCopyStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO copy (composite) VALUES ($1)", - )) + InsertCopyStmt("INSERT INTO copy (composite) VALUES ($1)", None) } - pub struct InsertCopyStmt(cornucopia_async::private::Stmt); + pub struct InsertCopyStmt(&'static str, Option); impl InsertCopyStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, composite: &'a super::super::super::types::public::CopyComposite, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[composite]).await + client.execute(self.0, &[composite]).await } } pub fn select_copy() -> SelectCopyStmt { - SelectCopyStmt(cornucopia_async::private::Stmt::new("SELECT * FROM copy")) + SelectCopyStmt("SELECT * FROM copy", None) } - pub struct SelectCopyStmt(cornucopia_async::private::Stmt); + pub struct SelectCopyStmt(&'static str, Option); impl SelectCopyStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> PublicCopyCompositeQuery< 'a, @@ -1639,7 +1733,8 @@ pub mod queries { PublicCopyCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it, } @@ -1737,11 +1832,13 @@ pub mod queries { } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct SelectNightmareDomainQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::SelectNightmareDomainBorrowed, mapper: fn(super::SelectNightmareDomainBorrowed) -> T, } @@ -1756,43 +1853,54 @@ pub mod queries { SelectNightmareDomainQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct SelectNightmareDomainNullQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::SelectNightmareDomainNullBorrowed, mapper: fn(super::SelectNightmareDomainNullBorrowed) -> T, } @@ -1807,55 +1915,71 @@ pub mod queries { SelectNightmareDomainNullQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn select_nightmare_domain() -> SelectNightmareDomainStmt { - SelectNightmareDomainStmt(cornucopia_sync::private::Stmt::new( - "SELECT txt, json, nb, arr FROM nightmare_domain", - )) + SelectNightmareDomainStmt("SELECT txt, json, nb, arr FROM nightmare_domain", None) } - pub struct SelectNightmareDomainStmt(cornucopia_sync::private::Stmt); + pub struct SelectNightmareDomainStmt(&'static str, Option); impl SelectNightmareDomainStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> SelectNightmareDomainQuery<'a, C, super::SelectNightmareDomain, 0> { SelectNightmareDomainQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectNightmareDomainBorrowed { txt: row.get(0), json: row.get(1), @@ -1867,10 +1991,17 @@ pub mod queries { } } pub fn insert_nightmare_domain() -> InsertNightmareDomainStmt { - InsertNightmareDomainStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)")) + InsertNightmareDomainStmt("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)", None) } - pub struct InsertNightmareDomainStmt(cornucopia_sync::private::Stmt); + pub struct InsertNightmareDomainStmt(&'static str, Option); impl InsertNightmareDomainStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, @@ -1879,7 +2010,7 @@ pub mod queries { T3: cornucopia_sync::JsonSql, T4: cornucopia_sync::ArraySql, >( - &'a mut self, + &'a self, client: &'a mut C, txt: &'a T1, json: &'a T2, @@ -1889,9 +2020,8 @@ pub mod queries { super::super::super::types::public::DomainCompositeParams<'a>, >, ) -> Result { - let stmt = self.0.prepare(client)?; client.execute( - stmt, + self.0, &[ &cornucopia_sync::private::Domain(txt), &cornucopia_sync::private::Domain(json), @@ -1920,7 +2050,7 @@ pub mod queries { > for InsertNightmareDomainStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, ) -> Result { @@ -1935,21 +2065,27 @@ pub mod queries { } } pub fn select_nightmare_domain_null() -> SelectNightmareDomainNullStmt { - SelectNightmareDomainNullStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM nightmare_domain", - )) + SelectNightmareDomainNullStmt("SELECT * FROM nightmare_domain", None) } - pub struct SelectNightmareDomainNullStmt(cornucopia_sync::private::Stmt); + pub struct SelectNightmareDomainNullStmt(&'static str, Option); impl SelectNightmareDomainNullStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> SelectNightmareDomainNullQuery<'a, C, super::SelectNightmareDomainNull, 0> { SelectNightmareDomainNullQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectNightmareDomainNullBorrowed { txt: row.get(0), json: row.get(1), @@ -1969,7 +2105,8 @@ pub mod queries { pub struct SelectNightmareDomainQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::SelectNightmareDomainBorrowed, mapper: fn(super::SelectNightmareDomainBorrowed) -> T, } @@ -1984,26 +2121,34 @@ pub mod queries { SelectNightmareDomainQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -2011,20 +2156,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct SelectNightmareDomainNullQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::SelectNightmareDomainNullBorrowed, mapper: fn(super::SelectNightmareDomainNullBorrowed) -> T, } @@ -2039,26 +2188,34 @@ pub mod queries { SelectNightmareDomainNullQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -2066,32 +2223,41 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn select_nightmare_domain() -> SelectNightmareDomainStmt { - SelectNightmareDomainStmt(cornucopia_async::private::Stmt::new( - "SELECT txt, json, nb, arr FROM nightmare_domain", - )) + SelectNightmareDomainStmt("SELECT txt, json, nb, arr FROM nightmare_domain", None) } - pub struct SelectNightmareDomainStmt(cornucopia_async::private::Stmt); + pub struct SelectNightmareDomainStmt(&'static str, Option); impl SelectNightmareDomainStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> SelectNightmareDomainQuery<'a, C, super::SelectNightmareDomain, 0> { SelectNightmareDomainQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectNightmareDomainBorrowed { txt: row.get(0), json: row.get(1), @@ -2103,10 +2269,17 @@ pub mod queries { } } pub fn insert_nightmare_domain() -> InsertNightmareDomainStmt { - InsertNightmareDomainStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)")) + InsertNightmareDomainStmt("INSERT INTO nightmare_domain (txt, json, nb, arr, composite) VALUES ($1, $2, $3, $4, $5)", None) } - pub struct InsertNightmareDomainStmt(cornucopia_async::private::Stmt); + pub struct InsertNightmareDomainStmt(&'static str, Option); impl InsertNightmareDomainStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind< 'a, C: GenericClient, @@ -2115,7 +2288,7 @@ pub mod queries { T3: cornucopia_async::JsonSql, T4: cornucopia_async::ArraySql, >( - &'a mut self, + &'a self, client: &'a C, txt: &'a T1, json: &'a T2, @@ -2125,10 +2298,9 @@ pub mod queries { super::super::super::types::public::DomainCompositeParams<'a>, >, ) -> Result { - let stmt = self.0.prepare(client).await?; client .execute( - stmt, + self.0, &[ &cornucopia_async::private::Domain(txt), &cornucopia_async::private::Domain(json), @@ -2164,7 +2336,7 @@ pub mod queries { > for InsertNightmareDomainStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::InsertNightmareDomainParams<'a, T1, T2, T3, T4>, ) -> std::pin::Pin< @@ -2185,21 +2357,30 @@ pub mod queries { } } pub fn select_nightmare_domain_null() -> SelectNightmareDomainNullStmt { - SelectNightmareDomainNullStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM nightmare_domain", - )) + SelectNightmareDomainNullStmt("SELECT * FROM nightmare_domain", None) } - pub struct SelectNightmareDomainNullStmt(cornucopia_async::private::Stmt); + pub struct SelectNightmareDomainNullStmt( + &'static str, + Option, + ); impl SelectNightmareDomainNullStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> SelectNightmareDomainNullQuery<'a, C, super::SelectNightmareDomainNull, 0> { SelectNightmareDomainNullQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectNightmareDomainNullBorrowed { txt: row.get(0), json: row.get(1), @@ -2281,11 +2462,13 @@ pub mod queries { } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct IdQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::Id, mapper: fn(super::Id) -> T, } @@ -2297,43 +2480,54 @@ pub mod queries { IdQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct NamedQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::NamedBorrowed, mapper: fn(super::NamedBorrowed) -> T, } @@ -2348,43 +2542,54 @@ pub mod queries { NamedQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct NamedComplexQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::NamedComplexBorrowed, mapper: fn(super::NamedComplexBorrowed) -> T, } @@ -2399,48 +2604,66 @@ pub mod queries { NamedComplexQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn new_named_visible() -> NewNamedVisibleStmt { - NewNamedVisibleStmt(cornucopia_sync::private::Stmt::new( + NewNamedVisibleStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, true) RETURNING id ", - )) + None, + ) } - pub struct NewNamedVisibleStmt(cornucopia_sync::private::Stmt); + pub struct NewNamedVisibleStmt(&'static str, Option); impl NewNamedVisibleStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, name: &'a T1, price: &'a Option, @@ -2448,7 +2671,8 @@ pub mod queries { IdQuery { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::Id { id: row.get(0) }, mapper: |it| ::from(it), } @@ -2459,7 +2683,7 @@ pub mod queries { for NewNamedVisibleStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::NamedParams, ) -> IdQuery<'a, C, super::Id, 2> { @@ -2467,14 +2691,22 @@ pub mod queries { } } pub fn new_named_hidden() -> NewNamedHiddenStmt { - NewNamedHiddenStmt(cornucopia_sync::private::Stmt::new( + NewNamedHiddenStmt( "INSERT INTO named (price, name, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct NewNamedHiddenStmt(cornucopia_sync::private::Stmt); + pub struct NewNamedHiddenStmt(&'static str, Option); impl NewNamedHiddenStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, price: &'a Option, name: &'a T1, @@ -2482,7 +2714,8 @@ pub mod queries { IdQuery { client, params: [price, name], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::Id { id: row.get(0) }, mapper: |it| ::from(it), } @@ -2493,7 +2726,7 @@ pub mod queries { for NewNamedHiddenStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::NamedParams, ) -> IdQuery<'a, C, super::Id, 2> { @@ -2501,18 +2734,26 @@ pub mod queries { } } pub fn named() -> NamedStmt { - NamedStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM named")) + NamedStmt("SELECT * FROM named", None) } - pub struct NamedStmt(cornucopia_sync::private::Stmt); + pub struct NamedStmt(&'static str, Option); impl NamedStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> NamedQuery<'a, C, super::Named, 0> { NamedQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NamedBorrowed { id: row.get(0), name: row.get(1), @@ -2524,21 +2765,27 @@ pub mod queries { } } pub fn named_by_id() -> NamedByIdStmt { - NamedByIdStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM named WHERE id = $1", - )) + NamedByIdStmt("SELECT * FROM named WHERE id = $1", None) } - pub struct NamedByIdStmt(cornucopia_sync::private::Stmt); + pub struct NamedByIdStmt(&'static str, Option); impl NamedByIdStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, id: &'a i32, ) -> NamedQuery<'a, C, super::Named, 1> { NamedQuery { client, params: [id], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NamedBorrowed { id: row.get(0), name: row.get(1), @@ -2550,22 +2797,29 @@ pub mod queries { } } pub fn new_named_complex() -> NewNamedComplexStmt { - NewNamedComplexStmt(cornucopia_sync::private::Stmt::new( + NewNamedComplexStmt( "INSERT INTO named_complex (named, \"named.with_dot\") VALUES ($1, $2)", - )) + None, + ) } - pub struct NewNamedComplexStmt(cornucopia_sync::private::Stmt); + pub struct NewNamedComplexStmt(&'static str, Option); impl NewNamedComplexStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, named: &'a super::super::super::types::public::NamedCompositeBorrowed<'a>, named_with_dot: &'a Option< super::super::super::types::public::NamedCompositeWithDot, >, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[named, named_with_dot]) + client.execute(self.0, &[named, named_with_dot]) } } impl<'a, C: GenericClient> @@ -2577,7 +2831,7 @@ pub mod queries { > for NewNamedComplexStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::NamedComplexParams<'a>, ) -> Result { @@ -2585,20 +2839,26 @@ pub mod queries { } } pub fn named_complex() -> NamedComplexStmt { - NamedComplexStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM named_complex", - )) + NamedComplexStmt("SELECT * FROM named_complex", None) } - pub struct NamedComplexStmt(cornucopia_sync::private::Stmt); + pub struct NamedComplexStmt(&'static str, Option); impl NamedComplexStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> NamedComplexQuery<'a, C, super::NamedComplex, 0> { NamedComplexQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NamedComplexBorrowed { named: row.get(0), named_with_dot: row.get(1), @@ -2615,7 +2875,8 @@ pub mod queries { pub struct IdQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::Id, mapper: fn(super::Id) -> T, } @@ -2627,26 +2888,34 @@ pub mod queries { IdQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -2654,20 +2923,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct NamedQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::NamedBorrowed, mapper: fn(super::NamedBorrowed) -> T, } @@ -2682,26 +2955,34 @@ pub mod queries { NamedQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -2709,20 +2990,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct NamedComplexQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::NamedComplexBorrowed, mapper: fn(super::NamedComplexBorrowed) -> T, } @@ -2737,26 +3022,34 @@ pub mod queries { NamedComplexQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -2764,25 +3057,36 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn new_named_visible() -> NewNamedVisibleStmt { - NewNamedVisibleStmt(cornucopia_async::private::Stmt::new( + NewNamedVisibleStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, true) RETURNING id ", - )) + None, + ) } - pub struct NewNamedVisibleStmt(cornucopia_async::private::Stmt); + pub struct NewNamedVisibleStmt(&'static str, Option); impl NewNamedVisibleStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, name: &'a T1, price: &'a Option, @@ -2790,7 +3094,8 @@ pub mod queries { IdQuery { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::Id { id: row.get(0) }, mapper: |it| ::from(it), } @@ -2805,7 +3110,7 @@ pub mod queries { > for NewNamedVisibleStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::NamedParams, ) -> IdQuery<'a, C, super::Id, 2> { @@ -2813,14 +3118,22 @@ pub mod queries { } } pub fn new_named_hidden() -> NewNamedHiddenStmt { - NewNamedHiddenStmt(cornucopia_async::private::Stmt::new( + NewNamedHiddenStmt( "INSERT INTO named (price, name, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct NewNamedHiddenStmt(cornucopia_async::private::Stmt); + pub struct NewNamedHiddenStmt(&'static str, Option); impl NewNamedHiddenStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, price: &'a Option, name: &'a T1, @@ -2828,7 +3141,8 @@ pub mod queries { IdQuery { client, params: [price, name], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::Id { id: row.get(0) }, mapper: |it| ::from(it), } @@ -2843,7 +3157,7 @@ pub mod queries { > for NewNamedHiddenStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::NamedParams, ) -> IdQuery<'a, C, super::Id, 2> { @@ -2851,18 +3165,26 @@ pub mod queries { } } pub fn named() -> NamedStmt { - NamedStmt(cornucopia_async::private::Stmt::new("SELECT * FROM named")) + NamedStmt("SELECT * FROM named", None) } - pub struct NamedStmt(cornucopia_async::private::Stmt); + pub struct NamedStmt(&'static str, Option); impl NamedStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> NamedQuery<'a, C, super::Named, 0> { NamedQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NamedBorrowed { id: row.get(0), name: row.get(1), @@ -2874,21 +3196,27 @@ pub mod queries { } } pub fn named_by_id() -> NamedByIdStmt { - NamedByIdStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM named WHERE id = $1", - )) + NamedByIdStmt("SELECT * FROM named WHERE id = $1", None) } - pub struct NamedByIdStmt(cornucopia_async::private::Stmt); + pub struct NamedByIdStmt(&'static str, Option); impl NamedByIdStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, id: &'a i32, ) -> NamedQuery<'a, C, super::Named, 1> { NamedQuery { client, params: [id], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NamedBorrowed { id: row.get(0), name: row.get(1), @@ -2900,22 +3228,29 @@ pub mod queries { } } pub fn new_named_complex() -> NewNamedComplexStmt { - NewNamedComplexStmt(cornucopia_async::private::Stmt::new( + NewNamedComplexStmt( "INSERT INTO named_complex (named, \"named.with_dot\") VALUES ($1, $2)", - )) + None, + ) } - pub struct NewNamedComplexStmt(cornucopia_async::private::Stmt); + pub struct NewNamedComplexStmt(&'static str, Option); impl NewNamedComplexStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, named: &'a super::super::super::types::public::NamedCompositeBorrowed<'a>, named_with_dot: &'a Option< super::super::super::types::public::NamedCompositeWithDot, >, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[named, named_with_dot]).await + client.execute(self.0, &[named, named_with_dot]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -2933,7 +3268,7 @@ pub mod queries { > for NewNamedComplexStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::NamedComplexParams<'a>, ) -> std::pin::Pin< @@ -2947,20 +3282,26 @@ pub mod queries { } } pub fn named_complex() -> NamedComplexStmt { - NamedComplexStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM named_complex", - )) + NamedComplexStmt("SELECT * FROM named_complex", None) } - pub struct NamedComplexStmt(cornucopia_async::private::Stmt); + pub struct NamedComplexStmt(&'static str, Option); impl NamedComplexStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> NamedComplexQuery<'a, C, super::NamedComplex, 0> { NamedComplexQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NamedComplexBorrowed { named: row.get(0), named_with_dot: row.get(1), @@ -3010,11 +3351,13 @@ pub mod queries { } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct NullityQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::NullityBorrowed, mapper: fn(super::NullityBorrowed) -> T, } @@ -3029,46 +3372,64 @@ pub mod queries { NullityQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn new_nullity() -> NewNullityStmt { - NewNullityStmt(cornucopia_sync::private::Stmt::new( + NewNullityStmt( "INSERT INTO nullity(texts, name, composite) VALUES ($1, $2, $3)", - )) + None, + ) } - pub struct NewNullityStmt(cornucopia_sync::private::Stmt); + pub struct NewNullityStmt(&'static str, Option); impl NewNullityStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, @@ -3076,7 +3437,7 @@ pub mod queries { T2: cornucopia_sync::ArraySql>, T3: cornucopia_sync::StringSql, >( - &'a mut self, + &'a self, client: &'a mut C, texts: &'a T2, name: &'a T3, @@ -3084,8 +3445,7 @@ pub mod queries { super::super::super::types::public::NullityCompositeParams<'a>, >, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[texts, name, composite]) + client.execute(self.0, &[texts, name, composite]) } } impl< @@ -3103,7 +3463,7 @@ pub mod queries { > for NewNullityStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::NullityParams<'a, T1, T2, T3>, ) -> Result { @@ -3111,18 +3471,26 @@ pub mod queries { } } pub fn nullity() -> NullityStmt { - NullityStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM nullity")) + NullityStmt("SELECT * FROM nullity", None) } - pub struct NullityStmt(cornucopia_sync::private::Stmt); + pub struct NullityStmt(&'static str, Option); impl NullityStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> NullityQuery<'a, C, super::Nullity, 0> { NullityQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NullityBorrowed { texts: row.get(0), name: row.get(1), @@ -3140,7 +3508,8 @@ pub mod queries { pub struct NullityQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::NullityBorrowed, mapper: fn(super::NullityBorrowed) -> T, } @@ -3155,26 +3524,34 @@ pub mod queries { NullityQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -3182,23 +3559,34 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn new_nullity() -> NewNullityStmt { - NewNullityStmt(cornucopia_async::private::Stmt::new( + NewNullityStmt( "INSERT INTO nullity(texts, name, composite) VALUES ($1, $2, $3)", - )) + None, + ) } - pub struct NewNullityStmt(cornucopia_async::private::Stmt); + pub struct NewNullityStmt(&'static str, Option); impl NewNullityStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind< 'a, C: GenericClient, @@ -3206,7 +3594,7 @@ pub mod queries { T2: cornucopia_async::ArraySql>, T3: cornucopia_async::StringSql, >( - &'a mut self, + &'a self, client: &'a C, texts: &'a T2, name: &'a T3, @@ -3214,8 +3602,7 @@ pub mod queries { super::super::super::types::public::NullityCompositeParams<'a>, >, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[texts, name, composite]).await + client.execute(self.0, &[texts, name, composite]).await } } impl< @@ -3239,7 +3626,7 @@ pub mod queries { > for NewNullityStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::NullityParams<'a, T1, T2, T3>, ) -> std::pin::Pin< @@ -3253,20 +3640,26 @@ pub mod queries { } } pub fn nullity() -> NullityStmt { - NullityStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM nullity", - )) + NullityStmt("SELECT * FROM nullity", None) } - pub struct NullityStmt(cornucopia_async::private::Stmt); + pub struct NullityStmt(&'static str, Option); impl NullityStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> NullityQuery<'a, C, super::Nullity, 0> { NullityQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::NullityBorrowed { texts: row.get(0), name: row.get(1), @@ -3327,11 +3720,13 @@ pub mod queries { } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct SelectBookQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::SelectBookBorrowed, mapper: fn(super::SelectBookBorrowed) -> T, } @@ -3346,43 +3741,54 @@ pub mod queries { SelectBookQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct FindBooksQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::FindBooksBorrowed, mapper: fn(super::FindBooksBorrowed) -> T, } @@ -3397,59 +3803,73 @@ pub mod queries { FindBooksQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_sync::private::Stmt::new( - "INSERT INTO book (author, name) VALUES ($1, $2)", - )) + InsertBookStmt("INSERT INTO book (author, name) VALUES ($1, $2)", None) } - pub struct InsertBookStmt(cornucopia_sync::private::Stmt); + pub struct InsertBookStmt(&'static str, Option); impl InsertBookStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, T1: cornucopia_sync::StringSql, T2: cornucopia_sync::StringSql, >( - &'a mut self, + &'a self, client: &'a mut C, author: &'a Option, name: &'a T2, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[author, name]) + client.execute(self.0, &[author, name]) } } impl< @@ -3466,7 +3886,7 @@ pub mod queries { > for InsertBookStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::InsertBookParams, ) -> Result { @@ -3474,18 +3894,26 @@ pub mod queries { } } pub fn select_book() -> SelectBookStmt { - SelectBookStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM book")) + SelectBookStmt("SELECT * FROM book", None) } - pub struct SelectBookStmt(cornucopia_sync::private::Stmt); + pub struct SelectBookStmt(&'static str, Option); impl SelectBookStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> SelectBookQuery<'a, C, super::SelectBook, 0> { SelectBookQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectBookBorrowed { name: row.get(0), author: row.get(1), @@ -3495,26 +3923,32 @@ pub mod queries { } } pub fn find_books() -> FindBooksStmt { - FindBooksStmt(cornucopia_sync::private::Stmt::new( - "SELECT * FROM book WHERE name = ANY ($1)", - )) + FindBooksStmt("SELECT * FROM book WHERE name = ANY ($1)", None) } - pub struct FindBooksStmt(cornucopia_sync::private::Stmt); + pub struct FindBooksStmt(&'static str, Option); impl FindBooksStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, T1: cornucopia_sync::StringSql, T2: cornucopia_sync::ArraySql, >( - &'a mut self, + &'a self, client: &'a mut C, title: &'a T2, ) -> FindBooksQuery<'a, C, super::FindBooks, 1> { FindBooksQuery { client, params: [title], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::FindBooksBorrowed { name: row.get(0), author: row.get(1), @@ -3524,36 +3958,47 @@ pub mod queries { } } pub fn params_use_twice() -> ParamsUseTwiceStmt { - ParamsUseTwiceStmt(cornucopia_sync::private::Stmt::new( + ParamsUseTwiceStmt( "UPDATE book SET name = $1 WHERE length(name) > 42 AND length($1) < 42", - )) + None, + ) } - pub struct ParamsUseTwiceStmt(cornucopia_sync::private::Stmt); + pub struct ParamsUseTwiceStmt(&'static str, Option); impl ParamsUseTwiceStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, name: &'a T1, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[name]) + client.execute(self.0, &[name]) } } pub fn params_order() -> ParamsOrderStmt { - ParamsOrderStmt(cornucopia_sync::private::Stmt::new( - "UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", - )) + ParamsOrderStmt("UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", None) } - pub struct ParamsOrderStmt(cornucopia_sync::private::Stmt); + pub struct ParamsOrderStmt(&'static str, Option); impl ParamsOrderStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, c: &'a i32, a: &'a i32, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[c, a]) + client.execute(self.0, &[c, a]) } } impl<'a, C: GenericClient> @@ -3565,7 +4010,7 @@ pub mod queries { > for ParamsOrderStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::ParamsOrderParams, ) -> Result { @@ -3580,7 +4025,8 @@ pub mod queries { pub struct SelectBookQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::SelectBookBorrowed, mapper: fn(super::SelectBookBorrowed) -> T, } @@ -3595,26 +4041,34 @@ pub mod queries { SelectBookQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -3622,20 +4076,24 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct FindBooksQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::FindBooksBorrowed, mapper: fn(super::FindBooksBorrowed) -> T, } @@ -3650,26 +4108,34 @@ pub mod queries { FindBooksQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -3677,36 +4143,43 @@ pub mod queries { impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn insert_book() -> InsertBookStmt { - InsertBookStmt(cornucopia_async::private::Stmt::new( - "INSERT INTO book (author, name) VALUES ($1, $2)", - )) + InsertBookStmt("INSERT INTO book (author, name) VALUES ($1, $2)", None) } - pub struct InsertBookStmt(cornucopia_async::private::Stmt); + pub struct InsertBookStmt(&'static str, Option); impl InsertBookStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind< 'a, C: GenericClient, T1: cornucopia_async::StringSql, T2: cornucopia_async::StringSql, >( - &'a mut self, + &'a self, client: &'a C, author: &'a Option, name: &'a T2, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[author, name]).await + client.execute(self.0, &[author, name]).await } } impl< @@ -3729,7 +4202,7 @@ pub mod queries { > for InsertBookStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::InsertBookParams, ) -> std::pin::Pin< @@ -3743,18 +4216,26 @@ pub mod queries { } } pub fn select_book() -> SelectBookStmt { - SelectBookStmt(cornucopia_async::private::Stmt::new("SELECT * FROM book")) + SelectBookStmt("SELECT * FROM book", None) } - pub struct SelectBookStmt(cornucopia_async::private::Stmt); + pub struct SelectBookStmt(&'static str, Option); impl SelectBookStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> SelectBookQuery<'a, C, super::SelectBook, 0> { SelectBookQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::SelectBookBorrowed { name: row.get(0), author: row.get(1), @@ -3764,26 +4245,32 @@ pub mod queries { } } pub fn find_books() -> FindBooksStmt { - FindBooksStmt(cornucopia_async::private::Stmt::new( - "SELECT * FROM book WHERE name = ANY ($1)", - )) + FindBooksStmt("SELECT * FROM book WHERE name = ANY ($1)", None) } - pub struct FindBooksStmt(cornucopia_async::private::Stmt); + pub struct FindBooksStmt(&'static str, Option); impl FindBooksStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, T1: cornucopia_async::StringSql, T2: cornucopia_async::ArraySql, >( - &'a mut self, + &'a self, client: &'a C, title: &'a T2, ) -> FindBooksQuery<'a, C, super::FindBooks, 1> { FindBooksQuery { client, params: [title], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::FindBooksBorrowed { name: row.get(0), author: row.get(1), @@ -3793,36 +4280,47 @@ pub mod queries { } } pub fn params_use_twice() -> ParamsUseTwiceStmt { - ParamsUseTwiceStmt(cornucopia_async::private::Stmt::new( + ParamsUseTwiceStmt( "UPDATE book SET name = $1 WHERE length(name) > 42 AND length($1) < 42", - )) + None, + ) } - pub struct ParamsUseTwiceStmt(cornucopia_async::private::Stmt); + pub struct ParamsUseTwiceStmt(&'static str, Option); impl ParamsUseTwiceStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, name: &'a T1, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[name]).await + client.execute(self.0, &[name]).await } } pub fn params_order() -> ParamsOrderStmt { - ParamsOrderStmt(cornucopia_async::private::Stmt::new( - "UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", - )) + ParamsOrderStmt("UPDATE imaginary SET c=$1, a=$2, z=$2, r=$1", None) } - pub struct ParamsOrderStmt(cornucopia_async::private::Stmt); + pub struct ParamsOrderStmt(&'static str, Option); impl ParamsOrderStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, c: &'a i32, a: &'a i32, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[c, a]).await + client.execute(self.0, &[c, a]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -3840,7 +4338,7 @@ pub mod queries { > for ParamsOrderStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::ParamsOrderParams, ) -> std::pin::Pin< @@ -4549,11 +5047,13 @@ pub mod queries { } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct EverythingQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::EverythingBorrowed, mapper: fn(super::EverythingBorrowed) -> T, } @@ -4568,43 +5068,54 @@ pub mod queries { EverythingQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct EverythingNullQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::EverythingNullBorrowed, mapper: fn(super::EverythingNullBorrowed) -> T, } @@ -4619,43 +5130,54 @@ pub mod queries { EverythingNullQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct EverythingArrayQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::EverythingArrayBorrowed, mapper: fn(super::EverythingArrayBorrowed) -> T, } @@ -4670,43 +5192,54 @@ pub mod queries { EverythingArrayQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct EverythingArrayNullQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::EverythingArrayNullBorrowed, mapper: fn(super::EverythingArrayNullBorrowed) -> T, } @@ -4721,43 +5254,54 @@ pub mod queries { EverythingArrayNullQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct PublicNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn( &postgres::Row, ) @@ -4775,57 +5319,76 @@ pub mod queries { PublicNightmareCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn select_everything() -> SelectEverythingStmt { - SelectEverythingStmt(cornucopia_sync::private::Stmt::new( + SelectEverythingStmt( "SELECT * FROM Everything", - )) + None, + ) } - pub struct SelectEverythingStmt(cornucopia_sync::private::Stmt); + pub struct SelectEverythingStmt(&'static str, Option); impl SelectEverythingStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> EverythingQuery<'a, C, super::Everything, 0> { EverythingQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -4867,23 +5430,32 @@ FROM } } pub fn select_everything_null() -> SelectEverythingNullStmt { - SelectEverythingNullStmt(cornucopia_sync::private::Stmt::new( + SelectEverythingNullStmt( "SELECT * FROM Everything", - )) + None, + ) } - pub struct SelectEverythingNullStmt(cornucopia_sync::private::Stmt); + pub struct SelectEverythingNullStmt(&'static str, Option); impl SelectEverythingNullStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> EverythingNullQuery<'a, C, super::EverythingNull, 0> { EverythingNullQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingNullBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -4925,11 +5497,18 @@ FROM } } pub fn insert_everything() -> InsertEverythingStmt { - InsertEverythingStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)")) + InsertEverythingStmt("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)", None) } - pub struct InsertEverythingStmt(cornucopia_sync::private::Stmt); + pub struct InsertEverythingStmt(&'static str, Option); impl InsertEverythingStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, @@ -4939,7 +5518,7 @@ FROM T4: cornucopia_sync::JsonSql, T5: cornucopia_sync::JsonSql, >( - &'a mut self, + &'a self, client: &'a mut C, bool_: &'a bool, boolean_: &'a bool, @@ -4976,9 +5555,8 @@ FROM macaddr_: &'a eui48::MacAddress, numeric_: &'a rust_decimal::Decimal, ) -> Result { - let stmt = self.0.prepare(client)?; client.execute( - stmt, + self.0, &[ bool_, boolean_, @@ -5035,7 +5613,7 @@ FROM > for InsertEverythingStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::EverythingParams, ) -> Result { @@ -5079,23 +5657,32 @@ FROM } } pub fn select_everything_array() -> SelectEverythingArrayStmt { - SelectEverythingArrayStmt(cornucopia_sync::private::Stmt::new( + SelectEverythingArrayStmt( "SELECT * FROM EverythingArray", - )) + None, + ) } - pub struct SelectEverythingArrayStmt(cornucopia_sync::private::Stmt); + pub struct SelectEverythingArrayStmt(&'static str, Option); impl SelectEverythingArrayStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> EverythingArrayQuery<'a, C, super::EverythingArray, 0> { EverythingArrayQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingArrayBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -5131,24 +5718,33 @@ FROM } } pub fn select_everything_array_null() -> SelectEverythingArrayNullStmt { - SelectEverythingArrayNullStmt(cornucopia_sync::private::Stmt::new( + SelectEverythingArrayNullStmt( "SELECT * FROM EverythingArray", - )) + None, + ) } - pub struct SelectEverythingArrayNullStmt(cornucopia_sync::private::Stmt); + pub struct SelectEverythingArrayNullStmt(&'static str, Option); impl SelectEverythingArrayNullStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> EverythingArrayNullQuery<'a, C, super::EverythingArrayNull, 0> { EverythingArrayNullQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingArrayNullBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -5184,11 +5780,18 @@ FROM } } pub fn insert_everything_array() -> InsertEverythingArrayStmt { - InsertEverythingArrayStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)")) + InsertEverythingArrayStmt("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)", None) } - pub struct InsertEverythingArrayStmt(cornucopia_sync::private::Stmt); + pub struct InsertEverythingArrayStmt(&'static str, Option); impl InsertEverythingArrayStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind< 'a, C: GenericClient, @@ -5226,7 +5829,7 @@ FROM T32: cornucopia_sync::ArraySql, T33: cornucopia_sync::ArraySql, >( - &'a mut self, + &'a self, client: &'a mut C, bool_: &'a T1, boolean_: &'a T2, @@ -5257,9 +5860,8 @@ FROM macaddr_: &'a T32, numeric_: &'a T33, ) -> Result { - let stmt = self.0.prepare(client)?; client.execute( - stmt, + self.0, &[ bool_, boolean_, @@ -5372,7 +5974,7 @@ FROM > for InsertEverythingArrayStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::EverythingArrayParams< T1, @@ -5444,17 +6046,25 @@ FROM } } pub fn select_nightmare() -> SelectNightmareStmt { - SelectNightmareStmt(cornucopia_sync::private::Stmt::new( + SelectNightmareStmt( "SELECT * FROM nightmare", - )) + None, + ) } - pub struct SelectNightmareStmt(cornucopia_sync::private::Stmt); + pub struct SelectNightmareStmt(&'static str, Option); impl SelectNightmareStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> PublicNightmareCompositeQuery< 'a, @@ -5465,27 +6075,35 @@ FROM PublicNightmareCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn insert_nightmare() -> InsertNightmareStmt { - InsertNightmareStmt(cornucopia_sync::private::Stmt::new( + InsertNightmareStmt( "INSERT INTO nightmare (composite) VALUES ($1)", - )) + None, + ) } - pub struct InsertNightmareStmt(cornucopia_sync::private::Stmt); + pub struct InsertNightmareStmt(&'static str, Option); impl InsertNightmareStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, composite: &'a super::super::super::types::public::NightmareCompositeParams<'a>, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[composite]) + client.execute(self.0, &[composite]) } } } @@ -5496,7 +6114,8 @@ FROM pub struct EverythingQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::EverythingBorrowed, mapper: fn(super::EverythingBorrowed) -> T, } @@ -5511,26 +6130,34 @@ FROM EverythingQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -5538,20 +6165,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct EverythingNullQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::EverythingNullBorrowed, mapper: fn(super::EverythingNullBorrowed) -> T, } @@ -5566,26 +6197,34 @@ FROM EverythingNullQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -5593,20 +6232,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct EverythingArrayQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::EverythingArrayBorrowed, mapper: fn(super::EverythingArrayBorrowed) -> T, } @@ -5621,26 +6264,34 @@ FROM EverythingArrayQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -5648,20 +6299,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct EverythingArrayNullQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::EverythingArrayNullBorrowed, mapper: fn(super::EverythingArrayNullBorrowed) -> T, } @@ -5676,26 +6331,34 @@ FROM EverythingArrayNullQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -5703,20 +6366,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct PublicNightmareCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn( &tokio_postgres::Row, ) @@ -5734,26 +6401,34 @@ FROM PublicNightmareCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -5761,34 +6436,46 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn select_everything() -> SelectEverythingStmt { - SelectEverythingStmt(cornucopia_async::private::Stmt::new( + SelectEverythingStmt( "SELECT * FROM Everything", - )) + None, + ) } - pub struct SelectEverythingStmt(cornucopia_async::private::Stmt); + pub struct SelectEverythingStmt(&'static str, Option); impl SelectEverythingStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> EverythingQuery<'a, C, super::Everything, 0> { EverythingQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -5830,23 +6517,32 @@ FROM } } pub fn select_everything_null() -> SelectEverythingNullStmt { - SelectEverythingNullStmt(cornucopia_async::private::Stmt::new( + SelectEverythingNullStmt( "SELECT * FROM Everything", - )) + None, + ) } - pub struct SelectEverythingNullStmt(cornucopia_async::private::Stmt); + pub struct SelectEverythingNullStmt(&'static str, Option); impl SelectEverythingNullStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> EverythingNullQuery<'a, C, super::EverythingNull, 0> { EverythingNullQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingNullBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -5888,11 +6584,18 @@ FROM } } pub fn insert_everything() -> InsertEverythingStmt { - InsertEverythingStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)")) + InsertEverythingStmt("INSERT INTO Everything (bool_, boolean_, char_, smallint_, int2_, smallserial_, serial2_, int_, int4_, serial_, serial4_, bingint_, int8_, bigserial_, serial8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34)", None) } - pub struct InsertEverythingStmt(cornucopia_async::private::Stmt); + pub struct InsertEverythingStmt(&'static str, Option); impl InsertEverythingStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind< 'a, C: GenericClient, @@ -5902,7 +6605,7 @@ FROM T4: cornucopia_async::JsonSql, T5: cornucopia_async::JsonSql, >( - &'a mut self, + &'a self, client: &'a C, bool_: &'a bool, boolean_: &'a bool, @@ -5939,10 +6642,9 @@ FROM macaddr_: &'a eui48::MacAddress, numeric_: &'a rust_decimal::Decimal, ) -> Result { - let stmt = self.0.prepare(client).await?; client .execute( - stmt, + self.0, &[ bool_, boolean_, @@ -6006,7 +6708,7 @@ FROM > for InsertEverythingStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::EverythingParams, ) -> std::pin::Pin< @@ -6056,23 +6758,32 @@ FROM } } pub fn select_everything_array() -> SelectEverythingArrayStmt { - SelectEverythingArrayStmt(cornucopia_async::private::Stmt::new( + SelectEverythingArrayStmt( "SELECT * FROM EverythingArray", - )) + None, + ) } - pub struct SelectEverythingArrayStmt(cornucopia_async::private::Stmt); + pub struct SelectEverythingArrayStmt(&'static str, Option); impl SelectEverythingArrayStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> EverythingArrayQuery<'a, C, super::EverythingArray, 0> { EverythingArrayQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingArrayBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -6108,24 +6819,36 @@ FROM } } pub fn select_everything_array_null() -> SelectEverythingArrayNullStmt { - SelectEverythingArrayNullStmt(cornucopia_async::private::Stmt::new( + SelectEverythingArrayNullStmt( "SELECT * FROM EverythingArray", - )) + None, + ) } - pub struct SelectEverythingArrayNullStmt(cornucopia_async::private::Stmt); + pub struct SelectEverythingArrayNullStmt( + &'static str, + Option, + ); impl SelectEverythingArrayNullStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> EverythingArrayNullQuery<'a, C, super::EverythingArrayNull, 0> { EverythingArrayNullQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::EverythingArrayNullBorrowed { bool_: row.get(0), boolean_: row.get(1), @@ -6161,11 +6884,18 @@ FROM } } pub fn insert_everything_array() -> InsertEverythingArrayStmt { - InsertEverythingArrayStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)")) + InsertEverythingArrayStmt("INSERT INTO EverythingArray (bool_, boolean_, char_, smallint_, int2_, int_, int4_, bingint_, int8_, float4_, real_, float8_, double_precision_, text_, varchar_, bytea_, timestamp_, timestamp_without_time_zone_, timestamptz_, timestamp_with_time_zone_, date_, time_, json_, jsonb_, uuid_, inet_, macaddr_, numeric_) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)", None) } - pub struct InsertEverythingArrayStmt(cornucopia_async::private::Stmt); + pub struct InsertEverythingArrayStmt(&'static str, Option); impl InsertEverythingArrayStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind< 'a, C: GenericClient, @@ -6203,7 +6933,7 @@ FROM T32: cornucopia_async::ArraySql, T33: cornucopia_async::ArraySql, >( - &'a mut self, + &'a self, client: &'a C, bool_: &'a T1, boolean_: &'a T2, @@ -6234,10 +6964,9 @@ FROM macaddr_: &'a T32, numeric_: &'a T33, ) -> Result { - let stmt = self.0.prepare(client).await?; client .execute( - stmt, + self.0, &[ bool_, boolean_, @@ -6357,7 +7086,7 @@ FROM > for InsertEverythingArrayStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::EverythingArrayParams< T1, @@ -6435,17 +7164,25 @@ FROM } } pub fn select_nightmare() -> SelectNightmareStmt { - SelectNightmareStmt(cornucopia_async::private::Stmt::new( + SelectNightmareStmt( "SELECT * FROM nightmare", - )) + None, + ) } - pub struct SelectNightmareStmt(cornucopia_async::private::Stmt); + pub struct SelectNightmareStmt(&'static str, Option); impl SelectNightmareStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> PublicNightmareCompositeQuery< 'a, @@ -6456,27 +7193,35 @@ FROM PublicNightmareCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn insert_nightmare() -> InsertNightmareStmt { - InsertNightmareStmt(cornucopia_async::private::Stmt::new( + InsertNightmareStmt( "INSERT INTO nightmare (composite) VALUES ($1)", - )) + None, + ) } - pub struct InsertNightmareStmt(cornucopia_async::private::Stmt); + pub struct InsertNightmareStmt(&'static str, Option); impl InsertNightmareStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, composite: &'a super::super::super::types::public::NightmareCompositeParams<'a>, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[composite]).await + client.execute(self.0, &[composite]).await } } } @@ -6587,11 +7332,13 @@ FROM } } pub mod sync { - use postgres::{fallible_iterator::FallibleIterator, GenericClient}; + use cornucopia_sync::GenericClient; + use postgres::fallible_iterator::FallibleIterator; pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn( &postgres::Row, ) @@ -6609,43 +7356,54 @@ FROM PublicCloneCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct Optioni32Query<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> Option, mapper: fn(Option) -> T, } @@ -6657,43 +7415,54 @@ FROM Optioni32Query { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct RowQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::Row, mapper: fn(super::Row) -> T, } @@ -6705,43 +7474,54 @@ FROM RowQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct RowSpaceQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::RowSpace, mapper: fn(super::RowSpace) -> T, } @@ -6756,43 +7536,54 @@ FROM RowSpaceQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub struct TypeofQuery<'a, C: GenericClient, T, const N: usize> { client: &'a mut C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_sync::private::Stmt, + query: &'static str, + cached: Option<&'a postgres::Statement>, extractor: fn(&postgres::Row) -> super::TypeofBorrowed, mapper: fn(super::TypeofBorrowed) -> T, } @@ -6807,46 +7598,63 @@ FROM TypeofQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client)?; - let row = self.client.query_one(stmt, &self.params)?; + let row = cornucopia_sync::private::one( + self.client, + self.query, + &self.params, + self.cached, + )?; Ok((self.mapper)((self.extractor)(&row))) } pub fn all(self) -> Result, postgres::Error> { self.iter()?.collect() } pub fn opt(self) -> Result, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - Ok(self - .client - .query_opt(stmt, &self.params)? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_sync::private::opt( + self.client, + self.query, + &self.params, + self.cached, + )?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub fn iter( self, ) -> Result> + 'a, postgres::Error> { - let stmt = self.stmt.prepare(self.client)?; - let it = self - .client - .query_raw(stmt, cornucopia_sync::private::slice_iter(&self.params))? + let stream = cornucopia_sync::private::raw( + self.client, + self.query, + cornucopia_sync::private::slice_iter(&self.params), + self.cached, + )?; + let mapped = stream .iterator() .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))); - Ok(it) + Ok(mapped) } } pub fn select_compact() -> SelectCompactStmt { - SelectCompactStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM clone")) + SelectCompactStmt("SELECT * FROM clone", None) } - pub struct SelectCompactStmt(cornucopia_sync::private::Stmt); + pub struct SelectCompactStmt(&'static str, Option); impl SelectCompactStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> PublicCloneCompositeQuery< 'a, @@ -6857,21 +7665,27 @@ FROM PublicCloneCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn select_spaced() -> SelectSpacedStmt { - SelectSpacedStmt(cornucopia_sync::private::Stmt::new( - " SELECT * FROM clone ", - )) + SelectSpacedStmt(" SELECT * FROM clone ", None) } - pub struct SelectSpacedStmt(cornucopia_sync::private::Stmt); + pub struct SelectSpacedStmt(&'static str, Option); impl SelectSpacedStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> PublicCloneCompositeQuery< 'a, @@ -6882,21 +7696,30 @@ FROM PublicCloneCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn implicit_compact() -> ImplicitCompactStmt { - ImplicitCompactStmt(cornucopia_sync::private::Stmt::new( + ImplicitCompactStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct ImplicitCompactStmt(cornucopia_sync::private::Stmt); + pub struct ImplicitCompactStmt(&'static str, Option); impl ImplicitCompactStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, name: &'a Option, price: &'a Option, @@ -6904,7 +7727,8 @@ FROM Optioni32Query { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it, } @@ -6919,7 +7743,7 @@ FROM > for ImplicitCompactStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::ImplicitCompactParams, ) -> Optioni32Query<'a, C, Option, 2> { @@ -6927,14 +7751,22 @@ FROM } } pub fn implicit_spaced() -> ImplicitSpacedStmt { - ImplicitSpacedStmt(cornucopia_sync::private::Stmt::new( + ImplicitSpacedStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct ImplicitSpacedStmt(cornucopia_sync::private::Stmt); + pub struct ImplicitSpacedStmt(&'static str, Option); impl ImplicitSpacedStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, name: &'a Option, price: &'a Option, @@ -6942,7 +7774,8 @@ FROM Optioni32Query { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it, } @@ -6957,7 +7790,7 @@ FROM > for ImplicitSpacedStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::ImplicitSpacedParams, ) -> Optioni32Query<'a, C, Option, 2> { @@ -6965,14 +7798,22 @@ FROM } } pub fn named_compact() -> NamedCompactStmt { - NamedCompactStmt(cornucopia_sync::private::Stmt::new( + NamedCompactStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct NamedCompactStmt(cornucopia_sync::private::Stmt); + pub struct NamedCompactStmt(&'static str, Option); impl NamedCompactStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, name: &'a T1, price: &'a f64, @@ -6980,7 +7821,8 @@ FROM RowQuery { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::Row { id: row.get(0) }, mapper: |it| ::from(it), } @@ -6991,7 +7833,7 @@ FROM for NamedCompactStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::Params, ) -> RowQuery<'a, C, super::Row, 2> { @@ -6999,14 +7841,22 @@ FROM } } pub fn named_spaced() -> NamedSpacedStmt { - NamedSpacedStmt(cornucopia_sync::private::Stmt::new( + NamedSpacedStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct NamedSpacedStmt(cornucopia_sync::private::Stmt); + pub struct NamedSpacedStmt(&'static str, Option); impl NamedSpacedStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_sync::StringSql>( - &'a mut self, + &'a self, client: &'a mut C, name: &'a T1, price: &'a f64, @@ -7014,7 +7864,8 @@ FROM RowSpaceQuery { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::RowSpace { id: row.get(0) }, mapper: |it| ::from(it), } @@ -7029,7 +7880,7 @@ FROM > for NamedSpacedStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::ParamsSpace, ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { @@ -7037,18 +7888,24 @@ FROM } } pub fn tricky_sql() -> TrickySqlStmt { - TrickySqlStmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)")) + TrickySqlStmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)", None) } - pub struct TrickySqlStmt(cornucopia_sync::private::Stmt); + pub struct TrickySqlStmt(&'static str, Option); impl TrickySqlStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7056,7 +7913,7 @@ FROM for TrickySqlStmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySqlParams, ) -> Result { @@ -7064,18 +7921,24 @@ FROM } } pub fn tricky_sql1() -> TrickySql1Stmt { - TrickySql1Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)")) + TrickySql1Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)", None) } - pub struct TrickySql1Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql1Stmt(&'static str, Option); impl TrickySql1Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7087,7 +7950,7 @@ FROM > for TrickySql1Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql1Params, ) -> Result { @@ -7095,18 +7958,24 @@ FROM } } pub fn tricky_sql2() -> TrickySql2Stmt { - TrickySql2Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)")) + TrickySql2Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)", None) } - pub struct TrickySql2Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql2Stmt(&'static str, Option); impl TrickySql2Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7118,7 +7987,7 @@ FROM > for TrickySql2Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql2Params, ) -> Result { @@ -7126,18 +7995,24 @@ FROM } } pub fn tricky_sql3() -> TrickySql3Stmt { - TrickySql3Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)")) + TrickySql3Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)", None) } - pub struct TrickySql3Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql3Stmt(&'static str, Option); impl TrickySql3Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7149,7 +8024,7 @@ FROM > for TrickySql3Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql3Params, ) -> Result { @@ -7157,18 +8032,24 @@ FROM } } pub fn tricky_sql4() -> TrickySql4Stmt { - TrickySql4Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)")) + TrickySql4Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)", None) } - pub struct TrickySql4Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql4Stmt(&'static str, Option); impl TrickySql4Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7180,7 +8061,7 @@ FROM > for TrickySql4Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql4Params, ) -> Result { @@ -7188,18 +8069,24 @@ FROM } } pub fn tricky_sql6() -> TrickySql6Stmt { - TrickySql6Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)")) + TrickySql6Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)", None) } - pub struct TrickySql6Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql6Stmt(&'static str, Option); impl TrickySql6Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7211,7 +8098,7 @@ FROM > for TrickySql6Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql6Params, ) -> Result { @@ -7219,18 +8106,24 @@ FROM } } pub fn tricky_sql7() -> TrickySql7Stmt { - TrickySql7Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)")) + TrickySql7Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)", None) } - pub struct TrickySql7Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql7Stmt(&'static str, Option); impl TrickySql7Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7242,7 +8135,7 @@ FROM > for TrickySql7Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql7Params, ) -> Result { @@ -7250,18 +8143,24 @@ FROM } } pub fn tricky_sql8() -> TrickySql8Stmt { - TrickySql8Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)")) + TrickySql8Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)", None) } - pub struct TrickySql8Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql8Stmt(&'static str, Option); impl TrickySql8Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7273,7 +8172,7 @@ FROM > for TrickySql8Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql8Params, ) -> Result { @@ -7281,18 +8180,24 @@ FROM } } pub fn tricky_sql9() -> TrickySql9Stmt { - TrickySql9Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)")) + TrickySql9Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)", None) } - pub struct TrickySql9Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql9Stmt(&'static str, Option); impl TrickySql9Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7304,7 +8209,7 @@ FROM > for TrickySql9Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql9Params, ) -> Result { @@ -7312,18 +8217,24 @@ FROM } } pub fn tricky_sql10() -> TrickySql10Stmt { - TrickySql10Stmt(cornucopia_sync :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)")) + TrickySql10Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)", None) } - pub struct TrickySql10Stmt(cornucopia_sync::private::Stmt); + pub struct TrickySql10Stmt(&'static str, Option); impl TrickySql10Stmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client)?; - client.execute(stmt, &[r#async, r#enum]) + client.execute(self.0, &[r#async, r#enum]) } } impl<'a, C: GenericClient> @@ -7335,7 +8246,7 @@ FROM > for TrickySql10Stmt { fn params( - &'a mut self, + &'a self, client: &'a mut C, params: &'a super::TrickySql10Params, ) -> Result { @@ -7343,18 +8254,26 @@ FROM } } pub fn r#typeof() -> RTypeofStmt { - RTypeofStmt(cornucopia_sync::private::Stmt::new("SELECT * FROM syntax")) + RTypeofStmt("SELECT * FROM syntax", None) } - pub struct RTypeofStmt(cornucopia_sync::private::Stmt); + pub struct RTypeofStmt(&'static str, Option); impl RTypeofStmt { + pub fn prepare<'a, C: GenericClient>( + mut self, + client: &'a mut C, + ) -> Result { + self.1 = Some(client.prepare(self.0)?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a mut C, ) -> TypeofQuery<'a, C, super::Typeof, 0> { TypeofQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::TypeofBorrowed { trick_y: row.get(0), r#async: row.get(1), @@ -7372,7 +8291,8 @@ FROM pub struct PublicCloneCompositeQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn( &tokio_postgres::Row, ) @@ -7390,26 +8310,34 @@ FROM PublicCloneCompositeQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -7417,20 +8345,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct Optioni32Query<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> Option, mapper: fn(Option) -> T, } @@ -7442,26 +8374,34 @@ FROM Optioni32Query { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -7469,20 +8409,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct RowQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::Row, mapper: fn(super::Row) -> T, } @@ -7494,26 +8438,34 @@ FROM RowQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -7521,20 +8473,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct RowSpaceQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::RowSpace, mapper: fn(super::RowSpace) -> T, } @@ -7549,26 +8505,34 @@ FROM RowSpaceQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -7576,20 +8540,24 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub struct TypeofQuery<'a, C: GenericClient, T, const N: usize> { client: &'a C, params: [&'a (dyn postgres_types::ToSql + Sync); N], - stmt: &'a mut cornucopia_async::private::Stmt, + query: &'static str, + cached: Option<&'a tokio_postgres::Statement>, extractor: fn(&tokio_postgres::Row) -> super::TypeofBorrowed, mapper: fn(super::TypeofBorrowed) -> T, } @@ -7604,26 +8572,34 @@ FROM TypeofQuery { client: self.client, params: self.params, - stmt: self.stmt, + query: self.query, + cached: self.cached, extractor: self.extractor, mapper, } } pub async fn one(self) -> Result { - let stmt = self.stmt.prepare(self.client).await?; - let row = self.client.query_one(stmt, &self.params).await?; + let row = cornucopia_async::private::one( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; Ok((self.mapper)((self.extractor)(&row))) } pub async fn all(self) -> Result, tokio_postgres::Error> { self.iter().await?.try_collect().await } pub async fn opt(self) -> Result, tokio_postgres::Error> { - let stmt = self.stmt.prepare(self.client).await?; - Ok(self - .client - .query_opt(stmt, &self.params) - .await? - .map(|row| (self.mapper)((self.extractor)(&row)))) + let opt_row = cornucopia_async::private::opt( + self.client, + self.query, + &self.params, + self.cached, + ) + .await?; + Ok(opt_row.map(|row| (self.mapper)((self.extractor)(&row)))) } pub async fn iter( self, @@ -7631,23 +8607,33 @@ FROM impl futures::Stream> + 'a, tokio_postgres::Error, > { - let stmt = self.stmt.prepare(self.client).await?; - let it = self - .client - .query_raw(stmt, cornucopia_async::private::slice_iter(&self.params)) - .await? + let stream = cornucopia_async::private::raw( + self.client, + self.query, + cornucopia_async::private::slice_iter(&self.params), + self.cached, + ) + .await?; + let mapped = stream .map(move |res| res.map(|row| (self.mapper)((self.extractor)(&row)))) .into_stream(); - Ok(it) + Ok(mapped) } } pub fn select_compact() -> SelectCompactStmt { - SelectCompactStmt(cornucopia_async::private::Stmt::new("SELECT * FROM clone")) + SelectCompactStmt("SELECT * FROM clone", None) } - pub struct SelectCompactStmt(cornucopia_async::private::Stmt); + pub struct SelectCompactStmt(&'static str, Option); impl SelectCompactStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> PublicCloneCompositeQuery< 'a, @@ -7658,21 +8644,27 @@ FROM PublicCloneCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn select_spaced() -> SelectSpacedStmt { - SelectSpacedStmt(cornucopia_async::private::Stmt::new( - " SELECT * FROM clone ", - )) + SelectSpacedStmt(" SELECT * FROM clone ", None) } - pub struct SelectSpacedStmt(cornucopia_async::private::Stmt); + pub struct SelectSpacedStmt(&'static str, Option); impl SelectSpacedStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> PublicCloneCompositeQuery< 'a, @@ -7683,21 +8675,30 @@ FROM PublicCloneCompositeQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it.into(), } } } pub fn implicit_compact() -> ImplicitCompactStmt { - ImplicitCompactStmt(cornucopia_async::private::Stmt::new( + ImplicitCompactStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct ImplicitCompactStmt(cornucopia_async::private::Stmt); + pub struct ImplicitCompactStmt(&'static str, Option); impl ImplicitCompactStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, name: &'a Option, price: &'a Option, @@ -7705,7 +8706,8 @@ FROM Optioni32Query { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it, } @@ -7720,7 +8722,7 @@ FROM > for ImplicitCompactStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::ImplicitCompactParams, ) -> Optioni32Query<'a, C, Option, 2> { @@ -7728,14 +8730,22 @@ FROM } } pub fn implicit_spaced() -> ImplicitSpacedStmt { - ImplicitSpacedStmt(cornucopia_async::private::Stmt::new( + ImplicitSpacedStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct ImplicitSpacedStmt(cornucopia_async::private::Stmt); + pub struct ImplicitSpacedStmt(&'static str, Option); impl ImplicitSpacedStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, name: &'a Option, price: &'a Option, @@ -7743,7 +8753,8 @@ FROM Optioni32Query { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| row.get(0), mapper: |it| it, } @@ -7758,7 +8769,7 @@ FROM > for ImplicitSpacedStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::ImplicitSpacedParams, ) -> Optioni32Query<'a, C, Option, 2> { @@ -7766,14 +8777,22 @@ FROM } } pub fn named_compact() -> NamedCompactStmt { - NamedCompactStmt(cornucopia_async::private::Stmt::new( + NamedCompactStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct NamedCompactStmt(cornucopia_async::private::Stmt); + pub struct NamedCompactStmt(&'static str, Option); impl NamedCompactStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, name: &'a T1, price: &'a f64, @@ -7781,7 +8800,8 @@ FROM RowQuery { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::Row { id: row.get(0) }, mapper: |it| ::from(it), } @@ -7792,7 +8812,7 @@ FROM for NamedCompactStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::Params, ) -> RowQuery<'a, C, super::Row, 2> { @@ -7800,14 +8820,22 @@ FROM } } pub fn named_spaced() -> NamedSpacedStmt { - NamedSpacedStmt(cornucopia_async::private::Stmt::new( + NamedSpacedStmt( "INSERT INTO named (name, price, show) VALUES ($1, $2, false) RETURNING id", - )) + None, + ) } - pub struct NamedSpacedStmt(cornucopia_async::private::Stmt); + pub struct NamedSpacedStmt(&'static str, Option); impl NamedSpacedStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient, T1: cornucopia_async::StringSql>( - &'a mut self, + &'a self, client: &'a C, name: &'a T1, price: &'a f64, @@ -7815,7 +8843,8 @@ FROM RowSpaceQuery { client, params: [name, price], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::RowSpace { id: row.get(0) }, mapper: |it| ::from(it), } @@ -7830,7 +8859,7 @@ FROM > for NamedSpacedStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::ParamsSpace, ) -> RowSpaceQuery<'a, C, super::RowSpace, 2> { @@ -7838,18 +8867,24 @@ FROM } } pub fn tricky_sql() -> TrickySqlStmt { - TrickySqlStmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)")) + TrickySqlStmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a bind_param\', $1, $2)", None) } - pub struct TrickySqlStmt(cornucopia_async::private::Stmt); + pub struct TrickySqlStmt(&'static str, Option); impl TrickySqlStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -7867,7 +8902,7 @@ FROM > for TrickySqlStmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySqlParams, ) -> std::pin::Pin< @@ -7881,18 +8916,24 @@ FROM } } pub fn tricky_sql1() -> TrickySql1Stmt { - TrickySql1Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)")) + TrickySql1Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a :bind_param', $1, $2)", None) } - pub struct TrickySql1Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql1Stmt(&'static str, Option); impl TrickySql1Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -7910,7 +8951,7 @@ FROM > for TrickySql1Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql1Params, ) -> std::pin::Pin< @@ -7924,18 +8965,24 @@ FROM } } pub fn tricky_sql2() -> TrickySql2Stmt { - TrickySql2Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)")) + TrickySql2Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is not a '':bind_param''', $1, $2)", None) } - pub struct TrickySql2Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql2Stmt(&'static str, Option); impl TrickySql2Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -7953,7 +9000,7 @@ FROM > for TrickySql2Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql2Params, ) -> std::pin::Pin< @@ -7967,18 +9014,24 @@ FROM } } pub fn tricky_sql3() -> TrickySql3Stmt { - TrickySql3Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)")) + TrickySql3Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($$this is not a :bind_param$$, $1, $2)", None) } - pub struct TrickySql3Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql3Stmt(&'static str, Option); impl TrickySql3Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -7996,7 +9049,7 @@ FROM > for TrickySql3Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql3Params, ) -> std::pin::Pin< @@ -8010,18 +9063,24 @@ FROM } } pub fn tricky_sql4() -> TrickySql4Stmt { - TrickySql4Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)")) + TrickySql4Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ($tag$this is not a :bind_param$tag$, $1, $2)", None) } - pub struct TrickySql4Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql4Stmt(&'static str, Option); impl TrickySql4Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -8039,7 +9098,7 @@ FROM > for TrickySql4Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql4Params, ) -> std::pin::Pin< @@ -8053,18 +9112,24 @@ FROM } } pub fn tricky_sql6() -> TrickySql6Stmt { - TrickySql6Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)")) + TrickySql6Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is not a '':bind_param''', $1, $2)", None) } - pub struct TrickySql6Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql6Stmt(&'static str, Option); impl TrickySql6Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -8082,7 +9147,7 @@ FROM > for TrickySql6Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql6Params, ) -> std::pin::Pin< @@ -8096,18 +9161,24 @@ FROM } } pub fn tricky_sql7() -> TrickySql7Stmt { - TrickySql7Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)")) + TrickySql7Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is not a \':bind_param\'', $1, $2)", None) } - pub struct TrickySql7Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql7Stmt(&'static str, Option); impl TrickySql7Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -8125,7 +9196,7 @@ FROM > for TrickySql7Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql7Params, ) -> std::pin::Pin< @@ -8139,18 +9210,24 @@ FROM } } pub fn tricky_sql8() -> TrickySql8Stmt { - TrickySql8Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)")) + TrickySql8Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (e'this is ''not'' a \':bind_param\'', $1, $2)", None) } - pub struct TrickySql8Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql8Stmt(&'static str, Option); impl TrickySql8Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -8168,7 +9245,7 @@ FROM > for TrickySql8Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql8Params, ) -> std::pin::Pin< @@ -8182,18 +9259,24 @@ FROM } } pub fn tricky_sql9() -> TrickySql9Stmt { - TrickySql9Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)")) + TrickySql9Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES (E'this is \'not\' a \':bind_param\'', $1, $2)", None) } - pub struct TrickySql9Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql9Stmt(&'static str, Option); impl TrickySql9Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -8211,7 +9294,7 @@ FROM > for TrickySql9Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql9Params, ) -> std::pin::Pin< @@ -8225,18 +9308,24 @@ FROM } } pub fn tricky_sql10() -> TrickySql10Stmt { - TrickySql10Stmt(cornucopia_async :: private :: Stmt :: new("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)")) + TrickySql10Stmt("INSERT INTO syntax (\"trick:y\", async, enum) VALUES ('this is just a cast'::text, $1, $2)", None) } - pub struct TrickySql10Stmt(cornucopia_async::private::Stmt); + pub struct TrickySql10Stmt(&'static str, Option); impl TrickySql10Stmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub async fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, r#async: &'a super::super::super::types::public::SyntaxComposite, r#enum: &'a super::super::super::types::public::SyntaxEnum, ) -> Result { - let stmt = self.0.prepare(client).await?; - client.execute(stmt, &[r#async, r#enum]).await + client.execute(self.0, &[r#async, r#enum]).await } } impl<'a, C: GenericClient + Send + Sync> @@ -8254,7 +9343,7 @@ FROM > for TrickySql10Stmt { fn params( - &'a mut self, + &'a self, client: &'a C, params: &'a super::TrickySql10Params, ) -> std::pin::Pin< @@ -8268,18 +9357,26 @@ FROM } } pub fn r#typeof() -> RTypeofStmt { - RTypeofStmt(cornucopia_async::private::Stmt::new("SELECT * FROM syntax")) + RTypeofStmt("SELECT * FROM syntax", None) } - pub struct RTypeofStmt(cornucopia_async::private::Stmt); + pub struct RTypeofStmt(&'static str, Option); impl RTypeofStmt { + pub async fn prepare<'a, C: GenericClient>( + mut self, + client: &'a C, + ) -> Result { + self.1 = Some(client.prepare(self.0).await?); + Ok(self) + } pub fn bind<'a, C: GenericClient>( - &'a mut self, + &'a self, client: &'a C, ) -> TypeofQuery<'a, C, super::Typeof, 0> { TypeofQuery { client, params: [], - stmt: &mut self.0, + query: self.0, + cached: self.1.as_ref(), extractor: |row| super::TypeofBorrowed { trick_y: row.get(0), r#async: row.get(1),