Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Postgresql enum type via Kotlin Exposed ORM?

I have added some Postgresql types to Exposed as extensions. It has two ready types named enumeration and enumerationByName. I tested both of them with no success for mapping a postgre enum type to Kotlin enum class. In both reading and writing it raises error

enum class TicketStatus(val status: String) {
    Open("open"),
    Close("close"),
    InProgress("in_progress")
}

class Ticket(id: EntityID<UUID>) : Entity<UUID>(id) {
    companion object : EntityClass<UUID, Ticket>(Tickets)

    var geom by Tickets.geom
    var description by Tickets.description
    var status by Tickets.status
    var createdAt by Tickets.createdAt
    var updatedAt by Tickets.updatedAt
    var owner by Tickets.owner
}

When reading:

java.lang.IllegalStateException: open is not valid for enum TicketStatus
like image 932
Kamyar Avatar asked Aug 16 '17 22:08

Kamyar


People also ask

How do I select enum type in PostgreSQL?

Enumerated types can be selected in the same way as standard data types. You can pick the Enum type from the datatype drop-down. Tip: A default value can be defined for the column. Expand the column detail by clicking the arrow icon and specify the value in the Default value field.

Can enums have methods Kotlin?

Since Kotlin enums are classes, they can have their own properties, methods, and implement interfaces.

What is enum data type in PostgreSQL?

Enumerated (enum) types are data types that comprise a static, ordered set of values. They are equivalent to the enum types supported in a number of programming languages. An example of an enum type might be the days of the week, or a set of status values for a piece of data.

Can enum class inherit Kotlin?

Enums can be used in kotlin's when construct, We must use the else block to handle if we receive any value other Than value present in the Enum.


2 Answers

You should declare status column as follow:

object Tickets: Table() {
   val status = enumeration("status", TicketStatus::class.java) // will create integer column
   val status = enumerationByName("status", TicketStatus::class.java) // will create varchar with TicketStatus names
}
like image 176
Tapac Avatar answered Oct 20 '22 00:10

Tapac


I realize this is an old question, but if anyone is still looking for an answer here you go:

Exposed has a customEnumeration that can be used to deal with Enums, and is particularly useful if you are using Strings, or another non-default enumerator to back your enum.

For postgres, you'll first need to define a class like so:

class PGEnum<T:Enum<T>>(enumTypeName: String, enumValue: T?) : PGobject() {
    init {
        value = enumValue?.name
        type = enumTypeName
    }
}

Then in your table definition, use the following to define your column, replacing the placeholders as necessary:

val enumColumn = customEnumeration(
            "ENUM_COLUMN",
            "ENUM_SCHEMA.ENUM_TYPE",
            { value ->
                when (value) {
                    is PGobject -> LocalEnumClass.valueOf(value.value)
                    is String -> LocalEnumClass.valueOf(value)
                    else -> error("Can't convert ENUM_COLUMN")
                }
            },
            { PGEnum("ENUM_SCHEMA.ENUM_TYPE", it) }
)

I was running into the same org.postgresql.util.PGobject is not valid for enum before I did this.

See here for more information, and for non-Postgres databases

like image 33
William King Avatar answered Oct 19 '22 23:10

William King