mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 06:24:16 +00:00
track the kind of null arguments in order to provide the appropriate type when converting them
This commit is contained in:
parent
1e1697f655
commit
93f3d79f83
5 changed files with 30 additions and 14 deletions
|
@ -1,5 +1,5 @@
|
|||
use crate::any::value::AnyValueKind;
|
||||
use crate::any::Any;
|
||||
use crate::any::{Any, AnyTypeInfoKind};
|
||||
use crate::arguments::Arguments;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
|
@ -46,6 +46,14 @@ impl<'q> AnyArguments<'q> {
|
|||
where
|
||||
'q: 'a,
|
||||
Option<i32>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<bool>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<i16>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<i32>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<i64>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<f32>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<f64>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<String>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
Option<Vec<u8>>: Type<A::Database> + Encode<'a, A::Database>,
|
||||
bool: Type<A::Database> + Encode<'a, A::Database>,
|
||||
i16: Type<A::Database> + Encode<'a, A::Database>,
|
||||
i32: Type<A::Database> + Encode<'a, A::Database>,
|
||||
|
@ -59,7 +67,15 @@ impl<'q> AnyArguments<'q> {
|
|||
|
||||
for arg in &self.values.0 {
|
||||
match arg {
|
||||
AnyValueKind::Null => out.add(Option::<i32>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Null) => out.add(Option::<i32>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Bool) => out.add(Option::<bool>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::SmallInt) => out.add(Option::<i16>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Integer) => out.add(Option::<i32>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::BigInt) => out.add(Option::<i64>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Real) => out.add(Option::<f64>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Double) => out.add(Option::<f32>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Text) => out.add(Option::<String>::None),
|
||||
AnyValueKind::Null(AnyTypeInfoKind::Blob) => out.add(Option::<Vec<u8>>::None),
|
||||
AnyValueKind::Bool(b) => out.add(b),
|
||||
AnyValueKind::SmallInt(i) => out.add(i),
|
||||
AnyValueKind::Integer(i) => out.add(i),
|
||||
|
@ -70,7 +86,6 @@ impl<'q> AnyArguments<'q> {
|
|||
AnyValueKind::Blob(b) => out.add(&**b),
|
||||
}?
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ pub use transaction::AnyTransactionManager;
|
|||
pub use type_info::{AnyTypeInfo, AnyTypeInfoKind};
|
||||
pub use value::{AnyValue, AnyValueRef};
|
||||
|
||||
use crate::types::Type;
|
||||
#[doc(hidden)]
|
||||
pub use value::AnyValueKind;
|
||||
|
||||
|
@ -65,7 +66,7 @@ impl_column_index_for_statement!(AnyStatement);
|
|||
// required because some databases have a different handling of NULL
|
||||
impl<'q, T> Encode<'q, Any> for Option<T>
|
||||
where
|
||||
T: Encode<'q, Any> + 'q,
|
||||
T: Encode<'q, Any> + 'q + Type<Any>,
|
||||
{
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
|
@ -74,7 +75,7 @@ where
|
|||
if let Some(value) = self {
|
||||
value.encode_by_ref(buf)
|
||||
} else {
|
||||
buf.0.push(AnyValueKind::Null);
|
||||
buf.0.push(AnyValueKind::Null(T::type_info().kind));
|
||||
Ok(crate::encode::IsNull::Yes)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,8 +117,8 @@ impl AnyRow {
|
|||
})?;
|
||||
|
||||
let value_kind = match type_info.kind {
|
||||
_ if value.is_null() => AnyValueKind::Null,
|
||||
AnyTypeInfoKind::Null => AnyValueKind::Null,
|
||||
k if value.is_null() => AnyValueKind::Null(k),
|
||||
AnyTypeInfoKind::Null => AnyValueKind::Null(AnyTypeInfoKind::Null),
|
||||
AnyTypeInfoKind::Bool => AnyValueKind::Bool(decode(value)?),
|
||||
AnyTypeInfoKind::SmallInt => AnyValueKind::SmallInt(decode(value)?),
|
||||
AnyTypeInfoKind::Integer => AnyValueKind::Integer(decode(value)?),
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::value::{Value, ValueRef};
|
|||
#[derive(Clone, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum AnyValueKind<'a> {
|
||||
Null,
|
||||
Null(AnyTypeInfoKind),
|
||||
Bool(bool),
|
||||
SmallInt(i16),
|
||||
Integer(i32),
|
||||
|
@ -24,7 +24,7 @@ impl AnyValueKind<'_> {
|
|||
fn type_info(&self) -> AnyTypeInfo {
|
||||
AnyTypeInfo {
|
||||
kind: match self {
|
||||
AnyValueKind::Null => AnyTypeInfoKind::Null,
|
||||
AnyValueKind::Null(_) => AnyTypeInfoKind::Null,
|
||||
AnyValueKind::Bool(_) => AnyTypeInfoKind::Bool,
|
||||
AnyValueKind::SmallInt(_) => AnyTypeInfoKind::SmallInt,
|
||||
AnyValueKind::Integer(_) => AnyTypeInfoKind::Integer,
|
||||
|
@ -74,7 +74,7 @@ impl Value for AnyValue {
|
|||
fn as_ref(&self) -> <Self::Database as Database>::ValueRef<'_> {
|
||||
AnyValueRef {
|
||||
kind: match &self.kind {
|
||||
AnyValueKind::Null => AnyValueKind::Null,
|
||||
AnyValueKind::Null(k) => AnyValueKind::Null(*k),
|
||||
AnyValueKind::Bool(b) => AnyValueKind::Bool(*b),
|
||||
AnyValueKind::SmallInt(i) => AnyValueKind::SmallInt(*i),
|
||||
AnyValueKind::Integer(i) => AnyValueKind::Integer(*i),
|
||||
|
@ -92,7 +92,7 @@ impl Value for AnyValue {
|
|||
}
|
||||
|
||||
fn is_null(&self) -> bool {
|
||||
matches!(self.kind, AnyValueKind::Null)
|
||||
matches!(self.kind, AnyValueKind::Null(_))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ impl<'a> ValueRef<'a> for AnyValueRef<'a> {
|
|||
fn to_owned(&self) -> <Self::Database as Database>::Value {
|
||||
AnyValue {
|
||||
kind: match &self.kind {
|
||||
AnyValueKind::Null => AnyValueKind::Null,
|
||||
AnyValueKind::Null(k) => AnyValueKind::Null(*k),
|
||||
AnyValueKind::Bool(b) => AnyValueKind::Bool(*b),
|
||||
AnyValueKind::SmallInt(i) => AnyValueKind::SmallInt(*i),
|
||||
AnyValueKind::Integer(i) => AnyValueKind::Integer(*i),
|
||||
|
@ -120,6 +120,6 @@ impl<'a> ValueRef<'a> for AnyValueRef<'a> {
|
|||
}
|
||||
|
||||
fn is_null(&self) -> bool {
|
||||
matches!(self.kind, AnyValueKind::Null)
|
||||
matches!(self.kind, AnyValueKind::Null(_))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ fn map_arguments(args: AnyArguments<'_>) -> SqliteArguments<'_> {
|
|||
.0
|
||||
.into_iter()
|
||||
.map(|val| match val {
|
||||
AnyValueKind::Null => SqliteArgumentValue::Null,
|
||||
AnyValueKind::Null(_) => SqliteArgumentValue::Null,
|
||||
AnyValueKind::Bool(b) => SqliteArgumentValue::Int(b as i32),
|
||||
AnyValueKind::SmallInt(i) => SqliteArgumentValue::Int(i as i32),
|
||||
AnyValueKind::Integer(i) => SqliteArgumentValue::Int(i),
|
||||
|
|
Loading…
Reference in a new issue