Skip to content

Commit a69d4c8

Browse files
committed
Add the ExaHasArrayType marker trait
The trait limits encoding arrays to one dimensional arrays. Also renamed the types::iter module to types::array.
1 parent e43258a commit a69d4c8

21 files changed

Lines changed: 145 additions & 79 deletions
Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ use sqlx_core::{
99

1010
use crate::{arguments::ExaBuffer, Exasol};
1111

12+
/// Marker trait that limits arrays encoding to one dimensioanl arrays.
13+
///
14+
/// Implementing it for some type `T` enables relevant [`Type`], [`Encode`] and [`Decode`] impls for
15+
/// [`Vec<T>`], [`&T`] (slices), [`[T;N]`] (arrays), [`ExaIter`], etc.
16+
pub trait ExaHasArrayType: Type<Exasol> {}
17+
18+
impl<T> ExaHasArrayType for &T where T: ExaHasArrayType {}
19+
1220
/// Adapter allowing any iterator of encodable values to be treated and passed as a one dimensional
1321
/// parameter array for a column to Exasol in a single query invocation. Multi dimensional arrays
1422
/// are not supported. The adapter is needed because [`Encode`] is still a foreign trait and thus
@@ -31,53 +39,26 @@ use crate::{arguments::ExaBuffer, Exasol};
3139
#[repr(transparent)]
3240
pub struct ExaIter<I, T> {
3341
into_iter: I,
34-
data_lifetime: PhantomData<fn() -> T>,
42+
_marker: PhantomData<fn() -> T>,
3543
}
3644

3745
impl<I, T> ExaIter<I, T>
3846
where
3947
I: IntoIterator<Item = T> + Clone,
40-
T: for<'q> Encode<'q, Exasol> + Type<Exasol> + Copy,
48+
T: for<'q> Encode<'q, Exasol> + ExaHasArrayType + Copy,
4149
{
4250
pub fn new(into_iter: I) -> Self {
4351
Self {
4452
into_iter,
45-
data_lifetime: PhantomData,
53+
_marker: PhantomData,
4654
}
4755
}
4856
}
4957

5058
impl<I, T> Type<Exasol> for ExaIter<I, T>
5159
where
5260
I: IntoIterator<Item = T> + Clone,
53-
T: Type<Exasol> + Copy,
54-
{
55-
fn type_info() -> <Exasol as Database>::TypeInfo {
56-
T::type_info()
57-
}
58-
}
59-
60-
impl<T> Type<Exasol> for [T]
61-
where
62-
T: Type<Exasol>,
63-
{
64-
fn type_info() -> <Exasol as Database>::TypeInfo {
65-
T::type_info()
66-
}
67-
}
68-
69-
impl<T, const N: usize> Type<Exasol> for [T; N]
70-
where
71-
T: Type<Exasol>,
72-
{
73-
fn type_info() -> <Exasol as Database>::TypeInfo {
74-
T::type_info()
75-
}
76-
}
77-
78-
impl<T> Type<Exasol> for Vec<T>
79-
where
80-
T: Type<Exasol>,
61+
T: ExaHasArrayType + Copy,
8162
{
8263
fn type_info() -> <Exasol as Database>::TypeInfo {
8364
T::type_info()
@@ -104,11 +85,27 @@ where
10485
}
10586
}
10687

88+
macro_rules! forward_arr_type_impl {
89+
($for_type:ty, $($generics:tt)*) => {
90+
impl<T, $($generics)*> Type<Exasol> for $for_type
91+
where
92+
T: ExaHasArrayType,
93+
{
94+
fn type_info() -> <Exasol as Database>::TypeInfo {
95+
T::type_info()
96+
}
97+
}
98+
};
99+
($for_type:ty) => {
100+
forward_arr_type_impl!($for_type,);
101+
}
102+
}
103+
107104
macro_rules! forward_arr_encode_impl {
108105
($for_type:ty, $($generics:tt)*) => {
109106
impl<T, $($generics)*> Encode<'_, Exasol> for $for_type
110107
where
111-
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
108+
for<'q> T: Encode<'q, Exasol> + ExaHasArrayType,
112109
{
113110
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
114111
ExaIter::new(AsRef::<[T]>::as_ref(&self)).encode_by_ref(buf)
@@ -124,6 +121,10 @@ macro_rules! forward_arr_encode_impl {
124121
}
125122
}
126123

124+
forward_arr_type_impl!([T]);
125+
forward_arr_type_impl!([T; N], const N: usize);
126+
forward_arr_type_impl!(Vec<T>);
127+
127128
forward_arr_encode_impl!(&[T]);
128129
forward_arr_encode_impl!([T; N], const N: usize);
129130
forward_arr_encode_impl!(Vec<T>);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
arguments::ExaBuffer,
1212
database::Exasol,
1313
type_info::{Decimal, ExaDataType, ExaTypeInfo},
14+
types::ExaHasArrayType,
1415
value::ExaValueRef,
1516
};
1617

@@ -25,6 +26,8 @@ impl Type<Exasol> for BigDecimal {
2526
}
2627
}
2728

29+
impl ExaHasArrayType for BigDecimal {}
30+
2831
impl Encode<'_, Exasol> for BigDecimal {
2932
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
3033
buf.append(format_args!("{self}"))?;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
arguments::ExaBuffer,
1111
database::Exasol,
1212
type_info::{ExaDataType, ExaTypeInfo},
13+
types::ExaHasArrayType,
1314
value::ExaValueRef,
1415
};
1516

