Skip to content

Commit 469f227

Browse files
breaking: add SqlStr (#3723)
* refactor: introduce `SqlSafeStr` API * rebase main * Add SqlStr + remove Statement lifetime * Update the definition of Executor and AnyConnectionBackend + update Postgres driver * Update MySql driver * Update Sqlite driver * remove debug clone count * Reduce the amount of SqlStr clones * improve QueryBuilder error message * cargo fmt * fix clippy warnings * fix doc test * Avoid panic in `QueryBuilder::reset` * Use `QueryBuilder` when removing all test db's * Add comment to `SqlStr` Co-authored-by: Austin Bonander <austin.bonander@gmail.com> * Update sqlx-core/src/query_builder.rs Co-authored-by: Austin Bonander <austin.bonander@gmail.com> * Add `Clone` as supertrait to `Statement` * Move `Connection`, `AnyConnectionBackend` and `TransactionManager` to `SqlStr` * Replace `sql_cloned` with `sql` in `Statement` * Update `Executor` trait * Update unit tests + QueryBuilder changes * Remove code in comments * Update comment in `QueryBuilder` * Fix clippy warnings * Update `Migrate` comment * Small changes * Move `Migration` to `SqlStr` --------- Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
1 parent 2702b98 commit 469f227

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+901
-625
lines changed

sqlx-core/src/any/connection/backend.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::any::{Any, AnyArguments, AnyQueryResult, AnyRow, AnyStatement, AnyTypeInfo};
22
use crate::describe::Describe;
3+
use crate::sql_str::SqlStr;
34
use either::Either;
45
use futures_core::future::BoxFuture;
56
use futures_core::stream::BoxStream;
6-
use std::borrow::Cow;
77
use std::fmt::Debug;
88

99
pub trait AnyConnectionBackend: std::any::Any + Debug + Send + 'static {
@@ -33,7 +33,7 @@ pub trait AnyConnectionBackend: std::any::Any + Debug + Send + 'static {
3333
///
3434
/// If we are already inside a transaction and `statement.is_some()`, then
3535
/// `Error::InvalidSavePoint` is returned without running any statements.
36-
fn begin(&mut self, statement: Option<Cow<'static, str>>) -> BoxFuture<'_, crate::Result<()>>;
36+
fn begin(&mut self, statement: Option<SqlStr>) -> BoxFuture<'_, crate::Result<()>>;
3737

3838
fn commit(&mut self) -> BoxFuture<'_, crate::Result<()>>;
3939

@@ -96,23 +96,23 @@ pub trait AnyConnectionBackend: std::any::Any + Debug + Send + 'static {
9696

9797
fn fetch_many<'q>(
9898
&'q mut self,
99-
query: &'q str,
99+
query: SqlStr,
100100
persistent: bool,
101101
arguments: Option<AnyArguments<'q>>,
102102
) -> BoxStream<'q, crate::Result<Either<AnyQueryResult, AnyRow>>>;
103103

104104
fn fetch_optional<'q>(
105105
&'q mut self,
106-
query: &'q str,
106+
query: SqlStr,
107107
persistent: bool,
108108
arguments: Option<AnyArguments<'q>>,
109109
) -> BoxFuture<'q, crate::Result<Option<AnyRow>>>;
110110

111111
fn prepare_with<'c, 'q: 'c>(
112112
&'c mut self,
113-
sql: &'q str,
113+
sql: SqlStr,
114114
parameters: &[AnyTypeInfo],
115-
) -> BoxFuture<'c, crate::Result<AnyStatement<'q>>>;
115+
) -> BoxFuture<'c, crate::Result<AnyStatement>>;
116116

117-
fn describe<'q>(&'q mut self, sql: &'q str) -> BoxFuture<'q, crate::Result<Describe<Any>>>;
117+
fn describe(&mut self, sql: SqlStr) -> BoxFuture<'_, crate::Result<Describe<Any>>>;
118118
}

sqlx-core/src/any/connection/executor.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::any::{Any, AnyConnection, AnyQueryResult, AnyRow, AnyStatement, AnyTy
22
use crate::describe::Describe;
33
use crate::error::Error;
44
use crate::executor::{Execute, Executor};
5+
use crate::sql_str::SqlStr;
56
use either::Either;
67
use futures_core::future::BoxFuture;
78
use futures_core::stream::BoxStream;
@@ -23,8 +24,8 @@ impl<'c> Executor<'c> for &'c mut AnyConnection {
2324
Ok(arguments) => arguments,
2425
Err(error) => return stream::once(future::ready(Err(error))).boxed(),
2526
};
26-
self.backend
27-
.fetch_many(query.sql(), query.persistent(), arguments)
27+
let persistent = query.persistent();
28+
self.backend.fetch_many(query.sql(), persistent, arguments)
2829
}
2930

