我在使用下面的代码时遇到错误
import br.com.gbtech.model.PaymentRequestItem
import cats.effect.{IO, Resource}
import skunk.codec.all.*
import skunk.implicits.*
import skunk.{Query, Session, ~}
val query: Query[(String *: Int), ValueObject] =
sql"""
SELECT field1, field2
FROM sample_table
WHERE field1 = $text
AND field2 = $int4
""".query(ValueObject.decoder)
database.use(s => s.option(query)((param1, param2)))
解码器在这里:
case class ValueObject(field1: Int, field2: String)
object ValueObject {
val decoder: Decoder[ValueObject] =
(int4 ~ varchar).map { case (f1, f2) => ValueObject(f1, f2) }
}
错误是:
type mismatch;
found : skunk.Query[String *: Int *: org.typelevel.twiddles.EmptyTuple,br.com.ValueObject]
(which expands to) skunk.Query[String :: Int :: shapeless.HNil,br.com.ValueObject]
required: skunk.Query[String *: Int,br.com.ValueObject]
(which expands to) skunk.Query[String :: Int,br.com.ValueObject]
""".query(ValueObject.decoder)
问题究竟出在哪里?
解决方案:
import skunk.codec.all.*
import skunk.implicits.*
import skunk.*
Query[String *: Int *: EmptyTuple, ValueObject]
val decoder: Decoder[ValueObject] =
(int4 ~ varchar).map { case (f1, f2) =>
ValueObject(f1, f2)
}
版本:
import skunk.codec.all.{int4, varchar}
object Dto {
case class ValueObject(field1: Int, field2: String)
object ValueObject {
val codec: Codec[ValueObject] = (int4 *: varchar).to[ValueObject]
}
}
import skunk._
import skunk.implicits._
import Dto._
object ValueObjectSql {
val query: Query[String *: Int *: EmptyTuple, ValueObject] =
sql"""
SELECT field1, field2
FROM sample_table
WHERE field2 = $varchar
AND field1 = $int4
""".query(ValueObject.codec)
}
import cats.effect.Resource
import cats.effect.kernel.MonadCancelThrow
import skunk._
import Dto._
import ValueObjectSql._
trait ValueObjectRepository[F[_]] {
def findValue(field1: Int, field2: String): F[Option[ValueObject]]
}
object ValueObjectRepository {
def make[F[_]: MonadCancelThrow](
implicit
session: Resource[F, Session[F]]
): ValueObjectRepository[F] = new ValueObjectRepository[F] {
override def findValue(field1: Int, field2: String): F[Option[ValueObject]] =
session.use(s => s.option(query)(field2 *: field1 *: EmptyTuple))
}
}