as.seek-well_2.9.2.0.2.1.source-code.seekwell.scala Maven / Gradle / Ivy
The newest version!
package com.earldouglas.seekwell
object `package` {
import java.sql.{PreparedStatement,ResultSet,Timestamp}
trait ColumnType[A]
case class StringCT(columnName: String) extends ColumnType[String]
def string(columnName: String): StringCT = StringCT(columnName)
case class IntCT(columnName: String) extends ColumnType[Int]
def int(columnName: String): IntCT = IntCT(columnName)
case class LongCT(columnName: String) extends ColumnType[Long]
def long(columnName: String): LongCT = LongCT(columnName)
case class BytesCT(columnName: String) extends ColumnType[Array[Byte]]
def bytes(columnName: String): BytesCT = BytesCT(columnName)
case class StreamCT(columnName: String) extends ColumnType[java.io.InputStream]
def stream(columnName: String): StreamCT = StreamCT(columnName)
case class TimestampCT(columnName: String) extends ColumnType[Timestamp]
def timestamp(columnName: String): TimestampCT = TimestampCT(columnName)
implicit def richPreparedStatment(stmt: PreparedStatement): RichPreparedStatement = new RichPreparedStatement(stmt)
class RichPreparedStatement(stmt: PreparedStatement) {
def extract[A](a: ColumnType[A]) = new Extractor1[A](stmt, a)
def extract[A,B](a: ColumnType[A], b: ColumnType[B]) = new Extractor2[A, B](stmt, a, b)
def extract[A,B,C](a: ColumnType[A], b: ColumnType[B], c: ColumnType[C]) = new Extractor3[A,B,C](stmt, a, b, c)
def extract[A,B,C,D](a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D]) = new Extractor4[A,B,C,D](stmt, a, b, c, d)
def extract[A,B,C,D,E](a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D], e: ColumnType[E]) = new Extractor5[A,B,C,D,E](stmt, a, b, c, d, e)
def extract[A,B,C,D,E,F](a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D], e: ColumnType[E], f: ColumnType[F]) = new Extractor6[A,B,C,D,E,F](stmt, a, b, c, d, e, f)
def extract[A,B,C,D,E,F,G](a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D], e: ColumnType[E], f: ColumnType[F], g: ColumnType[G]) = new Extractor7[A,B,C,D,E,F,G](stmt, a, b, c, d, e, f, g)
private val index = new java.util.concurrent.atomic.AtomicInteger()
private def bindAndReturn(f: PreparedStatement => Unit): RichPreparedStatement = { f(stmt) ; this }
def bind(value: String) = bindAndReturn( _.setString(index.incrementAndGet(), value))
def bind(value: Int) = bindAndReturn( _.setInt(index.incrementAndGet(), value))
def bind(value: Long) = bindAndReturn( _.setLong(index.incrementAndGet(), value))
def bind(value: Timestamp) = bindAndReturn(_.setTimestamp(index.incrementAndGet(), value))
}
trait Extractor {
def extract[C](rs: ResultSet, columnType: ColumnType[C]): C = columnType match {
case StringCT(columnName) => rs.getString(columnName)
case IntCT(columnName) => rs.getInt(columnName)
case LongCT(columnName) => rs.getLong(columnName)
case BytesCT(columnName) => rs.getBytes(columnName)
case StreamCT(columnName) => rs.getBinaryStream(columnName)
case TimestampCT(columnName) => rs.getTimestamp(columnName)
}
}
class Extractor1[A](stmt: PreparedStatement, a: ColumnType[A]) extends Extractor {
def iterator(): Iterator[A] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[A](stmt, rs, rs => extract[A](rs, a))
}
}
class Extractor2[A, B](stmt: PreparedStatement, a: ColumnType[A], b: ColumnType[B]) extends Extractor {
def iterator(): Iterator[Tuple2[A, B]] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[Tuple2[A, B]](stmt, rs, rs => (extract[A](rs, a), extract[B](rs, b)))
}
}
class Extractor3[A, B, C](stmt: PreparedStatement, a: ColumnType[A], b: ColumnType[B], c: ColumnType[C]) extends Extractor {
def iterator(): Iterator[Tuple3[A, B, C]] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[Tuple3[A, B, C]](stmt, rs, rs => (extract[A](rs, a), extract[B](rs, b), extract[C](rs, c)))
}
}
class Extractor4[A,B,C,D](stmt: PreparedStatement, a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D]) extends Extractor {
def iterator(): Iterator[Tuple4[A,B,C,D]] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[Tuple4[A,B,C,D]](stmt, rs, rs => (extract[A](rs, a), extract[B](rs, b), extract[C](rs, c), extract[D](rs, d)))
}
}
class Extractor5[A,B,C,D,E](stmt: PreparedStatement, a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D], e: ColumnType[E]) extends Extractor {
def iterator(): Iterator[Tuple5[A,B,C,D,E]] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[Tuple5[A,B,C,D,E]](stmt, rs, rs => (extract[A](rs, a), extract[B](rs, b), extract[C](rs, c), extract[D](rs, d), extract[E](rs, e)))
}
}
class Extractor6[A,B,C,D,E,F](stmt: PreparedStatement, a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D], e: ColumnType[E], f: ColumnType[F]) extends Extractor {
def iterator(): Iterator[Tuple6[A,B,C,D,E,F]] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[Tuple6[A,B,C,D,E,F]](stmt, rs, rs => (extract[A](rs, a), extract[B](rs, b), extract[C](rs, c), extract[D](rs, d), extract[E](rs, e), extract[F](rs, f)))
}
}
class Extractor7[A,B,C,D,E,F,G](stmt: PreparedStatement, a: ColumnType[A], b: ColumnType[B], c: ColumnType[C], d: ColumnType[D], e: ColumnType[E], f: ColumnType[F], g: ColumnType[G]) extends Extractor {
def iterator(): Iterator[Tuple7[A,B,C,D,E,F,G]] = {
val rs: ResultSet = stmt.executeQuery()
new RSIterator[Tuple7[A,B,C,D,E,F,G]](stmt, rs, rs => (extract[A](rs, a), extract[B](rs, b), extract[C](rs, c), extract[D](rs, d), extract[E](rs, e), extract[F](rs, f), extract[G](rs, g)))
}
}
class RSIterator[A](stmt: PreparedStatement, rs: ResultSet, f: ResultSet => A) extends Iterator[A] {
private var moreResults: Boolean = rs.next()
def hasNext(): Boolean = synchronized(moreResults)
def next(): A = synchronized {
val a = f(rs)
if (hasNext()) {
moreResults = rs.next()
} else {
rs.close()
stmt.close()
}
a
}
def remove(): Unit = throw new java.lang.UnsupportedOperationException()
}
}