Skip to content
Merged
Changes from 2 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
eaf21f1
implement `LoadQuery` for `InsertStatement` with `BatchInsert` for `S…
bwqr May 25, 2025
dd92b09
put LoadQuery implementation behind `returning_clauses_for_sqlite_3_3…
bwqr May 25, 2025
2bd74c7
implement RunQueryDsl on batch insert statements with sqlite connecti…
bwqr May 29, 2025
18ed4ed
use `LoadIter` as iterator for `LoadQuery` implementation of sqlite's…
bwqr May 29, 2025
b70cbcf
implement `LoadQuery` for `InsertStatement` with `BatchInsert` for `S…
bwqr May 29, 2025
585e5ab
Merge branch 'master' of https://github.com/bwqr/diesel into impl-loa…
bwqr May 29, 2025
d92b6c6
bump minimal supported Rust version to 1.84.0
bwqr May 29, 2025
bc80aa7
implement LoadQuery for SqliteBatchInsertWrapper with on conflict clause
bwqr May 29, 2025
5834854
implement ExecuteDsl on batch insert statements using on conflict cla…
bwqr May 29, 2025
4dc6d23
fix clippy warnings
bwqr May 29, 2025
8436523
remove ExecuteDsl implementation for on conflict clause.
bwqr May 29, 2025
446af6a
update sqlite/all_about_inserts examples to reflect latest `LoadQuery…
bwqr May 29, 2025
8744dd0
early bubble up any errors other than deserialization in transaction …
bwqr May 30, 2025
9050d32
add tests related for sqlite related to batch insert with returning c…
bwqr May 30, 2025
b3def36
remove unnecessary trait bounds, reorganize impl blocks for consistency
bwqr May 30, 2025
e181641
revert making LoadIter pub(crate) since it is not required anymore
bwqr May 30, 2025
2aabce0
run rustfmt on diesel_tests/tests/insert.rs
bwqr May 30, 2025
0bc4518
Add changelog entry
weiznich Jun 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::prelude::*;
use crate::query_builder::upsert::on_conflict_clause::OnConflictValues;
use crate::query_builder::{AstPass, QueryId, ValuesClause};
use crate::query_builder::{DebugQuery, QueryFragment};
use crate::query_dsl::methods::ExecuteDsl;
use crate::query_dsl::{methods::ExecuteDsl, LoadQuery};
use crate::sqlite::Sqlite;
use std::fmt::{self, Debug, Display};

Expand Down Expand Up @@ -273,6 +273,36 @@ where
}
}

impl<'query, V, T, QId, Op, O, U, B, const STATIC_QUERY_ID: bool>
LoadQuery<'query, SqliteConnection, U, B>
for InsertStatement<T, BatchInsert<Vec<ValuesClause<V, T>>, T, QId, STATIC_QUERY_ID>, Op>
where
T: QuerySource,
V: ContainsDefaultableValue<Out = O>,
O: Default,
(O, Self): LoadQuery<'query, SqliteConnection, U, B>,
{
type RowIter<'conn> = <(O, Self) as LoadQuery<'query, SqliteConnection, U, B>>::RowIter<'conn>;

fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
<(O, Self) as LoadQuery<'query, SqliteConnection, U, B>>::internal_load(
(O::default(), self),
conn,
)
}
}

impl<V, T, QId, Op, const STATIC_QUERY_ID: bool> RunQueryDsl<SqliteConnection>
for (
No,
InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>,
)
where
T: QuerySource,
InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>: RunQueryDsl<SqliteConnection>,
{
}

#[allow(missing_debug_implementations, missing_copy_implementations)]
#[repr(transparent)]
pub struct SqliteBatchInsertWrapper<V, T, QId, const STATIC_QUERY_ID: bool>(
Expand Down Expand Up @@ -400,6 +430,48 @@ where
}
}

#[cfg(feature = "returning_clauses_for_sqlite_3_35")]
impl<'query, V, T, QId, Op, U, B, const STATIC_QUERY_ID: bool>
LoadQuery<'query, SqliteConnection, U, B>
for (
No,
InsertStatement<T, BatchInsert<V, T, QId, STATIC_QUERY_ID>, Op>,
)
where
T: Table + QueryId + 'static,
T::FromClause: QueryFragment<Sqlite>,
Op: QueryFragment<Sqlite> + QueryId,
<T as Table>::AllColumns: QueryFragment<Sqlite> + QueryId + crate::expression::NonAggregate,
Sqlite: crate::expression::QueryMetadata<<<T as Table>::AllColumns as Expression>::SqlType>,
SqliteBatchInsertWrapper<V, T, QId, STATIC_QUERY_ID>:
QueryFragment<Sqlite> + QueryId + CanInsertInSingleQuery<Sqlite>,
// Row to U deserialization bounds
U: crate::deserialize::FromSqlRow<<<T as Table>::AllColumns as Expression>::SqlType, Sqlite>
+ 'static,
// Connection bounds
SqliteConnection: crate::connection::LoadConnection<B>,
{
type RowIter<'conn> = Box<dyn Iterator<Item = QueryResult<U>> + 'conn>;

fn internal_load(self, conn: &mut SqliteConnection) -> QueryResult<Self::RowIter<'_>> {
let (No, query) = self;

let query = InsertStatement {
records: SqliteBatchInsertWrapper(query.records),
operator: query.operator,
target: query.target,
returning: crate::query_builder::returning_clause::ReturningClause(T::all_columns()),
into_clause: query.into_clause,
};

let results = <_ as crate::connection::LoadConnection<B>>::load(conn, query)?
.map(|row| U::build_from_row(&row?).map_err(crate::result::Error::DeserializationError))
.collect::<Vec<_>>();

Ok(Box::new(results.into_iter()))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to skip the collect here and return the iterator directly?

}
}

macro_rules! tuple_impls {
($(
$Tuple:tt {
Expand Down
Loading