@@ -19,6 +20,8 @@ impl Type<Exasol> for bool {
1920
}
2021
}
2122

23+
impl ExaHasArrayType for bool {}
24+
2225
impl Encode<'_, Exasol> for bool {
2326
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
2427
buf.append(self)?;

sqlx-exasol-impl/src/types/chrono/date.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
arguments::ExaBuffer,
1212
database::Exasol,
1313
type_info::{ExaDataType, ExaTypeInfo},
14+
types::ExaHasArrayType,
1415
value::ExaValueRef,
1516
};
1617

@@ -20,6 +21,8 @@ impl Type<Exasol> for NaiveDate {
2021
}
2122
}
2223

24+
impl ExaHasArrayType for NaiveDate {}
25+
2326
impl Encode<'_, Exasol> for NaiveDate {
2427
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
2528
buf.append(self)?;

sqlx-exasol-impl/src/types/chrono/datetime.rs

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
arguments::ExaBuffer,
1212
database::Exasol,
1313
type_info::{ExaDataType, ExaTypeInfo},
14+
types::ExaHasArrayType,
1415
value::ExaValueRef,
1516
};
1617

@@ -22,6 +23,22 @@ impl Type<Exasol> for NaiveDateTime {
2223
}
2324
}
2425

26+
impl Type<Exasol> for DateTime<Utc> {
27+
fn type_info() -> ExaTypeInfo {
28+
ExaDataType::Timestamp.into()
29+
}
30+
}
31+
32+
impl Type<Exasol> for DateTime<Local> {
33+
fn type_info() -> ExaTypeInfo {
34+
ExaDataType::TimestampWithLocalTimeZone.into()
35+
}
36+
}
37+
38+
impl ExaHasArrayType for NaiveDateTime {}
39+
impl ExaHasArrayType for DateTime<Utc> {}
40+
impl ExaHasArrayType for DateTime<Local> {}
41+
2542
impl Encode<'_, Exasol> for NaiveDateTime {
2643
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
2744
buf.append(format_args!("{}", self.format(TIMESTAMP_FMT)))?;
@@ -37,21 +54,6 @@ impl Encode<'_, Exasol> for NaiveDateTime {
3754
}
3855
}
3956

40-
impl Decode<'_, Exasol> for NaiveDateTime {
41-
fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
42-
let input = <&str>::deserialize(value.value).map_err(Box::new)?;
43-
Self::parse_from_str(input, TIMESTAMP_FMT)
44-
.map_err(Box::new)
45-
.map_err(From::from)
46-
}
47-
}
48-
49-
impl Type<Exasol> for DateTime<Utc> {
50-
fn type_info() -> ExaTypeInfo {
51-
ExaDataType::Timestamp.into()
52-
}
53-
}
54-
5557
impl Encode<'_, Exasol> for DateTime<Utc> {
5658
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
5759
Encode::<Exasol>::encode(self.naive_utc(), buf)
@@ -66,19 +68,6 @@ impl Encode<'_, Exasol> for DateTime<Utc> {
6668
}
6769
}
6870