3031
fn fetch_optional<'e, 'q: 'e, E>(
@@ -39,25 +40,23 @@ impl<'c> Executor<'c> for &'c mut AnyConnection {
3940
Ok(arguments) => arguments,
4041
Err(error) => return future::ready(Err(error)).boxed(),
4142
};
43+
let persistent = query.persistent();
4244
self.backend
43-
.fetch_optional(query.sql(), query.persistent(), arguments)
45+
.fetch_optional(query.sql(), persistent, arguments)
4446
}
4547

46-
fn prepare_with<'e, 'q: 'e>(
48+
fn prepare_with<'e>(
4749
self,
48-
sql: &'q str,
50+
sql: SqlStr,
4951
parameters: &[AnyTypeInfo],
50-
) -> BoxFuture<'e, Result<AnyStatement<'q>, Error>>
52+
) -> BoxFuture<'e, Result<AnyStatement, Error>>
5153
where
5254
'c: 'e,
5355
{
5456
self.backend.prepare_with(sql, parameters)
5557
}
5658

57-
fn describe<'e, 'q: 'e>(
58-
self,
59-
sql: &'q str,
60-
) -> BoxFuture<'e, Result<Describe<Self::Database>, Error>>
59+
fn describe<'e>(self, sql: SqlStr) -> BoxFuture<'e, Result<Describe<Self::Database>, Error>>
6160
where
6261
'c: 'e,
6362
{

sqlx-core/src/any/connection/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use futures_core::future::BoxFuture;
2-
use std::borrow::Cow;
32
use std::future::Future;
43

54
use crate::any::{Any, AnyConnectOptions};
65
use crate::connection::{ConnectOptions, Connection};
76
use crate::error::Error;
87

98
use crate::database::Database;
9+
use crate::sql_str::SqlSafeStr;
1010
pub use backend::AnyConnectionBackend;
1111

1212
use crate::transaction::Transaction;
@@ -96,12 +96,12 @@ impl Connection for AnyConnection {
9696

9797
fn begin_with(
9898
&mut self,
99-
statement: impl Into<Cow<'static, str>>,
99+
statement: impl SqlSafeStr,
100100
) -> impl Future<Output = Result<Transaction<'_, Self::Database>, Error>> + Send + '_
101101
where
102102
Self: Sized,
103103
{
104-
Transaction::begin(self, Some(statement.into()))
104+
Transaction::begin(self, Some(statement.into_sql_str()))
105105
}
106106

107107
fn cached_statements_size(&self) -> usize {

sqlx-core/src/any/database.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl Database for Any {
2828
type Arguments<'q> = AnyArguments<'q>;
2929
type ArgumentBuffer<'q> = AnyArgumentBuffer<'q>;
3030

31-
type Statement<'q> = AnyStatement<'q>;
31+
type Statement = AnyStatement;
3232

3333
const NAME: &'static str = "Any";
3434

sqlx-core/src/any/statement.rs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ use crate::column::ColumnIndex;
33
use crate::database::Database;
44
use crate::error::Error;
55
use crate::ext::ustr::UStr;
6+
use crate::sql_str::SqlStr;
67
use crate::statement::Statement;
78
use crate::HashMap;
89
use either::Either;
9-
use std::borrow::Cow;
1010
use std::sync::Arc;
1111

12-
pub struct AnyStatement<'q> {
12+
#[derive(Clone)]
13+
pub struct AnyStatement {
1314
#[doc(hidden)]
14-
pub sql: Cow<'q, str>,
15+
pub sql: SqlStr,
1516
#[doc(hidden)]
1617
pub parameters: Option<Either<Vec<AnyTypeInfo>, usize>>,
1718
#[doc(hidden)]
@@ -20,19 +21,14 @@ pub struct AnyStatement<'q> {
2021
pub columns: Vec<AnyColumn>,
2122
}
2223

23-
impl<'q> Statement<'q> for AnyStatement<'q> {
24+
impl Statement for AnyStatement {
2425
type Database = Any;
2526

26-
fn to_owned(&self) -> AnyStatement<'static> {
27-
AnyStatement::<'static> {
28-
sql: Cow::Owned(self.sql.clone().into_owned()),
29-
column_names: self.column_names.clone(),
30-
parameters: self.parameters.clone(),
31-
columns: self.columns.clone(),
32-
}
27+
fn into_sql(self) -> SqlStr {
28+
self.sql
3329
}
3430

35-
fn sql(&self) -> &str {
31+
fn sql(&self) -> &SqlStr {
3632
&self.sql
3733
}
3834

@@ -51,8 +47,8 @@ impl<'q> Statement<'q> for AnyStatement<'q> {
5147
impl_statement_query!(AnyArguments<'_>);
5248
}
5349

54-
impl ColumnIndex<AnyStatement<'_>> for &'_ str {
55-
fn index(&self, statement: &AnyStatement<'_>) -> Result<usize, Error> {
50+
impl ColumnIndex<AnyStatement> for &'_ str {
51+
fn index(&self, statement: &AnyStatement) -> Result<usize, Error> {
5652
statement
5753
.column_names
5854
.get(*self)
@@ -61,15 +57,14 @@ impl ColumnIndex<AnyStatement<'_>> for &'_ str {
6157
}
6258
}
6359

64-
impl<'q> AnyStatement<'q> {
60+
impl AnyStatement {
6561
#[doc(hidden)]
6662
pub fn try_from_statement<S>(
67-
query: &'q str,
68-
statement: &S,
63+
statement: S,
6964
column_names: Arc<HashMap<UStr, usize>>,
7065
) -> crate::Result<Self>
7166
where
72-
S: Statement<'q>,
67+
S: Statement,
7368
AnyTypeInfo: for<'a> TryFrom<&'a <S::Database as Database>::TypeInfo, Error = Error>,
7469
AnyColumn: for<'a> TryFrom<&'a <S::Database as Database>::Column, Error = Error>,
7570
{
@@ -91,7 +86,7 @@ impl<'q> AnyStatement<'q> {
9186
.collect::<Result<Vec<_>, _>>()?;
9287

9388
Ok(Self {
94-
sql: query.into(),
89+
sql: statement.into_sql(),
9590
columns,
9691
column_names,
9792
parameters,

sqlx-core/src/any/transaction.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
use std::borrow::Cow;
21
use std::future::Future;
32

43
use crate::any::{Any, AnyConnection};
54
use crate::database::Database;
65
use crate::error::Error;
6+
use crate::sql_str::SqlStr;
77
use crate::transaction::TransactionManager;
88

99
pub struct AnyTransactionManager;
1010

1111
impl TransactionManager for AnyTransactionManager {
1212
type Database = Any;
1313

14-
fn begin<'conn>(
15-
conn: &'conn mut AnyConnection,
16-
statement: Option<Cow<'static, str>>,
17-
) -> impl Future<Output = Result<(), Error>> + Send + 'conn {
14+
fn begin(
15+
conn: &mut AnyConnection,
16+
statement: Option<SqlStr>,
17+
) -> impl Future<Output = Result<(), Error>> + Send + '_ {
1818
conn.backend.begin(statement)
1919
}
2020

sqlx-core/src/column.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ macro_rules! impl_column_index_for_row {
125125
#[macro_export]
126126
macro_rules! impl_column_index_for_statement {
127127
($S:ident) => {
128-
impl $crate::column::ColumnIndex<$S<'_>> for usize {
129-
fn index(&self, statement: &$S<'_>) -> Result<usize, $crate::error::Error> {
128+
impl $crate::column::ColumnIndex<$S> for usize {
129+
fn index(&self, statement: &$S) -> Result<usize, $crate::error::Error> {
130130
let len = $crate::statement::Statement::columns(statement).len();
131131

132132
if *self >= len {

sqlx-core/src/connection.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::database::{Database, HasStatementCache};
22
use crate::error::Error;
33

4+
use crate::sql_str::SqlSafeStr;
45
use crate::transaction::{Transaction, TransactionManager};
56
use futures_core::future::BoxFuture;
67
use log::LevelFilter;
7-
use std::borrow::Cow;
88
use std::fmt::Debug;
99
use std::future::Future;
1010
use std::str::FromStr;
@@ -59,12 +59,12 @@ pub trait Connection: Send {
5959
/// `statement` does not put the connection into a transaction.
6060
fn begin_with(
6161
&mut self,
62-
statement: impl Into<Cow<'static, str>>,
62+
statement: impl SqlSafeStr,
6363
) -> impl Future<Output = Result<Transaction<'_, Self::Database>, Error>> + Send + '_
6464
where
6565
Self: Sized,
6666
{
67-
Transaction::begin(self, Some(statement.into()))
67+
Transaction::begin(self, Some(statement.into_sql_str()))
6868
}
6969

7070
/// Returns `true` if the connection is currently in a transaction.

sqlx-core/src/database.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub trait Database: 'static + Sized + Send + Debug {
101101
type ArgumentBuffer<'q>;
102102

103103
/// The concrete `Statement` implementation for this database.
104-
type Statement<'q>: Statement<'q, Database = Self>;
104+
type Statement: Statement<Database = Self>;
105105

106106
/// The display name for this database driver.
107107
const NAME: &'static str;

0 commit comments

Comments
 (0)