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

com.lucidchart.relate.RowParser.scala Maven / Gradle / Ivy

The newest version!
package com.lucidchart.relate

import java.util.Date
import java.time.Instant
import scala.collection.generic.CanBuildFrom
import scala.collection.mutable
import scala.language.higherKinds

trait RowParser[A] extends (SqlRow => A) {
  def parse(row: SqlRow): A

  def apply(row: SqlRow) = parse(row)
}

object RowParser {
  def apply[A](f: (SqlRow) => A) = new RowParser[A] {
    def parse(row: SqlRow) = f(row)
  }

  def bigInt(columnLabel: String) = RowParser(_.apply[BigInt](columnLabel))
  def date(columnLabel: String) = RowParser(_.apply[Date](columnLabel))
  def instant(columnLabel: String) = RowParser(_.apply[Instant](columnLabel))
  def int(columnLabel: String) = RowParser(_.apply[Int](columnLabel))
  def long(columnLabel: String) = RowParser(_.apply[Long](columnLabel))
  def string(columnLabel: String) = RowParser(_.apply[String](columnLabel))

  private[relate] val insertInt = (row: SqlRow) => row.strictInt(1)
  private[relate] val insertLong = (row: SqlRow) => row.strictLong(1)

  def limitedCollection[B: RowParser, Col[_]](maxRows: Long)(implicit cbf: CanBuildFrom[Col[B], B, Col[B]]) =
    RowParser { result =>
      val builder = cbf()

      result.withResultSet { resultSet =>
        while (resultSet.getRow < maxRows && resultSet.next()) {
          builder += implicitly[RowParser[B]].parse(result)
        }
      }

      builder.result
    }

  implicit def option[B: RowParser] = RowParser[Option[B]] { result =>
    limitedCollection[B, List](1).parse(result).headOption
  }

  implicit def collection[B: RowParser, Col[_]](implicit cbf: CanBuildFrom[Col[B], B, Col[B]]) =
    limitedCollection[B, Col](Long.MaxValue)

  implicit def pairCollection[Key: RowParser, Value: RowParser, PairCol[_, _]]
    (implicit cbf: CanBuildFrom[PairCol[Key, Value], (Key, Value), PairCol[Key, Value]]) =
    RowParser { result =>

      val builder = cbf()

      result.withResultSet { resultSet =>
        while (resultSet.getRow < Long.MaxValue && resultSet.next()) {
          builder += implicitly[RowParser[Key]].parse(result) -> implicitly[RowParser[Value]].parse(result)
        }
      }

      builder.result
    }

  implicit def multiMap[Key: RowParser, Value: RowParser] = RowParser[Map[Key, Set[Value]]] { result =>
    val mm: mutable.Map[Key, Set[Value]] = new mutable.HashMap[Key, Set[Value]]

    result.withResultSet { resultSet =>
      while (resultSet.next()) {
        val key = implicitly[RowParser[Key]].parse(result)
        val value = implicitly[RowParser[Value]].parse(result)

        mm.get(key).map { foundValue =>
          mm += (key -> (foundValue + value))
        }.getOrElse {
          mm += (key -> Set(value))
        }
      }
    }
    mm.toMap
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy