1
+ mod utils;
2
+
1
3
use crate :: AsyncConnectionCore ;
2
4
use diesel:: associations:: HasTable ;
3
5
use diesel:: query_builder:: IntoUpdateTarget ;
4
6
use diesel:: result:: QueryResult ;
5
7
use diesel:: AsChangeset ;
6
8
use futures_core:: future:: BoxFuture ;
7
- use futures_core:: Stream ;
8
- use futures_util:: { future, stream, FutureExt , StreamExt , TryFutureExt , TryStreamExt } ;
9
+ #[ cfg( any( feature = "mysql" , feature = "postgres" ) ) ]
10
+ use futures_util:: FutureExt ;
11
+ use futures_util:: { stream, StreamExt , TryStreamExt } ;
9
12
use std:: future:: Future ;
10
- use std:: pin:: Pin ;
11
13
12
14
/// The traits used by `QueryDsl`.
13
15
///
@@ -22,7 +24,7 @@ pub mod methods {
22
24
use diesel:: expression:: QueryMetadata ;
23
25
use diesel:: query_builder:: { AsQuery , QueryFragment , QueryId } ;
24
26
use diesel:: query_dsl:: CompatibleType ;
25
- use futures_util:: { Future , Stream , TryFutureExt } ;
27
+ use futures_util:: { Future , Stream } ;
26
28
27
29
/// The `execute` method
28
30
///
@@ -74,6 +76,7 @@ pub mod methods {
74
76
type LoadFuture < ' conn > : Future < Output = QueryResult < Self :: Stream < ' conn > > > + Send
75
77
where
76
78
Conn : ' conn ;
79
+
77
80
/// The inner stream returned by [`LoadQuery::internal_load`]
78
81
type Stream < ' conn > : Stream < Item = QueryResult < U > > + Send
79
82
where
@@ -96,10 +99,7 @@ pub mod methods {
96
99
ST : ' static ,
97
100
{
98
101
type LoadFuture < ' conn >
99
- = future:: MapOk <
100
- Conn :: LoadFuture < ' conn , ' query > ,
101
- fn ( Conn :: Stream < ' conn , ' query > ) -> Self :: Stream < ' conn > ,
102
- >
102
+ = utils:: Map < Conn :: LoadFuture < ' conn , ' query > , Self :: Stream < ' conn > >
103
103
where
104
104
Conn : ' conn ;
105
105
@@ -112,33 +112,13 @@ pub mod methods {
112
112
Conn : ' conn ;
113
113
114
114
fn internal_load ( self , conn : & mut Conn ) -> Self :: LoadFuture < ' _ > {
115
- conn. load ( self )
116
- . map_ok ( map_result_stream_future :: < U , _ , _ , DB , ST > )
115
+ utils:: Map :: new ( conn. load ( self ) , |stream| {
116
+ Ok ( stream?. map ( |row| {
117
+ U :: build_from_row ( & row?) . map_err ( diesel:: result:: Error :: DeserializationError )
118
+ } ) )
119
+ } )
117
120
}
118
121
}
119
-
120
- #[ allow( clippy:: type_complexity) ]
121
- fn map_result_stream_future < ' s , ' a , U , S , R , DB , ST > (
122
- stream : S ,
123
- ) -> stream:: Map < S , fn ( QueryResult < R > ) -> QueryResult < U > >
124
- where
125
- S : Stream < Item = QueryResult < R > > + Send + ' s ,
126
- R : diesel:: row:: Row < ' a , DB > + ' s ,
127
- DB : Backend + ' static ,
128
- U : FromSqlRow < ST , DB > + ' static ,
129
- ST : ' static ,
130
- {
131
- stream. map ( map_row_helper :: < _ , DB , U , ST > )
132
- }
133
-
134
- fn map_row_helper < ' a , R , DB , U , ST > ( row : QueryResult < R > ) -> QueryResult < U >
135
- where
136
- U : FromSqlRow < ST , DB > ,
137
- R : diesel:: row:: Row < ' a , DB > ,
138
- DB : Backend ,
139
- {
140
- U :: build_from_row ( & row?) . map_err ( diesel:: result:: Error :: DeserializationError )
141
- }
142
122
}
143
123
144
124
/// The return types produced by the various [`RunQueryDsl`] methods
@@ -149,37 +129,24 @@ pub mod methods {
149
129
// the same connection
150
130
#[ allow( type_alias_bounds) ] // we need these bounds otherwise we cannot use GAT's
151
131
pub mod return_futures {
132
+ use crate :: run_query_dsl:: utils;
133
+
152
134
use super :: methods:: LoadQuery ;
153
- use diesel:: QueryResult ;
154
- use futures_util:: { future, stream} ;
135
+ use futures_util:: stream;
155
136
use std:: pin:: Pin ;
156
137
157
138
/// The future returned by [`RunQueryDsl::load`](super::RunQueryDsl::load)
158
139
/// and [`RunQueryDsl::get_results`](super::RunQueryDsl::get_results)
159
140
///
160
141
/// This is essentially `impl Future<Output = QueryResult<Vec<U>>>`
161
- pub type LoadFuture < ' conn , ' query , Q : LoadQuery < ' query , Conn , U > , Conn , U > = future:: AndThen <
162
- Q :: LoadFuture < ' conn > ,
163
- stream:: TryCollect < Q :: Stream < ' conn > , Vec < U > > ,
164
- fn ( Q :: Stream < ' conn > ) -> stream:: TryCollect < Q :: Stream < ' conn > , Vec < U > > ,
165
- > ;
142
+ pub type LoadFuture < ' conn , ' query , Q : LoadQuery < ' query , Conn , U > , Conn , U > =
143
+ utils:: AndThen < Q :: LoadFuture < ' conn > , stream:: TryCollect < Q :: Stream < ' conn > , Vec < U > > > ;
166
144
167
145
/// The future returned by [`RunQueryDsl::get_result`](super::RunQueryDsl::get_result)
168
146
///
169
147
/// This is essentially `impl Future<Output = QueryResult<U>>`
170
- pub type GetResult < ' conn , ' query , Q : LoadQuery < ' query , Conn , U > , Conn , U > = future:: AndThen <
171
- Q :: LoadFuture < ' conn > ,
172
- future:: Map <
173
- stream:: StreamFuture < Pin < Box < Q :: Stream < ' conn > > > > ,
174
- fn ( ( Option < QueryResult < U > > , Pin < Box < Q :: Stream < ' conn > > > ) ) -> QueryResult < U > ,
175
- > ,
176
- fn (
177
- Q :: Stream < ' conn > ,
178
- ) -> future:: Map <
179
- stream:: StreamFuture < Pin < Box < Q :: Stream < ' conn > > > > ,
180
- fn ( ( Option < QueryResult < U > > , Pin < Box < Q :: Stream < ' conn > > > ) ) -> QueryResult < U > ,
181
- > ,
182
- > ;
148
+ pub type GetResult < ' conn , ' query , Q : LoadQuery < ' query , Conn , U > , Conn , U > =
149
+ utils:: AndThen < Q :: LoadFuture < ' conn > , utils:: LoadNext < Pin < Box < Q :: Stream < ' conn > > > > > ;
183
150
}
184
151
185
152
/// Methods used to execute queries.
@@ -346,13 +313,7 @@ pub trait RunQueryDsl<Conn>: Sized {
346
313
Conn : AsyncConnectionCore ,
347
314
Self : methods:: LoadQuery < ' query , Conn , U > + ' query ,
348
315
{
349
- fn collect_result < U , S > ( stream : S ) -> stream:: TryCollect < S , Vec < U > >
350
- where
351
- S : Stream < Item = QueryResult < U > > ,
352
- {
353
- stream. try_collect ( )
354
- }
355
- self . internal_load ( conn) . and_then ( collect_result :: < U , _ > )
316
+ utils:: AndThen :: new ( self . internal_load ( conn) , |stream| Ok ( stream?. try_collect ( ) ) )
356
317
}
357
318
358
319
/// Executes the given query, returning a [`Stream`] with the returned rows.
@@ -547,29 +508,9 @@ pub trait RunQueryDsl<Conn>: Sized {
547
508
Conn : AsyncConnectionCore ,
548
509
Self : methods:: LoadQuery < ' query , Conn , U > + ' query ,
549
510
{
550
- #[ allow( clippy:: type_complexity) ]
551
- fn get_next_stream_element < S , U > (
552
- stream : S ,
553
- ) -> future:: Map <
554
- stream:: StreamFuture < Pin < Box < S > > > ,
555
- fn ( ( Option < QueryResult < U > > , Pin < Box < S > > ) ) -> QueryResult < U > ,
556
- >
557
- where
558
- S : Stream < Item = QueryResult < U > > ,
559
- {
560
- fn map_option_to_result < U , S > (
561
- ( o, _) : ( Option < QueryResult < U > > , Pin < Box < S > > ) ,
562
- ) -> QueryResult < U > {
563
- match o {
564
- Some ( s) => s,
565
- None => Err ( diesel:: result:: Error :: NotFound ) ,
566
- }
567
- }
568
-
569
- Box :: pin ( stream) . into_future ( ) . map ( map_option_to_result)
570
- }
571
-
572
- self . load_stream ( conn) . and_then ( get_next_stream_element)
511
+ utils:: AndThen :: new ( self . internal_load ( conn) , |stream| {
512
+ Ok ( utils:: LoadNext :: new ( Box :: pin ( stream?) ) )
513
+ } )
573
514
}
574
515
575
516
/// Runs the command, returning an `Vec` with the affected rows.
0 commit comments