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

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

The newest version!
package com.lucidchart.relate

import java.nio.ByteBuffer
import java.sql.ResultSet
import java.time.Instant
import java.util.{Date, UUID}

class NullColumnException(col: String) extends Exception(s"Unexpected null value in column: $col")

trait ColReader[A] { self =>
  def read(col: String, row: SqlRow): Option[A]

  def forceRead(col: String, row: SqlRow): A = {
    read(col, row).getOrElse {
      throw new NullColumnException(col)
    }
  }

  def map[B](f: A => B): ColReader[B] = ColReader[B] { (col, rs) =>
    self.read(col, rs).map(f)
  }

  def flatMap[B](f: A => ColReader[B]): ColReader[B] = ColReader[B] { (col, rs) =>
    self.read(col, rs) match {
      case Some(a) => f(a).read(col, rs)
      case None => None
    }
  }

  def filter(f: A => Boolean): ColReader[A] =
    ColReader[A] { (col, rs) => self.read(col, rs).filter(f) }
}

object ColReader {
  def apply[A](f: (String, SqlRow) => Option[A]): ColReader[A] = new ColReader[A] {
    def read(col: String, rs: SqlRow): Option[A] = f(col, rs)
  }

  def option[A](x: A, rs: ResultSet): Option[A] = {
    if (rs.wasNull()) {
      None
    } else {
      Some(x)
    }
  }

  private def optReader[A](f: (String, ResultSet) => A): ColReader[A] = ColReader[A] { (col, row) =>
    option(f(col, row.resultSet), row.resultSet)
  }

  implicit val jbigDecimalReader: ColReader[java.math.BigDecimal] = ColReader[java.math.BigDecimal] { (col, row) =>
    option(row.resultSet.getBigDecimal(col), row.resultSet)
  }

  implicit val bigDecimalReader: ColReader[BigDecimal] = jbigDecimalReader.map(BigDecimal(_))

  implicit val bigIntReader: ColReader[BigInt] = jbigDecimalReader.map(bd => BigInt(bd.longValue))

  implicit val boolReader: ColReader[Boolean] = optReader((col, rs) => rs.getBoolean(col))
  implicit val byteArrayReader: ColReader[Array[Byte]] = optReader((col, rs) => rs.getBytes(col))
  implicit val byteReader: ColReader[Byte] = optReader((col, rs) => rs.getByte(col))
  implicit val dateReader: ColReader[Date] = optReader((col, rs) => rs.getDate(col))
  implicit val instantReader: ColReader[Instant] = optReader((col, rs) => rs.getTimestamp(col)).map(_.toInstant)
  implicit val doubleReader: ColReader[Double] = optReader((col, rs) => rs.getDouble(col))
  implicit val intReader: ColReader[Int] = optReader((col, rs) => rs.getInt(col))
  implicit val longReader: ColReader[Long] = optReader((col, rs) => rs.getLong(col))
  implicit val shortReader: ColReader[Short] = optReader((col, rs) => rs.getShort(col))
  implicit val stringReader: ColReader[String] = optReader((col, rs) => rs.getString(col))
  implicit val uuidReader: ColReader[UUID] = ColReader[UUID] { (col, row) =>
    row.uuidOption(col)
  }

  def enumReader[A <: Enumeration](e: A): ColReader[e.Value] = {
    intReader.flatMap(id => ColReader[e.Value] { (_, _) =>
      e.values.find(_.id == id)
    })
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy