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

Enumeration #252

Closed
2 of 3 tasks
tyt2y3 opened this issue Oct 16, 2021 · 0 comments · Fixed by #258, #261 or #274
Closed
2 of 3 tasks

Enumeration #252

tyt2y3 opened this issue Oct 16, 2021 · 0 comments · Fixed by #258, #261 or #274
Assignees

Comments

@tyt2y3
Copy link
Member

tyt2y3 commented Oct 16, 2021

This issue is to outline the design of how to allow custom Enums to be used in SeaORM Entity.

It will be supported in 3 steps:

  • Rust enum support (but serialize to string or integer)
  • Mapping to a database native enum
  • Schema discovery & code generation

A proposed trait ActiveEnum (or DbEnum or OrmEnum etc) would be:

trait ActiveEnum {
    type Value: ValueType;

    fn to_value(&self) -> Self::Value;
    fn try_from_value(v: &Self::Value) -> Result<Self, DbErr>;
    fn db_type() -> ColumnDef;
}

A sample model would be like:

enum Category {
    Big,
    Small,
}

struct Model {
    category: Category;
}

impl ActiveEnum for Category {
    type Value = String;

    fn to_value(&self) -> Self::Value {
        match self {
            Big => "B",
            Small => "S",
        }.to_owned()
    }
    fn from_value(v: &Self::Value) -> Result<Self, DbErr> {
        match v.as_ref {
            "B" => Ok(Self::Big),
            "S" => Ok(Self::Small),
            _ => Err(DbErr::TypeErr(format!("unexpected value for Category: {}", v))),
        }
    }
    fn db_type() -> ColumnDef {
        ColumnType::String(Some(1)).def
    }
}

Such a trait should be all it takes for using a custom enum (we need to eliminate all boilerplate as in #196 (reply in thread)). And it will be converted automatically during Select, Insert and Update.

We can also make a DeriveActiveEnum macro to make it easier:

#[derive(DeriveActiveEnum)]
#[sea_orm(db_type = "String(Some(1))")]
enum Category {
    #[sea_orm(string_value = "B")]
    Big,
    #[sea_orm(string_value = "S")]
    Small,
}

(because of the excess String("B"), we'd better divide into string_value and num_value)

After some discussion with @acidic9, to support native enum in Postgres, we basically have to cast everywhere:

SELECT CAST("category" AS text) from "mytable";
INSERT INTO "mytable" ("category") VALUES (CAST($1 AS CategoryEnum));
UPDATE "mytable" SET "category" = CAST($1 AS CategoryEnum);

For MySQL, casting is not needed.

Ref: #196

@tyt2y3 tyt2y3 added this to the 0.4.x - Enumeration milestone Oct 16, 2021
@billy1624 billy1624 mentioned this issue Oct 19, 2021
@billy1624 billy1624 self-assigned this Oct 19, 2021
@billy1624 billy1624 mentioned this issue Oct 21, 2021
1 task
@billy1624 billy1624 linked a pull request Oct 21, 2021 that will close this issue
1 task
@billy1624 billy1624 mentioned this issue Oct 26, 2021
1 task
@billy1624 billy1624 linked a pull request Oct 26, 2021 that will close this issue
1 task
@billy1624 billy1624 mentioned this issue Nov 17, 2021
10 tasks
billy1624 added a commit to SeaQL/seaql.github.io that referenced this issue Nov 17, 2021
billy1624 added a commit to SeaQL/seaql.github.io that referenced this issue Nov 18, 2021
tyt2y3 pushed a commit to SeaQL/seaql.github.io that referenced this issue Nov 19, 2021
* Draft "What's new in SeaORM 0.4.0"

* Disable SQLx logging (SeaQL/sea-orm#290)

* Refactor `Schema` (SeaQL/sea-orm#309)

* ActiveEnum (SeaQL/sea-orm#252)

* ActiveEnum (SeaQL/sea-orm#252)

* Move

* Move

* Update docs link

* Self referencing

* Move

* Generating database schema

* Generating database schema

* Change date

* Edit

* Edit
arpancodes pushed a commit to arpancodes/sea-orm that referenced this issue Apr 8, 2022
arpancodes pushed a commit to arpancodes/sea-orm that referenced this issue Apr 8, 2022
This reverts commit f60ee3a, reversing
changes made to 81285b9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants