diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eb87739..7e2125f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Breaking Changes * Rework SQLite type mapping https://github.com/SeaQL/sea-query/pull/735 +* MySQL blob types moved to `sea_query::extension::mysql::MySqlType` +```rust +assert_eq!( + Table::create() + .table(BinaryType::Table) + .col(ColumnDef::new(BinaryType::BinaryLen).binary_len(32)) + .col(ColumnDef::new(BinaryType::Binary).binary()) + .col(ColumnDef::new(BinaryType::Blob).custom(MySqlType::Blob)) + .col(ColumnDef::new(BinaryType::TinyBlob).custom(MySqlType::TinyBlob)) + .col(ColumnDef::new(BinaryType::MediumBlob).custom(MySqlType::MediumBlob)) + .col(ColumnDef::new(BinaryType::LongBlob).custom(MySqlType::LongBlob)) + .to_string(MysqlQueryBuilder), + [ + "CREATE TABLE `binary_type` (", + "`binlen` binary(32),", + "`bin` binary(1),", + "`b` blob,", + "`tb` tinyblob,", + "`mb` mediumblob,", + "`lb` longblob", + ")", + ] + .join(" ") +); +``` ## 0.30.8 - Pending diff --git a/src/backend/mysql/table.rs b/src/backend/mysql/table.rs index 881922f4..ceec823c 100644 --- a/src/backend/mysql/table.rs +++ b/src/backend/mysql/table.rs @@ -34,8 +34,9 @@ impl TableBuilder for MysqlQueryBuilder { None => "char".into(), }, ColumnType::String(length) => match length { - Some(length) => format!("varchar({length})"), - None => "varchar(255)".into(), + StringLen::N(length) => format!("varchar({length})"), + StringLen::None => "varchar(255)".into(), + StringLen::Max => "varchar(65535)".into(), }, ColumnType::Text => "text".into(), ColumnType::TinyInteger | ColumnType::TinyUnsigned => "tinyint".into(), @@ -63,18 +64,12 @@ impl TableBuilder for MysqlQueryBuilder { } } ColumnType::Interval(_, _) => "unsupported".into(), - ColumnType::Binary(blob_size) => match blob_size { - BlobSize::Tiny => "tinyblob".into(), - BlobSize::Blob(length) => { - match length { - Some(length) => format!("binary({length})"), - None => "blob".into(), - } - } - BlobSize::Medium => "mediumblob".into(), - BlobSize::Long => "longblob".into(), + ColumnType::Binary(length) => format!("binary({length})"), + ColumnType::VarBinary(length) => match length { + StringLen::N(length) => format!("varbinary({length})"), + StringLen::None => "varbinary(255)".into(), + StringLen::Max => "varbinary(65535)".into(), }, - ColumnType::VarBinary(length) => format!("varbinary({length})"), ColumnType::Bit(length) => { match length { Some(length) => format!("bit({length})"), diff --git a/src/backend/postgres/table.rs b/src/backend/postgres/table.rs index 11fc6a4f..22caec88 100644 --- a/src/backend/postgres/table.rs +++ b/src/backend/postgres/table.rs @@ -18,8 +18,8 @@ impl TableBuilder for PostgresQueryBuilder { None => "char".into(), }, ColumnType::String(length) => match length { - Some(length) => format!("varchar({length})"), - None => "varchar".into(), + StringLen::N(length) => format!("varchar({length})"), + _ => "varchar".into(), }, ColumnType::Text => "text".into(), ColumnType::TinyInteger | ColumnType::TinyUnsigned => "smallint".into(), @@ -47,11 +47,10 @@ impl TableBuilder for PostgresQueryBuilder { } typ } - ColumnType::Binary(_) => "bytea".into(), - ColumnType::VarBinary(length) => format!("bit varying({length})"), + ColumnType::Binary(_) | ColumnType::VarBinary(_) => "bytea".into(), ColumnType::Bit(length) => { match length { - Some(length) => format!("varbit({length})"), + Some(length) => format!("bit({length})"), None => "bit".into(), } } diff --git a/src/backend/sqlite/table.rs b/src/backend/sqlite/table.rs index e32741be..6be1528e 100644 --- a/src/backend/sqlite/table.rs +++ b/src/backend/sqlite/table.rs @@ -135,8 +135,8 @@ impl SqliteQueryBuilder { None => "char".into(), }, ColumnType::String(length) => match length { - Some(length) => format!("varchar({length})"), - None => "varchar".into(), + StringLen::N(length) => format!("varchar({length})"), + _ => "varchar".into(), }, ColumnType::Text => "text".into(), ColumnType::TinyInteger | ColumnType::TinyUnsigned => integer("tinyint").into(), @@ -167,18 +167,15 @@ impl SqliteQueryBuilder { ColumnType::Date => "date_text".into(), ColumnType::Interval(_, _) => unimplemented!("Interval is not available in Sqlite."), - ColumnType::Binary(blob_size) => match blob_size { - BlobSize::Tiny => "tinyblob".into(), - BlobSize::Blob(Some(length)) => format!("blob({length})"), - BlobSize::Blob(None) => "blob".into(), - BlobSize::Medium => "mediumblob".into(), - BlobSize::Long => "longblob".into(), + ColumnType::Binary(length) => format!("blob({length})"), + ColumnType::VarBinary(length) => match length { + StringLen::N(length) => format!("varbinary_blob({length})"), + _ => "varbinary_blob".into(), }, - ColumnType::VarBinary(length) => format!("varbinary_blob({length})"), ColumnType::Boolean => "boolean".into(), ColumnType::Money(precision) => match precision { - Some((precision, scale)) => format!("money({precision}, {scale})"), - None => "money".into(), + Some((precision, scale)) => format!("real_money({precision}, {scale})"), + None => "real_money".into(), }, ColumnType::Json => "json_text".into(), ColumnType::JsonBinary => "jsonb_text".into(), diff --git a/src/extension/mysql/column.rs b/src/extension/mysql/column.rs new file mode 100644 index 00000000..2782208a --- /dev/null +++ b/src/extension/mysql/column.rs @@ -0,0 +1,21 @@ +use crate::Iden; + +#[derive(Debug, Copy, Clone)] +pub enum MySqlType { + Blob, + TinyBlob, + MediumBlob, + LongBlob, +} + +impl Iden for MySqlType { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + let ty = match self { + Self::Blob => "blob", + Self::TinyBlob => "tinyblob", + Self::MediumBlob => "mediumblob", + Self::LongBlob => "longblob", + }; + write!(s, "{ty}").unwrap(); + } +} diff --git a/src/extension/mysql/mod.rs b/src/extension/mysql/mod.rs index dd8cc4f8..9841ca6e 100644 --- a/src/extension/mysql/mod.rs +++ b/src/extension/mysql/mod.rs @@ -1,5 +1,7 @@ +mod column; mod index; mod select; +pub use column::*; pub use index::*; pub use select::*; diff --git a/src/table/column.rs b/src/table/column.rs index 6fc4c28e..84c4d628 100644 --- a/src/table/column.rs +++ b/src/table/column.rs @@ -34,12 +34,12 @@ pub struct ColumnDef { /// | Date | date | date | date_text | /// | Year | year | N/A | N/A | /// | Interval | N/A | interval | N/A | -/// | Binary | blob | bytea | blob | -/// | VarBinary | varbinary | bit varying | varbinary_blob | +/// | Binary | binary | bytea | blob | +/// | VarBinary | varbinary | bytea | varbinary_blob | /// | Bit | bit | bit | N/A | /// | VarBit | bit | varbit | N/A | /// | Boolean | bool | bool | boolean | -/// | Money | money | money | money | +/// | Money | money | money | real_money | /// | Json | json | json | json_text | /// | JsonBinary | json | jsonb | jsonb_text | /// | Uuid | binary(16) | uuid | uuid_text | @@ -53,7 +53,7 @@ pub struct ColumnDef { #[derive(Debug, Clone)] pub enum ColumnType { Char(Option), - String(Option), + String(StringLen), Text, TinyInteger, SmallInteger, @@ -73,8 +73,8 @@ pub enum ColumnType { Date, Year(Option), Interval(Option, Option), - Binary(BlobSize), - VarBinary(u32), + Binary(u32), + VarBinary(StringLen), Bit(Option), VarBit(u32), Boolean, @@ -94,6 +94,16 @@ pub enum ColumnType { LTree, } +/// Length for var-char/binary; default to 255 +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum StringLen { + /// String size + N(u32), + Max, + #[default] + None, +} + impl PartialEq for ColumnType { fn eq(&self, other: &Self) -> bool { match (self, other) { @@ -179,15 +189,6 @@ pub enum MySqlYear { Four, } -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum BlobSize { - Tiny, - /// MySQL & SQLite support `binary(length)` column type - Blob(Option), - Medium, - Long, -} - impl ColumnDef { /// Construct a table column pub fn new(name: T) -> Self @@ -305,13 +306,13 @@ impl ColumnDef { /// Set column type as string with custom length pub fn string_len(&mut self, length: u32) -> &mut Self { - self.types = Some(ColumnType::String(Some(length))); + self.types = Some(ColumnType::String(StringLen::N(length))); self } /// Set column type as string pub fn string(&mut self) -> &mut Self { - self.types = Some(ColumnType::String(None)); + self.types = Some(ColumnType::String(Default::default())); self } @@ -477,25 +478,18 @@ impl ColumnDef { /// Set column type as binary with custom length pub fn binary_len(&mut self, length: u32) -> &mut Self { - self.types = Some(ColumnType::Binary(BlobSize::Blob(Some(length)))); + self.types = Some(ColumnType::Binary(length)); self } - /// Set column type as binary + /// Set column type as binary with default length of 1 pub fn binary(&mut self) -> &mut Self { - self.types = Some(ColumnType::Binary(BlobSize::Blob(None))); - self - } - - /// Set column type as blob, but when given BlobSize::Blob(size) argument, this column map to binary(size) type instead. - pub fn blob(&mut self, size: BlobSize) -> &mut Self { - self.types = Some(ColumnType::Binary(size)); - self + self.binary_len(1) } /// Set column type as binary with variable length pub fn var_binary(&mut self, length: u32) -> &mut Self { - self.types = Some(ColumnType::VarBinary(length)); + self.types = Some(ColumnType::VarBinary(StringLen::N(length))); self } diff --git a/src/value.rs b/src/value.rs index 7049d744..37cd4d2f 100644 --- a/src/value.rs +++ b/src/value.rs @@ -31,7 +31,7 @@ use std::net::IpAddr; #[cfg(feature = "with-mac_address")] use mac_address::MacAddress; -use crate::{BlobSize, ColumnType, CommonSqlQueryBuilder, QueryBuilder}; +use crate::{ColumnType, CommonSqlQueryBuilder, QueryBuilder, StringLen}; /// [`Value`] types variant for Postgres array #[derive(Clone, Debug, Eq, PartialEq, Hash)] @@ -495,12 +495,12 @@ impl ValueType for Cow<'_, str> { } fn column_type() -> ColumnType { - ColumnType::String(None) + ColumnType::String(StringLen::Max) } } -type_to_box_value!(Vec, Bytes, Binary(BlobSize::Blob(None))); -type_to_box_value!(String, String, String(None)); +type_to_box_value!(Vec, Bytes, VarBinary(StringLen::Max)); +type_to_box_value!(String, String, String(StringLen::Max)); #[cfg(feature = "with-json")] #[cfg_attr(docsrs, doc(cfg(feature = "with-json")))] diff --git a/tests/common.rs b/tests/common.rs index 65a24ebf..a3f90863 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -11,6 +11,7 @@ use sea_query::Iden; /// /// [`Iden`]: crate::types::Iden #[derive(Debug)] +#[allow(dead_code)] pub enum BinaryType { Table, BinaryLen, diff --git a/tests/mysql/mod.rs b/tests/mysql/mod.rs index fc7388cd..d717774f 100644 --- a/tests/mysql/mod.rs +++ b/tests/mysql/mod.rs @@ -1,4 +1,4 @@ -use sea_query::{tests_cfg::*, *}; +use sea_query::{extension::mysql::*, tests_cfg::*, *}; mod foreign_key; mod index; diff --git a/tests/mysql/table.rs b/tests/mysql/table.rs index d07df98d..8e19bf0a 100644 --- a/tests/mysql/table.rs +++ b/tests/mysql/table.rs @@ -165,18 +165,17 @@ fn create_6() { .table(BinaryType::Table) .col(ColumnDef::new(BinaryType::BinaryLen).binary_len(32)) .col(ColumnDef::new(BinaryType::Binary).binary()) - .col(ColumnDef::new(BinaryType::BlobSize).blob(BlobSize::Blob(Some(32)))) - .col(ColumnDef::new(BinaryType::TinyBlob).blob(BlobSize::Tiny)) - .col(ColumnDef::new(BinaryType::Blob).blob(BlobSize::Blob(None))) - .col(ColumnDef::new(BinaryType::MediumBlob).blob(BlobSize::Medium)) - .col(ColumnDef::new(BinaryType::LongBlob).blob(BlobSize::Long)) + .col(ColumnDef::new(BinaryType::Blob).custom(MySqlType::Blob)) + .col(ColumnDef::new(BinaryType::TinyBlob).custom(MySqlType::TinyBlob)) + .col(ColumnDef::new(BinaryType::MediumBlob).custom(MySqlType::MediumBlob)) + .col(ColumnDef::new(BinaryType::LongBlob).custom(MySqlType::LongBlob)) .to_string(MysqlQueryBuilder), [ "CREATE TABLE `binary_type` (", "`binlen` binary(32),", - "`bin` blob, `defb` binary(32),", - "`tb` tinyblob,", + "`bin` binary(1),", "`b` blob,", + "`tb` tinyblob,", "`mb` mediumblob,", "`lb` longblob", ")", @@ -196,7 +195,7 @@ fn create_7() { .to_string(MysqlQueryBuilder), [ "CREATE TABLE `character` (", - "`character` blob,", + "`character` binary(1),", "`font_size` binary(10),", "`size_w` varbinary(10)", ")", diff --git a/tests/postgres/table.rs b/tests/postgres/table.rs index c63e9e54..d26fa2c3 100644 --- a/tests/postgres/table.rs +++ b/tests/postgres/table.rs @@ -260,21 +260,11 @@ fn create_12() { .table(BinaryType::Table) .col(ColumnDef::new(BinaryType::BinaryLen).binary_len(32)) .col(ColumnDef::new(BinaryType::Binary).binary()) - .col(ColumnDef::new(BinaryType::BlobSize).blob(BlobSize::Blob(Some(32)))) - .col(ColumnDef::new(BinaryType::TinyBlob).blob(BlobSize::Tiny)) - .col(ColumnDef::new(BinaryType::Blob).blob(BlobSize::Blob(None))) - .col(ColumnDef::new(BinaryType::MediumBlob).blob(BlobSize::Medium)) - .col(ColumnDef::new(BinaryType::LongBlob).blob(BlobSize::Long)) .to_string(PostgresQueryBuilder), [ r#"CREATE TABLE "binary_type" ("#, r#""binlen" bytea,"#, - r#""bin" bytea,"#, - r#""defb" bytea,"#, - r#""tb" bytea,"#, - r#""b" bytea,"#, - r#""mb" bytea,"#, - r#""lb" bytea"#, + r#""bin" bytea"#, r#")"#, ] .join(" ") @@ -294,7 +284,7 @@ fn create_13() { r#"CREATE TABLE "character" ("#, r#""character" bytea,"#, r#""font_size" bytea,"#, - r#""size_w" bit varying(10)"#, + r#""size_w" bytea"#, r#")"#, ] .join(" ") diff --git a/tests/sqlite/table.rs b/tests/sqlite/table.rs index aa377359..12f2be7c 100644 --- a/tests/sqlite/table.rs +++ b/tests/sqlite/table.rs @@ -107,21 +107,11 @@ fn create_4() { .table(BinaryType::Table) .col(ColumnDef::new(BinaryType::BinaryLen).binary_len(32)) .col(ColumnDef::new(BinaryType::Binary).binary()) - .col(ColumnDef::new(BinaryType::BlobSize).blob(BlobSize::Blob(Some(32)))) - .col(ColumnDef::new(BinaryType::TinyBlob).blob(BlobSize::Tiny)) - .col(ColumnDef::new(BinaryType::Blob).blob(BlobSize::Blob(None))) - .col(ColumnDef::new(BinaryType::MediumBlob).blob(BlobSize::Medium)) - .col(ColumnDef::new(BinaryType::LongBlob).blob(BlobSize::Long)) .to_string(SqliteQueryBuilder), [ r#"CREATE TABLE "binary_type" ("#, r#""binlen" blob(32),"#, - r#""bin" blob,"#, - r#""defb" blob(32),"#, - r#""tb" tinyblob,"#, - r#""b" blob,"#, - r#""mb" mediumblob,"#, - r#""lb" longblob"#, + r#""bin" blob(1)"#, r#")"#, ] .join(" ") @@ -139,7 +129,7 @@ fn create_5() { .to_string(SqliteQueryBuilder), [ r#"CREATE TABLE "character" ("#, - r#""character" blob,"#, + r#""character" blob(1),"#, r#""font_size" blob(10),"#, r#""size_w" varbinary_blob(10)"#, r#")"#,