69-
impl<'r> Decode<'r, Exasol> for DateTime<Utc> {
70-
fn decode(value: ExaValueRef<'r>) -> Result<Self, BoxDynError> {
71-
let naive: NaiveDateTime = Decode::<Exasol>::decode(value)?;
72-
Ok(DateTime::from_naive_utc_and_offset(naive, Utc))
73-
}
74-
}
75-
76-
impl Type<Exasol> for DateTime<Local> {
77-
fn type_info() -> ExaTypeInfo {
78-
ExaDataType::TimestampWithLocalTimeZone.into()
79-
}
80-
}
81-
8271
impl Encode<'_, Exasol> for DateTime<Local> {
8372
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
8473
Encode::<Exasol>::encode(self.naive_local(), buf)
@@ -93,6 +82,22 @@ impl Encode<'_, Exasol> for DateTime<Local> {
9382
}
9483
}
9584

85+
impl Decode<'_, Exasol> for NaiveDateTime {
86+
fn decode(value: ExaValueRef<'_>) -> Result<Self, BoxDynError> {
87+
let input = <&str>::deserialize(value.value).map_err(Box::new)?;
88+
Self::parse_from_str(input, TIMESTAMP_FMT)
89+
.map_err(Box::new)
90+
.map_err(From::from)
91+
}
92+
}
93+
94+
impl<'r> Decode<'r, Exasol> for DateTime<Utc> {
95+
fn decode(value: ExaValueRef<'r>) -> Result<Self, BoxDynError> {
96+
let naive: NaiveDateTime = Decode::<Exasol>::decode(value)?;
97+
Ok(DateTime::from_naive_utc_and_offset(naive, Utc))
98+
}
99+
}
100+
96101
impl<'r> Decode<'r, Exasol> for DateTime<Local> {
97102
fn decode(value: ExaValueRef<'r>) -> Result<Self, BoxDynError> {
98103
let naive: NaiveDateTime = Decode::<Exasol>::decode(value)?;

sqlx-exasol-impl/src/types/chrono/timedelta.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
arguments::ExaBuffer,
1212
database::Exasol,
1313
type_info::{ExaDataType, ExaTypeInfo},
14+
types::ExaHasArrayType,
1415
value::ExaValueRef,
1516
};
1617

@@ -24,6 +25,8 @@ impl Type<Exasol> for TimeDelta {
2425
}
2526
}
2627

28+
impl ExaHasArrayType for TimeDelta {}
29+
2730
impl Encode<'_, Exasol> for TimeDelta {
2831
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
2932
buf.append(format_args!(

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::{
1111
arguments::ExaBuffer,
1212
database::Exasol,
1313
type_info::{ExaDataType, ExaTypeInfo},
14+
types::ExaHasArrayType,
1415
value::ExaValueRef,
1516
};
1617

@@ -20,6 +21,8 @@ impl Type<Exasol> for f64 {
2021
}
2122
}
2223

24+
impl ExaHasArrayType for f64 {}
25+
2326
impl Encode<'_, Exasol> for f64 {
2427
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
2528
// NaN is treated as NULL by Exasol.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::{
1616
arguments::ExaBuffer,
1717
database::Exasol,
1818
type_info::{ExaDataType, ExaTypeInfo},
19+
types::ExaHasArrayType,
1920
value::ExaValueRef,
2021
};
2122

@@ -28,6 +29,8 @@ where
2829
}
2930
}
3031

32+
impl<T> ExaHasArrayType for Geometry<T> where T: CoordNum {}
33+
3134
impl<T> Encode<'_, Exasol> for Geometry<T>
3235
where
3336
T: CoordNum + Display,

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
arguments::ExaBuffer,
1111
database::Exasol,
1212
type_info::{ExaDataType, ExaTypeInfo},
13+
types::ExaHasArrayType,
1314
value::ExaValueRef,
1415
};
1516

@@ -32,6 +33,8 @@ impl Type<Exasol> for HashType {
3233
}
3334
}
3435

36+
impl ExaHasArrayType for HashType {}
37+
3538
impl Encode<'_, Exasol> for HashType {
3639
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
3740
<&str as Encode<Exasol>>::encode_by_ref(&self.0.as_str(), buf)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
arguments::ExaBuffer,
1414
database::Exasol,
1515
type_info::{Decimal, ExaDataType, ExaTypeInfo},
16+
types::ExaHasArrayType,
1617
value::ExaValueRef,
1718
};
1819

@@ -60,6 +61,11 @@ impl Type<Exasol> for i64 {
6061
}
6162
}
6263

64+
impl ExaHasArrayType for i8 {}
65+
impl ExaHasArrayType for i16 {}
66+
impl ExaHasArrayType for i32 {}
67+
impl ExaHasArrayType for i64 {}
68+
6369
impl Encode<'_, Exasol> for i8 {
6470
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
6571
buf.append(self)?;

0 commit comments

Comments
 (0)