Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mysql: sized blob data type moved to MySqlType & upstream StringLen #743

Merged
merged 11 commits into from
Jan 30, 2024
Merged
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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
21 changes: 8 additions & 13 deletions src/backend/mysql/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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})"),
Expand Down
9 changes: 4 additions & 5 deletions src/backend/postgres/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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(),
}
}
Expand Down
19 changes: 8 additions & 11 deletions src/backend/sqlite/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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(),
Expand Down
21 changes: 21 additions & 0 deletions src/extension/mysql/column.rs
Original file line number Diff line number Diff line change
@@ -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();
}
}
2 changes: 2 additions & 0 deletions src/extension/mysql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod column;
mod index;
mod select;

pub use column::*;
pub use index::*;
pub use select::*;
50 changes: 22 additions & 28 deletions src/table/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -53,7 +53,7 @@ pub struct ColumnDef {
#[derive(Debug, Clone)]
pub enum ColumnType {
Char(Option<u32>),
String(Option<u32>),
String(StringLen),
Text,
TinyInteger,
SmallInteger,
Expand All @@ -73,8 +73,8 @@ pub enum ColumnType {
Date,
Year(Option<MySqlYear>),
Interval(Option<PgInterval>, Option<u32>),
Binary(BlobSize),
VarBinary(u32),
Binary(u32),
VarBinary(StringLen),
Bit(Option<u32>),
VarBit(u32),
Boolean,
Expand All @@ -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) {
Expand Down Expand Up @@ -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<u32>),
Medium,
Long,
}

impl ColumnDef {
/// Construct a table column
pub fn new<T>(name: T) -> Self
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand Down
8 changes: 4 additions & 4 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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<u8>, Bytes, Binary(BlobSize::Blob(None)));
type_to_box_value!(String, String, String(None));
type_to_box_value!(Vec<u8>, 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")))]
Expand Down
1 change: 1 addition & 0 deletions tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use sea_query::Iden;
///
/// [`Iden`]: crate::types::Iden
#[derive(Debug)]
#[allow(dead_code)]
pub enum BinaryType {
Table,
BinaryLen,
Expand Down
2 changes: 1 addition & 1 deletion tests/mysql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use sea_query::{tests_cfg::*, *};
use sea_query::{extension::mysql::*, tests_cfg::*, *};

mod foreign_key;
mod index;
Expand Down
15 changes: 7 additions & 8 deletions tests/mysql/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
")",
Expand All @@ -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)",
")",
Expand Down
14 changes: 2 additions & 12 deletions tests/postgres/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(" ")
Expand All @@ -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(" ")
Expand Down
Loading
Loading