From 0708b3a873356364df1b586af1e557b850762f2e Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Tue, 23 Feb 2021 02:05:23 -0800 Subject: [PATCH] feat(mysql): detect BOOLEAN, SET, and ENUM with MySqlTypeInfo --- sqlx-mysql/src/type_id.rs | 8 +++++++- sqlx-mysql/src/type_info.rs | 38 +++++++++++++++++++++++++++++++------ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/sqlx-mysql/src/type_id.rs b/sqlx-mysql/src/type_id.rs index 93f41100..0e83701a 100644 --- a/sqlx-mysql/src/type_id.rs +++ b/sqlx-mysql/src/type_id.rs @@ -33,7 +33,7 @@ impl MySqlTypeId { /// directly used in an expression by itself, such as `SELECT NULL`. /// pub(crate) const fn is_null(&self) -> bool { - matches!(*self, MySqlTypeId::NULL) + matches!(*self, Self::NULL) } /// Returns `true` if this is an integer data type. @@ -70,6 +70,7 @@ impl MySqlTypeId { /// If the display width is 1 ( `TINYINT(1)` ), maps to `bool`. Otherwise, /// maps to `i8`. /// + #[doc(alias = "BOOLEAN")] pub const TINYINT: Self = Self(1, 0); /// An unsigned 8-bit integer. @@ -183,7 +184,12 @@ impl MySqlTypeId { /// level, they are identical. At the column, the presence of a binary (`_bin`) /// collation determines if the type stores binary data. /// + /// Additionally, the type identifier for `ENUM` and `SET` is also the + /// same as `CHAR`. + /// #[doc(alias = "BINARY")] + #[doc(alias = "ENUM")] + #[doc(alias = "SET")] pub const CHAR: Self = Self(254, 0); /// A variable-length string. diff --git a/sqlx-mysql/src/type_info.rs b/sqlx-mysql/src/type_info.rs index aaa96639..046a439f 100644 --- a/sqlx-mysql/src/type_info.rs +++ b/sqlx-mysql/src/type_info.rs @@ -13,7 +13,7 @@ use crate::{MySql, MySqlTypeId}; pub struct MySqlTypeInfo { id: MySqlTypeId, charset: u16, - has_binary_collation: bool, + flags: ColumnFlags, // [max_size] for integer types, this is (M) in BIT(M) or TINYINT(M) max_size: u32, @@ -25,7 +25,7 @@ impl MySqlTypeInfo { id: MySqlTypeId::new(def), charset: def.charset, max_size: def.max_size, - has_binary_collation: def.flags.contains(ColumnFlags::BINARY_COLLATION), + flags: def.flags, } } } @@ -40,7 +40,26 @@ impl MySqlTypeInfo { /// Returns `true` if this type has a binary collation. #[must_use] pub const fn has_binary_collation(&self) -> bool { - self.has_binary_collation + self.flags.contains(ColumnFlags::BINARY_COLLATION) + } + + /// Returns `true` if this type is `BOOLEAN`. + #[must_use] + pub const fn is_boolean(&self) -> bool { + matches!(self.id(), MySqlTypeId::TINYINT | MySqlTypeId::TINYINT_UNSIGNED) + && self.max_size == 1 + } + + /// Returns `true` if this type is an `ENUM`. + #[must_use] + pub const fn is_enum(&self) -> bool { + self.flags.contains(ColumnFlags::ENUM) + } + + /// Returns `true` if this type is a `SET`. + #[must_use] + pub const fn is_set(&self) -> bool { + self.flags.contains(ColumnFlags::SET) } /// Returns the name for this MySQL type. @@ -49,6 +68,9 @@ impl MySqlTypeInfo { match self.id { MySqlTypeId::NULL => "NULL", + // BOOLEAN has the same type ID as TINYINT + _ if self.is_boolean() => "BOOLEAN", + MySqlTypeId::TINYINT => "TINYINT", MySqlTypeId::SMALLINT => "SMALLINT", MySqlTypeId::MEDIUMINT => "MEDIUMINT", @@ -64,9 +86,13 @@ impl MySqlTypeInfo { MySqlTypeId::FLOAT => "FLOAT", MySqlTypeId::DOUBLE => "DOUBLE", - // note: VARBINARY, BINARY, and BLOB have the same type IDs as - // VARCHAR, CHAR, and TEXT; the only difference is the - // presence of a binary collation + // ENUM, and SET have the same type ID as CHAR + _ if self.is_enum() => "ENUM", + _ if self.is_set() => "SET", + + // VARBINARY, BINARY, and BLOB have the same type IDs as + // VARCHAR, CHAR, and TEXT; the only difference is the + // presence of a binary collation MySqlTypeId::VARCHAR if self.has_binary_collation() => "VARBINARY", MySqlTypeId::CHAR if self.has_binary_collation() => "BINARY", MySqlTypeId::TEXT if self.has_binary_collation() => "BLOB",