All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ldbc.dsl.ResultSetConsumer.scala Maven / Gradle / Ivy

/**
 * Copyright (c) 2023-2024 by Takahiko Tominaga
 * This software is licensed under the MIT License (MIT).
 * For more information see LICENSE or https://opensource.org/licenses/MIT
 */

package ldbc.dsl

import cats.*
import cats.syntax.all.*

import ldbc.sql.ResultSet
import ldbc.dsl.util.FactoryCompat
import ldbc.dsl.codec.Decoder

/**
 * Trait for generating the specified data type from a ResultSet.
 *
 * @tparam F
 *   The effect type
 * @tparam T
 *   Type you want to build with data obtained from ResultSet
 */
trait ResultSetConsumer[F[_], T]:

  /**
   * Method for generating the specified data type from a ResultSet.
   *
   * @param resultSet
   *   A table of data representing a database result set, which is usually generated by executing a statement that
   *   queries the database.
   * @return
   *   Type you want to build with data obtained from ResultSet
   */
  def consume(resultSet: ResultSet): F[T]

object ResultSetConsumer:

  type Read[T] = ResultSet => T

  given [F[_]: Monad, T](using
    consumer: ResultSetConsumer[F, Option[T]],
    error:    MonadError[F, Throwable]
  ): ResultSetConsumer[F, T] with
    override def consume(resultSet: ResultSet): F[T] =
      consumer.consume(resultSet).flatMap {
        case Some(value) => error.pure(value)
        case None        => error.raiseError(new NoSuchElementException(""))
      }

  given [F[_]: Monad, T](using decoder: Decoder[T]): ResultSetConsumer[F, Option[T]] with
    override def consume(resultSet: ResultSet): F[Option[T]] =
      if resultSet.next() then Monad[F].pure(decoder.decode(resultSet, None).some) else Monad[F].pure(None)

  given [F[_]: Monad, T, G[_]](using
    decoder:       Decoder[T],
    factoryCompat: FactoryCompat[T, G[T]]
  ): ResultSetConsumer[F, G[T]] with
    override def consume(resultSet: ResultSet): F[G[T]] =
      val builder = factoryCompat.newBuilder
      while resultSet.next() do builder += decoder.decode(resultSet, None)
      Monad[F].pure(builder.result())




© 2015 - 2024 Weber Informatics LLC | Privacy Policy