Merge pull request #324 from SeaQL/hotfix-custom-types
Unknown types could be a newtypes instead of `ActiveEnum`
This commit is contained in:
commit
aff988bd94
2
.github/workflows/rust.yml
vendored
2
.github/workflows/rust.yml
vendored
@ -314,7 +314,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
path: [86, 249, 262, 319]
|
path: [86, 249, 262, 319, 324]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
11
issues/324/Cargo.toml
Normal file
11
issues/324/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[workspace]
|
||||||
|
# A separate workspace
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "sea-orm-issues-324"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls" ]}
|
3
issues/324/src/main.rs
Normal file
3
issues/324/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod model;
|
||||||
|
|
||||||
|
pub fn main() {}
|
83
issues/324/src/model.rs
Normal file
83
issues/324/src/model.rs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "model")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key)]
|
||||||
|
pub id: AccountId,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct AccountId(Uuid);
|
||||||
|
|
||||||
|
impl From<AccountId> for Uuid {
|
||||||
|
fn from(account_id: AccountId) -> Self {
|
||||||
|
account_id.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_try_from_u64_err {
|
||||||
|
($newtype: ident) => {
|
||||||
|
impl sea_orm::TryFromU64 for $newtype {
|
||||||
|
fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {
|
||||||
|
Err(sea_orm::DbErr::Exec(format!(
|
||||||
|
"{} cannot be converted from u64",
|
||||||
|
stringify!($newtype)
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! into_sea_query_value {
|
||||||
|
($newtype: ident: Box($name: ident)) => {
|
||||||
|
impl From<$newtype> for sea_orm::Value {
|
||||||
|
fn from(source: $newtype) -> Self {
|
||||||
|
sea_orm::Value::$name(Some(Box::new(source.into())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_orm::TryGetable for $newtype {
|
||||||
|
fn try_get(
|
||||||
|
res: &sea_orm::QueryResult,
|
||||||
|
pre: &str,
|
||||||
|
col: &str,
|
||||||
|
) -> Result<Self, sea_orm::TryGetError> {
|
||||||
|
let val: $name = res.try_get(pre, col).map_err(sea_orm::TryGetError::DbErr)?;
|
||||||
|
Ok($newtype(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_orm::sea_query::Nullable for $newtype {
|
||||||
|
fn null() -> sea_orm::Value {
|
||||||
|
sea_orm::Value::$name(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sea_orm::sea_query::ValueType for $newtype {
|
||||||
|
fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
|
||||||
|
match v {
|
||||||
|
sea_orm::Value::$name(Some(x)) => Ok($newtype(*x)),
|
||||||
|
_ => Err(sea_orm::sea_query::ValueTypeErr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_name() -> String {
|
||||||
|
stringify!($newtype).to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn column_type() -> sea_orm::sea_query::ColumnType {
|
||||||
|
sea_orm::sea_query::ColumnType::$name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
into_sea_query_value!(AccountId: Box(Uuid));
|
||||||
|
impl_try_from_u64_err!(AccountId);
|
@ -237,7 +237,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
let field_span = field.span();
|
let field_span = field.span();
|
||||||
let ty = format_ident!("{}", temp);
|
let ty = format_ident!("{}", temp);
|
||||||
let def = quote_spanned! { field_span => {
|
let def = quote_spanned! { field_span => {
|
||||||
<#ty as ActiveEnum>::db_type()
|
std::convert::Into::<sea_orm::ColumnType>::into(
|
||||||
|
<#ty as sea_orm::sea_query::ValueType>::column_type()
|
||||||
|
)
|
||||||
|
.def()
|
||||||
}};
|
}};
|
||||||
quote! { #def }
|
quote! { #def }
|
||||||
} else {
|
} else {
|
||||||
|
@ -364,10 +364,11 @@ impl From<ColumnType> for sea_query::ColumnType {
|
|||||||
ColumnType::Money(s) => sea_query::ColumnType::Money(s),
|
ColumnType::Money(s) => sea_query::ColumnType::Money(s),
|
||||||
ColumnType::Json => sea_query::ColumnType::Json,
|
ColumnType::Json => sea_query::ColumnType::Json,
|
||||||
ColumnType::JsonBinary => sea_query::ColumnType::JsonBinary,
|
ColumnType::JsonBinary => sea_query::ColumnType::JsonBinary,
|
||||||
ColumnType::Custom(s) | ColumnType::Enum(s, _) => {
|
ColumnType::Custom(s) => {
|
||||||
sea_query::ColumnType::Custom(sea_query::SeaRc::new(sea_query::Alias::new(&s)))
|
sea_query::ColumnType::Custom(sea_query::SeaRc::new(sea_query::Alias::new(&s)))
|
||||||
}
|
}
|
||||||
ColumnType::Uuid => sea_query::ColumnType::Uuid,
|
ColumnType::Uuid => sea_query::ColumnType::Uuid,
|
||||||
|
ColumnType::Enum(name, variants) => sea_query::ColumnType::Enum(name, variants),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,6 +399,7 @@ impl From<sea_query::ColumnType> for ColumnType {
|
|||||||
sea_query::ColumnType::JsonBinary => Self::JsonBinary,
|
sea_query::ColumnType::JsonBinary => Self::JsonBinary,
|
||||||
sea_query::ColumnType::Custom(s) => Self::Custom(s.to_string()),
|
sea_query::ColumnType::Custom(s) => Self::Custom(s.to_string()),
|
||||||
sea_query::ColumnType::Uuid => Self::Uuid,
|
sea_query::ColumnType::Uuid => Self::Uuid,
|
||||||
|
sea_query::ColumnType::Enum(name, variants) => Self::Enum(name, variants),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,24 +128,17 @@ pub async fn create_byte_primary_key_table(db: &DbConn) -> Result<ExecResult, Db
|
|||||||
|
|
||||||
pub async fn create_active_enum_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
pub async fn create_active_enum_table(db: &DbConn) -> Result<ExecResult, DbErr> {
|
||||||
let db_backend = db.get_database_backend();
|
let db_backend = db.get_database_backend();
|
||||||
let tea_enum = Alias::new("tea");
|
|
||||||
|
|
||||||
let create_enum_stmts = match db_backend {
|
let create_enum_stmts = match db_backend {
|
||||||
DbBackend::MySql | DbBackend::Sqlite => Vec::new(),
|
DbBackend::MySql | DbBackend::Sqlite => Vec::new(),
|
||||||
DbBackend::Postgres => vec![Type::create()
|
DbBackend::Postgres => vec![Type::create()
|
||||||
.as_enum(tea_enum.clone())
|
.as_enum(Alias::new("tea"))
|
||||||
.values(vec![Alias::new("EverydayTea"), Alias::new("BreakfastTea")])
|
.values(vec![Alias::new("EverydayTea"), Alias::new("BreakfastTea")])
|
||||||
.to_owned()],
|
.to_owned()],
|
||||||
};
|
};
|
||||||
|
|
||||||
create_enum(db, &create_enum_stmts, ActiveEnum).await?;
|
create_enum(db, &create_enum_stmts, ActiveEnum).await?;
|
||||||
|
|
||||||
let mut tea_col = ColumnDef::new(active_enum::Column::Tea);
|
|
||||||
match db_backend {
|
|
||||||
DbBackend::MySql => tea_col.custom(Alias::new("ENUM('EverydayTea', 'BreakfastTea')")),
|
|
||||||
DbBackend::Sqlite => tea_col.text(),
|
|
||||||
DbBackend::Postgres => tea_col.custom(tea_enum),
|
|
||||||
};
|
|
||||||
let create_table_stmt = sea_query::Table::create()
|
let create_table_stmt = sea_query::Table::create()
|
||||||
.table(active_enum::Entity.table_ref())
|
.table(active_enum::Entity.table_ref())
|
||||||
.col(
|
.col(
|
||||||
@ -157,7 +150,10 @@ pub async fn create_active_enum_table(db: &DbConn) -> Result<ExecResult, DbErr>
|
|||||||
)
|
)
|
||||||
.col(ColumnDef::new(active_enum::Column::Category).string_len(1))
|
.col(ColumnDef::new(active_enum::Column::Category).string_len(1))
|
||||||
.col(ColumnDef::new(active_enum::Column::Color).integer())
|
.col(ColumnDef::new(active_enum::Column::Color).integer())
|
||||||
.col(&mut tea_col)
|
.col(
|
||||||
|
ColumnDef::new(active_enum::Column::Tea)
|
||||||
|
.enumeration("tea", vec!["EverydayTea", "BreakfastTea"]),
|
||||||
|
)
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
create_table(db, &create_table_stmt, ActiveEnum).await
|
create_table(db, &create_table_stmt, ActiveEnum).await
|
||||||
|
Loading…
x
Reference in New Issue
Block a user