Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions sqlx-core/src/any/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,27 @@ impl AnyArguments {
where
Option<i32>: Type<A::Database> + Encode<'a, A::Database>,
Option<bool>: Type<A::Database> + Encode<'a, A::Database>,
Option<i8>: 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<u8>: Type<A::Database> + Encode<'a, A::Database>,
Option<u16>: Type<A::Database> + Encode<'a, A::Database>,
Option<u32>: Type<A::Database> + Encode<'a, A::Database>,
Option<u64>: 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>,
i8: Type<A::Database> + Encode<'a, A::Database>,
i16: Type<A::Database> + Encode<'a, A::Database>,
i32: Type<A::Database> + Encode<'a, A::Database>,
i64: Type<A::Database> + Encode<'a, A::Database>,
u8: Type<A::Database> + Encode<'a, A::Database>,
u16: Type<A::Database> + Encode<'a, A::Database>,
u32: Type<A::Database> + Encode<'a, A::Database>,
u64: Type<A::Database> + Encode<'a, A::Database>,
f32: Type<A::Database> + Encode<'a, A::Database>,
f64: Type<A::Database> + Encode<'a, A::Database>,
Arc<String>: Type<A::Database> + Encode<'a, A::Database>,
Expand All @@ -64,17 +74,31 @@ impl AnyArguments {
match arg {
AnyValueKind::Null(AnyTypeInfoKind::Null) => out.add(Option::<i32>::None),
AnyValueKind::Null(AnyTypeInfoKind::Bool) => out.add(Option::<bool>::None),
AnyValueKind::Null(AnyTypeInfoKind::TinyInt) => out.add(Option::<i8>::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::UnsignedTinyInt) => out.add(Option::<u8>::None),
AnyValueKind::Null(AnyTypeInfoKind::UnsignedSmallInt) => {
out.add(Option::<u16>::None)
}
AnyValueKind::Null(AnyTypeInfoKind::UnsignedInteger) => {
out.add(Option::<u32>::None)
}
AnyValueKind::Null(AnyTypeInfoKind::UnsignedBigInt) => out.add(Option::<u64>::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::TinyInt(i) => out.add(i),
AnyValueKind::SmallInt(i) => out.add(i),
AnyValueKind::Integer(i) => out.add(i),
AnyValueKind::BigInt(i) => out.add(i),
AnyValueKind::UnsignedTinyInt(i) => out.add(i),
AnyValueKind::UnsignedSmallInt(i) => out.add(i),
AnyValueKind::UnsignedInteger(i) => out.add(i),
AnyValueKind::UnsignedBigInt(i) => out.add(i),
AnyValueKind::Real(r) => out.add(r),
AnyValueKind::Double(d) => out.add(d),
AnyValueKind::Text(t) => out.add(t),
Expand Down
10 changes: 10 additions & 0 deletions sqlx-core/src/any/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,14 @@ impl AnyRow {
AnyTypeInfo: for<'b> TryFrom<&'b <R::Database as Database>::TypeInfo, Error = Error>,
AnyColumn: for<'b> TryFrom<&'b <R::Database as Database>::Column, Error = Error>,
bool: Type<R::Database> + Decode<'a, R::Database>,
i8: Type<R::Database> + Decode<'a, R::Database>,
i16: Type<R::Database> + Decode<'a, R::Database>,
i32: Type<R::Database> + Decode<'a, R::Database>,
i64: Type<R::Database> + Decode<'a, R::Database>,
u8: Type<R::Database> + Decode<'a, R::Database>,
u16: Type<R::Database> + Decode<'a, R::Database>,
u32: Type<R::Database> + Decode<'a, R::Database>,
u64: Type<R::Database> + Decode<'a, R::Database>,
f32: Type<R::Database> + Decode<'a, R::Database>,
f64: Type<R::Database> + Decode<'a, R::Database>,
String: Type<R::Database> + Decode<'a, R::Database>,
Expand Down Expand Up @@ -120,9 +125,14 @@ impl AnyRow {
k if value.is_null() => AnyValueKind::Null(k),
AnyTypeInfoKind::Null => AnyValueKind::Null(AnyTypeInfoKind::Null),
AnyTypeInfoKind::Bool => AnyValueKind::Bool(decode(value)?),
AnyTypeInfoKind::TinyInt => AnyValueKind::TinyInt(decode(value)?),
AnyTypeInfoKind::SmallInt => AnyValueKind::SmallInt(decode(value)?),
AnyTypeInfoKind::Integer => AnyValueKind::Integer(decode(value)?),
AnyTypeInfoKind::BigInt => AnyValueKind::BigInt(decode(value)?),
AnyTypeInfoKind::UnsignedTinyInt => AnyValueKind::UnsignedTinyInt(decode(value)?),
AnyTypeInfoKind::UnsignedSmallInt => AnyValueKind::UnsignedSmallInt(decode(value)?),
AnyTypeInfoKind::UnsignedInteger => AnyValueKind::UnsignedInteger(decode(value)?),
AnyTypeInfoKind::UnsignedBigInt => AnyValueKind::UnsignedBigInt(decode(value)?),
AnyTypeInfoKind::Real => AnyValueKind::Real(decode(value)?),
AnyTypeInfoKind::Double => AnyValueKind::Double(decode(value)?),
AnyTypeInfoKind::Blob => AnyValueKind::Blob(decode::<_, Vec<u8>>(value)?.into()),
Expand Down
22 changes: 21 additions & 1 deletion sqlx-core/src/any/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ impl AnyTypeInfo {
pub enum AnyTypeInfoKind {
Null,
Bool,
TinyInt,
SmallInt,
Integer,
BigInt,
UnsignedTinyInt,
UnsignedSmallInt,
UnsignedInteger,
UnsignedBigInt,
Real,
Double,
Text,
Expand All @@ -39,9 +44,14 @@ impl TypeInfo for AnyTypeInfo {

match self.kind {
Bool => "BOOLEAN",
TinyInt => "TINYINT",
SmallInt => "SMALLINT",
Integer => "INTEGER",
BigInt => "BIGINT",
UnsignedTinyInt => "UNSIGNED TINYINT",
UnsignedSmallInt => "UNSIGNED SMALLINT",
UnsignedInteger => "UNSIGNED INTEGER",
UnsignedBigInt => "UNSIGNED BIGINT",
Real => "REAL",
Double => "DOUBLE",
Text => "TEXT",
Expand All @@ -59,6 +69,16 @@ impl Display for AnyTypeInfo {

impl AnyTypeInfoKind {
pub fn is_integer(&self) -> bool {
matches!(self, SmallInt | Integer | BigInt)
matches!(
self,
TinyInt
| SmallInt
| Integer
| BigInt
| UnsignedTinyInt
| UnsignedSmallInt
| UnsignedInteger
| UnsignedBigInt
)
}
}
28 changes: 28 additions & 0 deletions sqlx-core/src/any/types/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;

impl Type<Any> for i8 {
fn type_info() -> AnyTypeInfo {
AnyTypeInfo {
kind: AnyTypeInfoKind::TinyInt,
}
}

fn compatible(ty: &AnyTypeInfo) -> bool {
ty.kind().is_integer()
}
}

impl Encode<'_, Any> for i8 {
fn encode_by_ref(
&self,
buf: &mut <Any as Database>::ArgumentBuffer,
) -> Result<IsNull, BoxDynError> {
buf.0.push(AnyValueKind::TinyInt(*self));
Ok(IsNull::No)
}
}

impl<'r> Decode<'r, Any> for i8 {
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
value.kind.try_integer()
}
}

impl Type<Any> for i16 {
fn type_info() -> AnyTypeInfo {
AnyTypeInfo {
Expand Down
12 changes: 12 additions & 0 deletions sqlx-core/src/any/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
//! | Rust type | SQL type(s) |
//! |---------------------------------------|------------------------------------------------------|
//! | `bool` | BOOLEAN |
//! | `i8` | TINYINT |
//! | `i16` | SMALLINT |
//! | `i32` | INT |
//! | `i64` | BIGINT |
//! | `u8` | UNSIGNED TINYINT |
//! | `u16` | UNSIGNED SMALLINT |
//! | `u32` | UNSIGNED INT |
//! | `u64` | UNSIGNED BIGINT |
//! | `f32` | FLOAT |
//! | `f64` | DOUBLE |
//! | `&str`, [`String`] | VARCHAR, CHAR, TEXT |
Expand All @@ -22,6 +27,7 @@ mod bool;
mod float;
mod int;
mod str;
mod uint;

#[test]
fn test_type_impls() {
Expand All @@ -40,10 +46,16 @@ fn test_type_impls() {

has_type::<bool>();

has_type::<i8>();
has_type::<i16>();
has_type::<i32>();
has_type::<i64>();

has_type::<u8>();
has_type::<u16>();
has_type::<u32>();
has_type::<u64>();

has_type::<f32>();
has_type::<f64>();

Expand Down
118 changes: 118 additions & 0 deletions sqlx-core/src/any/types/uint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use crate::any::{Any, AnyTypeInfo, AnyTypeInfoKind, AnyValueKind};
use crate::database::Database;
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;

impl Type<Any> for u8 {
fn type_info() -> AnyTypeInfo {
AnyTypeInfo {
kind: AnyTypeInfoKind::UnsignedTinyInt,
}
}

fn compatible(ty: &AnyTypeInfo) -> bool {
ty.kind().is_integer()
}
}

impl Encode<'_, Any> for u8 {
fn encode_by_ref(
&self,
buf: &mut <Any as Database>::ArgumentBuffer,
) -> Result<IsNull, BoxDynError> {
buf.0.push(AnyValueKind::UnsignedTinyInt(*self));
Ok(IsNull::No)
}
}

impl<'r> Decode<'r, Any> for u8 {
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
value.kind.try_integer()
}
}

impl Type<Any> for u16 {
fn type_info() -> AnyTypeInfo {
AnyTypeInfo {
kind: AnyTypeInfoKind::UnsignedTinyInt,
}
}

fn compatible(ty: &AnyTypeInfo) -> bool {
ty.kind().is_integer()
}
}

impl Encode<'_, Any> for u16 {
fn encode_by_ref(
&self,
buf: &mut <Any as Database>::ArgumentBuffer,
) -> Result<IsNull, BoxDynError> {
buf.0.push(AnyValueKind::UnsignedSmallInt(*self));
Ok(IsNull::No)
}
}

impl<'r> Decode<'r, Any> for u16 {
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
value.kind.try_integer()
}
}

impl Type<Any> for u32 {
fn type_info() -> AnyTypeInfo {
AnyTypeInfo {
kind: AnyTypeInfoKind::UnsignedInteger,
}
}

fn compatible(ty: &AnyTypeInfo) -> bool {
ty.kind().is_integer()
}
}

impl Encode<'_, Any> for u32 {
fn encode_by_ref(
&self,
buf: &mut <Any as Database>::ArgumentBuffer,
) -> Result<IsNull, BoxDynError> {
buf.0.push(AnyValueKind::UnsignedInteger(*self));
Ok(IsNull::No)
}
}

impl<'r> Decode<'r, Any> for u32 {
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
value.kind.try_integer()
}
}

impl Type<Any> for u64 {
fn type_info() -> AnyTypeInfo {
AnyTypeInfo {
kind: AnyTypeInfoKind::UnsignedBigInt,
}
}

fn compatible(ty: &AnyTypeInfo) -> bool {
ty.kind().is_integer()
}
}

impl Encode<'_, Any> for u64 {
fn encode_by_ref(
&self,
buf: &mut <Any as Database>::ArgumentBuffer,
) -> Result<IsNull, BoxDynError> {
buf.0.push(AnyValueKind::UnsignedBigInt(*self));
Ok(IsNull::No)
}
}

impl<'r> Decode<'r, Any> for u64 {
fn decode(value: <Any as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
value.kind.try_integer()
}
}
30 changes: 29 additions & 1 deletion sqlx-core/src/any/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ use std::sync::Arc;
pub enum AnyValueKind {
Null(AnyTypeInfoKind),
Bool(bool),
TinyInt(i8),
SmallInt(i16),
Integer(i32),
BigInt(i64),
UnsignedTinyInt(u8),
UnsignedSmallInt(u16),
UnsignedInteger(u32),
UnsignedBigInt(u64),
Real(f32),
Double(f64),
Text(Arc<String>),
Expand All @@ -27,9 +32,14 @@ impl AnyValueKind {
kind: match self {
AnyValueKind::Null(_) => AnyTypeInfoKind::Null,
AnyValueKind::Bool(_) => AnyTypeInfoKind::Bool,
AnyValueKind::TinyInt(_) => AnyTypeInfoKind::TinyInt,
AnyValueKind::SmallInt(_) => AnyTypeInfoKind::SmallInt,
AnyValueKind::Integer(_) => AnyTypeInfoKind::Integer,
AnyValueKind::BigInt(_) => AnyTypeInfoKind::BigInt,
AnyValueKind::UnsignedTinyInt(_) => AnyTypeInfoKind::UnsignedTinyInt,
AnyValueKind::UnsignedSmallInt(_) => AnyTypeInfoKind::UnsignedSmallInt,
AnyValueKind::UnsignedInteger(_) => AnyTypeInfoKind::UnsignedInteger,
AnyValueKind::UnsignedBigInt(_) => AnyTypeInfoKind::UnsignedBigInt,
AnyValueKind::Real(_) => AnyTypeInfoKind::Real,
AnyValueKind::Double(_) => AnyTypeInfoKind::Double,
AnyValueKind::Text(_) => AnyTypeInfoKind::Text,
Expand All @@ -45,15 +55,33 @@ impl AnyValueKind {

pub(in crate::any) fn try_integer<T>(&self) -> Result<T, BoxDynError>
where
T: Type<Any> + TryFrom<i16> + TryFrom<i32> + TryFrom<i64>,
T: Type<Any>
+ TryFrom<i8>
+ TryFrom<i16>
+ TryFrom<i32>
+ TryFrom<i64>
+ TryFrom<u8>
+ TryFrom<u16>
+ TryFrom<u32>
+ TryFrom<u64>,
BoxDynError: From<<T as TryFrom<i8>>::Error>,
BoxDynError: From<<T as TryFrom<i16>>::Error>,
BoxDynError: From<<T as TryFrom<i32>>::Error>,
BoxDynError: From<<T as TryFrom<i64>>::Error>,
BoxDynError: From<<T as TryFrom<u8>>::Error>,
BoxDynError: From<<T as TryFrom<u16>>::Error>,
BoxDynError: From<<T as TryFrom<u32>>::Error>,
BoxDynError: From<<T as TryFrom<u64>>::Error>,
{
Ok(match self {
AnyValueKind::TinyInt(i) => (*i).try_into()?,
AnyValueKind::SmallInt(i) => (*i).try_into()?,
AnyValueKind::Integer(i) => (*i).try_into()?,
AnyValueKind::BigInt(i) => (*i).try_into()?,
AnyValueKind::UnsignedTinyInt(i) => (*i).try_into()?,
AnyValueKind::UnsignedSmallInt(i) => (*i).try_into()?,
AnyValueKind::UnsignedInteger(i) => (*i).try_into()?,
AnyValueKind::UnsignedBigInt(i) => (*i).try_into()?,
_ => return self.unexpected(),
})
}
Expand Down
Loading
Loading