jpenna
jpenna

Reputation: 9211

Rename enum value for use with sqlx in query

I'm using Postgres. I want to store char in the a column that will give the "type" of the row. But I also want the code to be more expressive, so I don't want to create enums with char values, but actual strings.

This is the table:

CREATE TABLE
    chats (
        id UUID PRIMARY KEY DEFAULT uuid_generate_v4 (),
        name VARCHAR(100) NOT NULL,
        -- p: one-on-one, g: group, b: broadcast, s: service
        type CHAR(1) NOT NULL,
        created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
        updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
    );

This is how I'd like to use it:

#[derive(sqlx::Type, Debug, Serialize, Deserialize)]
pub enum ChatType {
    #[sqlx(rename="p")]
    Personal, 
    #[sqlx(rename="g")]
    Group,
    #[sqlx(rename="b")]
    Broadcast,
    #[sqlx(rename="s")]
    Service,
}

There is a #[sqlx(rename="name")], but that didn't do what I expected. I get the following error at runtime (unfortunately, it compiles fine):

Error: error returned from database: type "chattype" does not exist

Caused by:
    type "chattype" does not exist

Stack backtrace:
   0: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from

Can it be achieved?

Upvotes: 1

Views: 37

Answers (1)

jpenna
jpenna

Reputation: 9211

Found out it can! And it was very simple...

The rename in the enum value works, but I had to add one line:

#[derive(sqlx::Type, Debug, Serialize, Deserialize)]
#[sqlx(type_name="CHAR")]
pub enum ChatType {
    #[sqlx(rename = "p")]
    Personal,
    #[sqlx(rename = "g")]
    Group,
    #[sqlx(rename = "b")]
    Broadcast,
    #[sqlx(rename = "s")]
    Service,
}

#[sqlx(type_name="CHAR")] says that the type for the enum is CHAR, which overrides the default type for the enum with string values, which is VARCHAR.

By the way, if you use sqlx::Type but don't define the sqlx(type_name...) trait, it will default to expecting a custom enum defined in the database with the name of the enum, in this case "chattype" (you will get the error "type "chattype" does not exist").

Upvotes: 1

Related Questions