Scala编译失败,错误为:找不到参数W的隐含值

bvjveswy  于 2022-11-09  发布在  Scala
关注(0)|答案(1)|浏览(203)

我得到了一个不想编译的doobie查询:

package de.x.vmdbplanningvalues.impl.queries

import de.x.campaignplans.CampaignPlanId
import de.x.distributionbrands.DistributionBrandId
import de.x.vmdbplanningvalues._
import doobie._

object UpdateVmdbPlanningValuesQuery {
  case class VmdbPlanningUpdate(
      creditRatingRejections: Option[Double],
      goodsCoupons: Option[Double],
      customerDiscounts: Option[Double],
      campaignPlanId: String,
      distributionBrandId: String,
      country: String,
      categoryId: String,
      lane: VmdbLane
  )

  def apply(
      distributionBrand: DistributionBrandId,
      country: String,
      campaignPlanId: CampaignPlanId,
      category: String,
      updates: List[VmdbPlanningValuesForVmdbLane]
  ): ConnectionIO[Unit] = {
    for {
      _ <- updateQuery(updates.map(update =>
        VmdbPlanningUpdate(
          update.creditRatingRejections,
          update.goodsCoupons,
          update.customerDiscounts,
          campaignPlanId.id,
          distributionBrand.id,
          country,
          category,
          update.lane
        )
      ))
    } yield ()
  }

  def updateQuery[T: Write](updates: List[VmdbPlanningUpdate]): ConnectionIO[Int] = {
    val sql =
      """
         UPDATE vmdb_planning_values as vmdb
         SET vmdb.credit_rating_rejections = ?,
             vmdb.goods_coupons = ?,
             vmdb.customer_discounts = ?
         FROM campaign_plan cp
         WHERE cp.id = ?
            AND vmdb.distribution_brand_id = ?
            AND vmdb.country_id = ?
            AND vmdb.year=DATE_PART('year', cp.start_date)
            AND vmdb.quarter=DATE_PART('quarter', cp.start_date)
            AND vmdb.category_id = ?
            AND vmdb.lane = ?
      """

    Update[VmdbPlanningUpdate](sql).updateMany(updates)
  }
}

但是,它会失败,并显示以下错误:

[error] /Users/johannesklauss/Documents/campaign-service/server/src/main/scala/de/x/vmdbplanningvalues/impl/queries/UpdateVmdbPlanningValuesQuery.scala:60:35: could not find implicit value for parameter W: doobie.Write[de.x.vmdbplanningvalues.impl.queries.UpdateVmdbPlanningValuesQuery.VmdbPlanningUpdate]
[error]     Update[VmdbPlanningUpdate](sql).updateMany(updates)
[error]

我不太确定错误消息是什么意思,因为我仍然不太清楚Scala中的隐含含义。有谁有主意吗?
编辑:添加了VmdbLane.scala:

package de.x.vmdbplanningvalues

import io.circe.Decoder.Result
import io.circe._

sealed trait VmdbLane {
  override def toString: String = VmdbLane.toEnum(this)
}

object VmdbLane {

  case object New extends VmdbLane
  case object CarryOver extends VmdbLane
  case object Sale extends VmdbLane
  case object Sum extends VmdbLane

  def toEnum(e: VmdbLane): String =
    e match {
      case New => "new"
      case CarryOver => "carryOver"
      case Sale => "sale"
      case Sum => "sum"
    }

  def fromEnum(s: String): Option[VmdbLane] =
    Option(s) collect {
      case "new" => New
      case "carryOver" => CarryOver
      case "sale" => Sale
      case "sum" => Sum
    }

  implicit val jsonFormat: Encoder[VmdbLane] with Decoder[VmdbLane] =
    new Encoder[VmdbLane] with Decoder[VmdbLane] {
      override def apply(a: VmdbLane): Json = Encoder.encodeString(toEnum(a))
      override def apply(c: HCursor): Result[VmdbLane] =
        c.value.asString.flatMap(s => fromEnum(s)) match {
          case Some(a) => Right(a)
          case None => Left(DecodingFailure("VmdbLane", c.history))
        }
    }
}
q0qdq0h2

q0qdq0h21#

这个问题与Circe无关,而是与定制doobie类型Map的工作方式有关。如果在VmdbLane对象中包含类似的内容:

implicit val natGet: Get[VmdbLane] = Get[String].map(in => {
    in match {
      case "New"       => New
      case "CarryOver" => CarryOver
      case "Sale"      => Sale
      case "Sum"       => Sum
    }
  })

implicit val natPut: Put[VmdbLane] = Put[String].contramap {
    case New       => "New"
    case CarryOver => "CarryOver"
    case Sale      => "Sale"
    case Sum       => "Sum"
  }

编译器应该包括它应该起作用的Map.

相关问题