Reputation: 534
I am getting an error with the code below
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)))
And the decoder is here:
case class ValueObject(field1: Int, field2: String)
object ValueObject {
val decoder: Decoder[ValueObject] =
(int4 ~ varchar).map { case (f1, f2) => ValueObject(f1, f2) }
}
And the error is:
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)
Where is actually the problem?
Upvotes: 1
Views: 273
Reputation: 13
Versions:
Represents a Data Transfer Object (DTO) for a database entity
import skunk.codec.all.{int4, varchar}
object Dto {
/**
* Represents a value object with two fields: field1 of type Int and
* field2 of type String.
*/
case class ValueObject(field1: Int, field2: String)
/**
* Companion object for ValueObject, providing codecs for
* serialization/deserialization.
*/
object ValueObject {
/** Codec to serialize/deserialize ValueObject instances. */
val codec: Codec[ValueObject] = (int4 *: varchar).to[ValueObject]
}
}
This query has a slight error:
val query: Query[(String *: Int), ValueObject] =
sql"""
SELECT field1, field2
FROM sample_table
WHERE field1 = $text
AND field2 = $int4
""".query(ValueObject.decoder)
WHERE field1 = $text AND field2 = $int4
should actually be field1 = $int4 and field2 = $text
Twiddle Lists String *: Int *: EmptyTuple
use instead of tuple
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)
}
Instead of s.option(query)((param1, param2))
, please write s.option(query)(field2 *: field1 *: EmptyTuple
).
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))
}
}
Upvotes: 0
Reputation: 534
SOLUTION:
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)
}
Upvotes: 0