Skip to content

Commit 01b7229

Browse files
committed
feat: Add ExecuteEx::replace_arguments
Addresses #3839
1 parent 91d26ba commit 01b7229

File tree

4 files changed

+85
-3
lines changed

4 files changed

+85
-3
lines changed

sqlx-core/src/executor.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::arguments::IntoArguments;
12
use crate::database::Database;
23
use crate::describe::Describe;
34
use crate::error::{BoxDynError, Error};
@@ -210,6 +211,16 @@ pub trait Execute<'q, DB: Database>: Send + Sized {
210211
fn persistent(&self) -> bool;
211212
}
212213

214+
pub trait ExecuteEx<'q, DB: Database, A: IntoArguments<'q, DB>>: Execute<'q, DB> {
215+
/// Replaces the arguments to be bound against the query string.
216+
///
217+
/// See [`Execute::take_arguments`] for the return value considerations
218+
fn replace_arguments(
219+
&mut self,
220+
arguments: A,
221+
) -> Result<Option<<DB as Database>::Arguments<'q>>, BoxDynError>;
222+
}
223+
213224
// NOTE: `Execute` is explicitly not implemented for String and &String to make it slightly more
214225
// involved to write `conn.execute(format!("SELECT {val}"))`
215226
impl<'q, DB: Database> Execute<'q, DB> for &'q str {
@@ -255,3 +266,15 @@ impl<'q, DB: Database> Execute<'q, DB> for (&'q str, Option<<DB as Database>::Ar
255266
true
256267
}
257268
}
269+
270+
impl<'q, DB: Database, A: IntoArguments<'q, DB>> ExecuteEx<'q, DB, A>
271+
for (&'q str, Option<<DB as Database>::Arguments<'q>>)
272+
{
273+
#[inline]
274+
fn replace_arguments(
275+
&mut self,
276+
arguments: A,
277+
) -> Result<Option<<DB as Database>::Arguments<'q>>, BoxDynError> {
278+
Ok(self.1.replace(arguments.into_arguments()))
279+
}
280+
}

sqlx-core/src/query.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::arguments::{Arguments, IntoArguments};
88
use crate::database::{Database, HasStatementCache};
99
use crate::encode::Encode;
1010
use crate::error::{BoxDynError, Error};
11-
use crate::executor::{Execute, Executor};
11+
use crate::executor::{Execute, ExecuteEx, Executor};
1212
use crate::statement::Statement;
1313
use crate::types::Type;
1414

@@ -72,6 +72,23 @@ where
7272
}
7373
}
7474

75+
impl<'q, DB, A> ExecuteEx<'q, DB, A> for Query<'q, DB, A>
76+
where
77+
DB: Database,
78+
A: Send + IntoArguments<'q, DB>,
79+
{
80+
#[inline]
81+
fn replace_arguments(
82+
&mut self,
83+
arguments: A,
84+
) -> Result<Option<<DB as Database>::Arguments<'q>>, BoxDynError> {
85+
self.arguments
86+
.replace(Ok(arguments))
87+
.transpose()
88+
.map(|option| option.map(IntoArguments::into_arguments))
89+
}
90+
}
91+
7592
impl<'q, DB: Database> Query<'q, DB, <DB as Database>::Arguments<'q>> {
7693
/// Bind a value for use with this SQL query.
7794
///
@@ -323,6 +340,20 @@ where
323340
}
324341
}
325342

343+
impl<'q, DB, F: Send, A: Send> ExecuteEx<'q, DB, A> for Map<'q, DB, F, A>
344+
where
345+
DB: Database,
346+
A: IntoArguments<'q, DB>,
347+
{
348+
#[inline]
349+
fn replace_arguments(
350+
&mut self,
351+
arguments: A,
352+
) -> Result<Option<<DB as Database>::Arguments<'q>>, BoxDynError> {
353+
self.inner.replace_arguments(arguments)
354+
}
355+
}
356+
326357
impl<'q, DB, F, O, A> Map<'q, DB, F, A>
327358
where
328359
DB: Database,

sqlx-core/src/query_as.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::arguments::IntoArguments;
88
use crate::database::{Database, HasStatementCache};
99
use crate::encode::Encode;
1010
use crate::error::{BoxDynError, Error};
11-
use crate::executor::{Execute, Executor};
11+
use crate::executor::{Execute, ExecuteEx, Executor};
1212
use crate::from_row::FromRow;
1313
use crate::query::{query, query_statement, query_statement_with, query_with_result, Query};
1414
use crate::types::Type;
@@ -47,6 +47,20 @@ where
4747
}
4848
}
4949

50+
impl<'q, DB, O: Send, A: Send> ExecuteEx<'q, DB, A> for QueryAs<'q, DB, O, A>
51+
where
52+
DB: Database,
53+
A: 'q + IntoArguments<'q, DB>,
54+
{
55+
#[inline]
56+
fn replace_arguments(
57+
&mut self,
58+
arguments: A,
59+
) -> Result<Option<<DB as Database>::Arguments<'q>>, BoxDynError> {
60+
self.inner.replace_arguments(arguments)
61+
}
62+
}
63+
5064
impl<'q, DB: Database, O> QueryAs<'q, DB, O, <DB as Database>::Arguments<'q>> {
5165
/// Bind a value for use with this SQL query.
5266
///

sqlx-core/src/query_scalar.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::arguments::IntoArguments;
66
use crate::database::{Database, HasStatementCache};
77
use crate::encode::Encode;
88
use crate::error::{BoxDynError, Error};
9-
use crate::executor::{Execute, Executor};
9+
use crate::executor::{Execute, ExecuteEx, Executor};
1010
use crate::from_row::FromRow;
1111
use crate::query_as::{
1212
query_as, query_as_with_result, query_statement_as, query_statement_as_with, QueryAs,
@@ -44,6 +44,20 @@ where
4444
}
4545
}
4646

47+
impl<'q, DB, O: Send, A: Send> ExecuteEx<'q, DB, A> for QueryScalar<'q, DB, O, A>
48+
where
49+
DB: Database,
50+
A: 'q + IntoArguments<'q, DB>,
51+
{
52+
#[inline]
53+
fn replace_arguments(
54+
&mut self,
55+
arguments: A,
56+
) -> Result<Option<<DB as Database>::Arguments<'q>>, BoxDynError> {
57+
self.inner.replace_arguments(arguments)
58+
}
59+
}
60+
4761
impl<'q, DB: Database, O> QueryScalar<'q, DB, O, <DB as Database>::Arguments<'q>> {
4862
/// Bind a value for use with this SQL query.
4963
///

0 commit comments

Comments
 (0)