1- use std:: { rc:: Rc , sync:: Arc } ;
1+ use std:: { marker :: PhantomData , rc:: Rc , sync:: Arc } ;
22
33use sqlx_core:: {
44 database:: Database ,
@@ -9,12 +9,15 @@ use sqlx_core::{
99
1010use crate :: { arguments:: ExaBuffer , Exasol } ;
1111
12- /// Adapter allowing any iterator of encodable values to be passed as a parameter array for a column
13- /// to Exasol in a single query invocation. The adapter is needed because [`Encode`] is still a
14- /// foreign trait and thus cannot be implemented in a generic manner.
12+ /// Adapter allowing any iterator of encodable values to be treated and passed as a one dimensional
13+ /// parameter array for a column to Exasol in a single query invocation. Multi dimensional arrays
14+ /// are not supported. The adapter is needed because [`Encode`] is still a foreign trait and thus
15+ /// cannot be implemented in a generic manner.
1516///
1617/// Note that the [`Encode`] trait requires the ability to encode by reference, thus the adapter
17- /// takes a reference that must implement [`IntoIterator`].
18+ /// takes a reference that implements [`IntoIterator`]. But since iteration requires mutability,
19+ /// the adaptar also requires [`Clone`]. The adapter definition should steer it towards being used
20+ /// with cheaply clonable iterators since it expects the iteration elements to be references.
1821///
1922/// ```rust
2023/// # use sqlx_exasol_impl as sqlx_exasol;
@@ -25,47 +28,53 @@ use crate::{arguments::ExaBuffer, Exasol};
2528/// ```
2629#[ derive( Debug ) ]
2730#[ repr( transparent) ]
28- pub struct ExaIter < ' i , I > ( & ' i I )
31+ pub struct ExaIter < ' i , I , T >
2932where
30- I : ?Sized ,
31- & ' i I : IntoIterator ,
32- <& ' i I as IntoIterator >:: Item : for < ' q > Encode < ' q , Exasol > + Type < Exasol > ;
33+ I : IntoIterator < Item = & ' i T > + Clone ,
34+ T : ' i ,
35+ {
36+ into_iter : I ,
37+ data_lifetime : PhantomData < & ' i ( ) > ,
38+ }
3339
34- impl < ' i , I > ExaIter < ' i , I >
40+ impl < ' i , ' q , I , T > ExaIter < ' i , I , T >
3541where
36- I : ? Sized ,
37- & ' i I : IntoIterator ,
38- < & ' i I as IntoIterator > :: Item : for < ' q > Encode < ' q , Exasol > + Type < Exasol > ,
42+ I : IntoIterator < Item = & ' i T > + Clone ,
43+ T : ' i + Type < Exasol > + Encode < ' q , Exasol > ,
44+ ' i : ' q ,
3945{
40- pub fn new ( into_iter : & ' i I ) -> Self {
41- Self ( into_iter)
46+ pub fn new ( into_iter : I ) -> Self {
47+ Self {
48+ into_iter,
49+ data_lifetime : PhantomData ,
50+ }
4251 }
4352}
4453
45- impl < ' i , I > Type < Exasol > for ExaIter < ' i , I >
54+ impl < ' i , I , T > Type < Exasol > for ExaIter < ' i , I , T >
4655where
47- I : ?Sized ,
48- & ' i I : IntoIterator ,
49- <& ' i I as IntoIterator >:: Item : for < ' q > Encode < ' q , Exasol > + Type < Exasol > ,
56+ I : IntoIterator < Item = & ' i T > + Clone ,
57+ T : ' i + Type < Exasol > ,
5058{
5159 fn type_info ( ) -> <Exasol as Database >:: TypeInfo {
52- <& ' i I as IntoIterator >:: Item :: type_info ( )
60+ <I as IntoIterator >:: Item :: type_info ( )
5361 }
5462}
5563
56- impl < ' i , I > Encode < ' _ , Exasol > for ExaIter < ' i , I >
64+ impl < ' i , ' q , I , T > Encode < ' q , Exasol > for ExaIter < ' i , I , T >
5765where
58- I : ? Sized ,
59- & ' i I : IntoIterator ,
60- < & ' i I as IntoIterator > :: Item : for < ' q > Encode < ' q , Exasol > + Type < Exasol > ,
66+ I : IntoIterator < Item = & ' i T > + Clone ,
67+ T : ' i + Encode < ' q , Exasol > ,
68+ ' i : ' q ,
6169{
6270 fn encode_by_ref ( & self , buf : & mut ExaBuffer ) -> Result < IsNull , BoxDynError > {
63- buf. append_iter ( self . 0 ) ?;
71+ buf. append_iter ( self . into_iter . clone ( ) ) ?;
6472 Ok ( IsNull :: No )
6573 }
6674
6775 fn size_hint ( & self ) -> usize {
68- self . 0
76+ self . into_iter
77+ . clone ( )
6978 . into_iter ( )
7079 . fold ( 0 , |sum, item| sum + item. size_hint ( ) )
7180 }
0 commit comments