From f348a8f2acdea910e14e4820115f12cd09801172 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Thu, 18 Feb 2021 21:43:08 -0800 Subject: [PATCH] feat(mysql): expand MySqlTypeInfo, MySqlTypeId --- sqlx-mysql/src/type_id.rs | 29 ++++++++++++++++++++++++---- sqlx-mysql/src/type_info.rs | 38 +++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/sqlx-mysql/src/type_id.rs b/sqlx-mysql/src/type_id.rs index fe68bca6..4b3b18d9 100644 --- a/sqlx-mysql/src/type_id.rs +++ b/sqlx-mysql/src/type_id.rs @@ -1,5 +1,7 @@ +use crate::protocol::{ColumnDefinition, ColumnFlags}; + /// A unique identifier for a MySQL data type. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr( any(feature = "offline", feature = "serde"), derive(serde::Serialize, serde::Deserialize) @@ -9,18 +11,32 @@ pub struct MySqlTypeId(u8, u8); // a flag byte which has the highest bit set to indicate the type is unsigned const UNSIGNED: u8 = 0x80; +impl MySqlTypeId { + pub(crate) const fn new(def: &ColumnDefinition) -> Self { + Self(def.ty, if def.flags.contains(ColumnFlags::UNSIGNED) { UNSIGNED } else { 0 }) + } + + pub(crate) const fn ty(self) -> u8 { + self.0 + } + + pub(crate) const fn flags(self) -> u8 { + self.1 + } +} + impl MySqlTypeId { /// Returns `true` if this is the `NULL` type. /// /// For MySQL, this occurs in types from parameters or when `NULL` is /// directly used in an expression by itself, such as `SELECT NULL`. /// - pub const fn is_null(&self) -> bool { + pub(crate) const fn is_null(&self) -> bool { matches!(*self, MySqlTypeId::NULL) } /// Returns `true` if this is an integer data type. - pub const fn is_integer(&self) -> bool { + pub(crate) const fn is_integer(&self) -> bool { matches!( *self, MySqlTypeId::TINYINT @@ -36,8 +52,13 @@ impl MySqlTypeId { ) } + /// Returns `true` if this is an unsigned data type. + pub(crate) const fn is_unsigned(&self) -> bool { + self.1 == UNSIGNED + } + /// Returns the name for this MySQL data type. - pub const fn name(&self) -> &'static str { + pub(crate) const fn name(&self) -> &'static str { match *self { Self::NULL => "NULL", diff --git a/sqlx-mysql/src/type_info.rs b/sqlx-mysql/src/type_info.rs index 5906b7a4..fba4bf89 100644 --- a/sqlx-mysql/src/type_info.rs +++ b/sqlx-mysql/src/type_info.rs @@ -1,4 +1,7 @@ -use crate::MySqlTypeId; +use sqlx_core::TypeInfo; + +use crate::protocol::ColumnDefinition; +use crate::{MySql, MySqlTypeId}; /// Provides information about a MySQL type. #[derive(Debug, Clone)] @@ -8,11 +11,16 @@ use crate::MySqlTypeId; )] pub struct MySqlTypeInfo { id: MySqlTypeId, - flags: u16, - charset: u8, + charset: u16, // [max_size] for integer types, this is (M) in BIT(M) or TINYINT(M) - max_size: u8, + max_size: u32, +} + +impl MySqlTypeInfo { + pub(crate) const fn new(def: &ColumnDefinition) -> Self { + Self { id: MySqlTypeId::new(def), charset: def.charset, max_size: def.max_size } + } } impl MySqlTypeInfo { @@ -20,18 +28,20 @@ impl MySqlTypeInfo { pub const fn id(&self) -> MySqlTypeId { self.id } +} - /// Returns `true` if this is the `NULL` type. - /// - /// For MySQL, this occurs in types from parameters or when `NULL` is - /// directly used in an expression by itself, such as `SELECT NULL`. - /// - pub const fn is_null(&self) -> bool { - self.id().is_null() +impl TypeInfo for MySqlTypeInfo { + type Database = MySql; + + fn id(&self) -> MySqlTypeId { + self.id() } - /// Returns the name for this MySQL data type. - pub const fn name(&self) -> &'static str { - self.id().name() + fn is_unknown(&self) -> bool { + self.id.is_null() + } + + fn name(&self) -> &str { + self.id.name() } }