Skip to content

Instantly share code, notes, and snippets.

@afsalthaj
Created September 5, 2021 08:41
Show Gist options
  • Save afsalthaj/c6475fdbfb99fd9f4816c1d3696c7875 to your computer and use it in GitHub Desktop.
Save afsalthaj/c6475fdbfb99fd9f4816c1d3696c7875 to your computer and use it in GitHub Desktop.
package metrics
import java.sql.ResultSet
/**
* A highly simplified functional jdbc with no dependencies.
* Serves the purpose for the time being. Currently returns scala.Stream.
*/
object myjdbc {
trait Primitive[A] {
def get: ResultSet => Int => A
}
object Primitive {
def apply[A](implicit ev: Primitive[A]): Primitive[A] = ev
implicit val primaryVarChar: Primitive[String] = new Primitive[String] {
override def get: ResultSet => Int => String = _.getString
}
implicit val primaryInt: Primitive[Int] = new Primitive[Int] {
override def get: ResultSet => Int => Int = _.getInt
}
implicit val primaryLong: Primitive[Long] = new Primitive[Long] {
override def get: ResultSet => Int => Long = _.getLong
}
implicit val primaryDouble: Primitive[Double] = new Primitive[Double] {
override def get: ResultSet => Int => Double = _.getDouble
}
}
import resultset._
trait MultiColSelector[A] { outer =>
def get: State[RowState, A]
def map[B](f: A => B): MultiColSelector[B] =
new MultiColSelector[B] {
def get: State[RowState, B] =
outer.get.map(f)
}
}
object MultiColSelector {
def apply[A](implicit A: MultiColSelector[A]): MultiColSelector[A] = A
def readPrimitive[A](n: Int)(implicit A: Primitive[A]): ResultSet => A = { (rs: ResultSet) =>
A.get(rs)(n)
}
implicit def prim[A: Primitive]: MultiColSelector[A] =
new MultiColSelector[A] {
def get: State[RowState, A] = State { s =>
val newState = RowState(s.rs, s.columnIndex + 1)
val result = readPrimitive(s.columnIndex)(Primitive[A])(s.rs)
(newState, result)
}
}
implicit def tuple[A: MultiColSelector, B: MultiColSelector]: MultiColSelector[(A, B)] =
new MultiColSelector[(A, B)] {
override def get: State[RowState, (A, B)] =
MultiColSelector[A].get.flatMap(a => MultiColSelector[B].get.map(b => (a, b)))
}
}
final case class State[S, A](f: S => (S, A)) {
def map[B](g: A => B): State[S, B] = State { s =>
val (s1, a) = f(s)
(s1, g(a))
}
def flatMap[B](g: A => State[S, B]): State[S, B] =
State { s =>
val (s1, a) = f(s)
val s2 = g(a)
s2.f(s1)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment