Skip to content

Commit fec4941

Browse files
committed
improvements on compile time array types support
1 parent 9f0ace1 commit fec4941

File tree

5 files changed

+69
-29
lines changed

5 files changed

+69
-29
lines changed

sqlx-exasol-impl/src/arguments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl ExaBuffer {
7777
pub fn append_iter<'q, I, T>(&mut self, iter: I) -> Result<(), BoxDynError>
7878
where
7979
I: IntoIterator<Item = T>,
80-
T: 'q + Encode<'q, Exasol> + Type<Exasol>,
80+
T: 'q + Encode<'q, Exasol>,
8181
{
8282
let mut iter = iter.into_iter();
8383

sqlx-exasol-impl/src/types/iter.rs

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{rc::Rc, sync::Arc};
1+
use std::{marker::PhantomData, rc::Rc, sync::Arc};
22

33
use sqlx_core::{
44
database::Database,
@@ -9,12 +9,15 @@ use sqlx_core::{
99

1010
use 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>
2932
where
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>
3541
where
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>
4655
where
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>
5765
where
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
}

sqlx-exasol-impl/src/types/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,4 @@ mod uuid;
1717
pub use ::chrono::Duration;
1818
#[cfg(feature = "chrono")]
1919
pub use chrono::Months;
20-
2120
pub use iter::ExaIter;

src/ty_match.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
44
use std::{marker::PhantomData, rc::Rc, sync::Arc};
55

6+
use sqlx_exasol_impl::types::ExaIter;
7+
68
#[allow(clippy::just_underscores_and_digits)]
79
pub fn same_type<T>(_1: &T, _2: &T) {}
810

@@ -138,6 +140,34 @@ impl<'a, T> MatchBorrowExt for MatchBorrow<&'a T, Arc<[T]>> {
138140
type Matched = &'a T;
139141
}
140142

143+
impl<'i, I, T> MatchBorrowExt for MatchBorrow<T, ExaIter<'i, I, Option<T>>>
144+
where
145+
I: IntoIterator<Item = &'i Option<T>> + Clone,
146+
{
147+
type Matched = T;
148+
}
149+
150+
impl<'i, I, T> MatchBorrowExt for MatchBorrow<&'i T, ExaIter<'i, I, Option<T>>>
151+
where
152+
I: IntoIterator<Item = &'i Option<T>> + Clone,
153+
{
154+
type Matched = &'i T;
155+
}
156+
157+
impl<'i, I, T> MatchBorrowExt for MatchBorrow<T, ExaIter<'i, I, T>>
158+
where
159+
I: IntoIterator<Item = &'i T> + Clone,
160+
{
161+
type Matched = T;
162+
}
163+
164+
impl<'i, I, T> MatchBorrowExt for MatchBorrow<&'i T, ExaIter<'i, I, T>>
165+
where
166+
I: IntoIterator<Item = &'i T> + Clone,
167+
{
168+
type Matched = &'i T;
169+
}
170+
141171
// ##############################
142172
// ######### END CUSTOM #########
143173
// ##############################

tests/compile_time.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
//! cargo run -p sqlx-exasol-cli prepare -- --features runtime-tokio --tests
44
//! ```
55
6+
use sqlx_exasol::types::ExaIter;
7+
68
extern crate sqlx_exasol as sqlx;
79

810
#[ignore]
@@ -103,7 +105,7 @@ async fn test_compile_time_queries(
103105

104106
sqlx_exasol::query!(
105107
"INSERT INTO compile_time_tests (column_i8, column_f64) VALUES(?, ?);",
106-
vec![10i8],
108+
ExaIter::new([Some(10i8)].iter()),
107109
15.3f64
108110
)
109111
.execute(&mut *conn)

0 commit comments

Comments
 (0)