美文网首页
Slick支持postgre枚举类型

Slick支持postgre枚举类型

作者: Assassin_1397 | 来源:发表于2023-01-10 14:39 被阅读0次

假如你在postgre创建了一个枚举类型

create type merchants_location_type as enum('IN_CAMPUS','OTHER_LOCATION','NO_LIMIT');

merchants table schema is as below

create table merchants
(
    id                  text                                                                    not null
        constraint merchants_pk
            primary key,
    location_type       merchants_location_type     default 'NO_LIMIT'::merchants_location_type not null
);

Customer postgres profile is

package xxx.api.merchant.utils

import xxx.api.merchant.merchant.LocationType
import com.github.tminglei.slickpg._
import play.api.libs.json.{JsValue, Json}
import slick.jdbc.PostgresProfile
trait MyPostgresProfile
    extends ExPostgresProfile
    with PgArraySupport
    with PgDate2Support
    with PgRangeSupport
    with PgHStoreSupport
    with PgPlayJsonSupport
    with PgSearchSupport
    with PgNetSupport
    with PgLTreeSupport
    with PgEnumSupport
    with PgDateSupportJoda {
  def pgjson = "jsonb" // jsonb support is in postgres 9.4.0 onward; for 9.3.x use "json"

  // Add back `capabilities.insertOrUpdate` to enable native `upsert` support; for postgres 9.5+
  override protected def computeCapabilities: Set[slick.basic.Capability] =
    super.computeCapabilities + slick.jdbc.JdbcCapabilities.insertOrUpdate

  override val api = MyAPI

  object MyAPI
      extends super.API
      with ArrayImplicits
      with DateTimeImplicits
      with JsonImplicits
      with NetImplicits
      with LTreeImplicits
      with RangeImplicits
      with HStoreImplicits
      with SearchImplicits
      with SearchAssistants {
    implicit val strListTypeMapper = new SimpleArrayJdbcType[String]("text").to(_.toList)
    implicit val playJsonArrayTypeMapper =
      new AdvancedArrayJdbcType[JsValue](
        pgjson,
        s => utils.SimpleArrayUtils.fromString[JsValue](Json.parse(_))(s).orNull,
        v => utils.SimpleArrayUtils.mkString[JsValue](_.toString())(v)
      ).to(_.toList)

    implicit val locationTypeMapper = createEnumJdbcType("merchants_location_type", LocationType)
  }
}

object MyPostgresProfile extends MyPostgresProfile {
  /*bindPgDateTypesToScala(
    classTag[LocalDate],
    classTag[LocalTime],
    classTag[LocalDateTime],
    classTag[OffsetTime],
    classTag[OffsetDateTime],
    classTag[Duration]
  )*/
}

Slick code generator code is as bellow

package xxx.app.api.merchant.slick.gen

import slick.codegen.SourceCodeGenerator
import slick.model.Model
import slick.sql.SqlProfile.ColumnOption

class CustomSourceCodeGenerator(model: Model) extends SourceCodeGenerator(model) {
  override def Table: slick.model.Table => TableDef = new Table(_) { table =>
    override def Column: slick.model.Column => ColumnDef = new Column(_) { column =>
      override def rawType: String =
        model.options
          .find(_.isInstanceOf[ColumnOption.SqlType])
          .flatMap { tpe =>
            tpe.asInstanceOf[ColumnOption.SqlType].typeName match {
              case "_text" | "text[]" | "_varchar" | "varchar[]" => Option("List[String]")
              case "_int8" | "int8[]"                            => Option("List[Long]")
              case "_int4" | "int4[]"                            => Option("List[Int]")
              case "_int2" | "int2[]"                            => Option("List[Short]")
              case "_uuid" | "uuid[]"                            => Option("List[java.util.UUID]")
              case "merchants_location_type" =>
                Option("xxx.api.merchant.merchant.LocationType.LocationType")
              case _ => None
            }
          }
          .getOrElse {
            model.tpe match {
              case _ => super.rawType
            }
          }

    }
  }

  override def packageCode(
      profile: String,
      pkg: String,
      container: String,
      parentType: Option[String]
  ): String =
    s"""
       |package $pkg
       |// AUTO-GENERATED Slick data model
       |/** Stand-alone Slick data model for immediate use */
       |object $container extends {
       |  val profile = $profile
       |} with $container
       |
       |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.) */
       |trait $container${parentType.map(t => s" extends $t").getOrElse("")} {
       |  val profile: $profile
       |  import profile.api._
       |  ${indent(code)}
       |}
       |""".stripMargin

  protected def handleQuotedNamed(tableName: String): String =
    if (tableName.endsWith("`")) s"${tableName.init}Table`" else s"${tableName}Table"

  override def packageContainerCode(profile: String, pkg: String, container: String): String = {
    val mixinCode =
      codePerTable.keys
        .map(tableName => s"${handleQuotedNamed(tableName)}")
        .mkString("extends ", " with ", "")

    s"""
       |package $pkg
       |// AUTO-GENERATED Slick data model
       |/** Stand-alone Slick data model for immediate use */
       |object $container extends {
       |  val profile = $profile
       |} with $container
       |
       |/** Slick data model trait for extension, choice of backend or usage in the cake pattern. (Make sure to initialize this late.)
       |    Each generated XXXXTable trait is mixed in this trait hence allowing access to all the TableQuery lazy vals.
       |  */
       |trait $container${parentType.map(t => s" extends $t").getOrElse("")} $mixinCode {
       |  val profile: $profile
       |  import profile.api._
       |  ${indent(codeForContainer)}
       |
       |}
       |""".stripMargin
  }
}

相关文章

网友评论

      本文标题:Slick支持postgre枚举类型

      本文链接:https://www.haomeiwen.com/subject/wudvcdtx.html