Created
November 12, 2016 14:37
-
-
Save TomTriple/d64920c409b55c5ed5ca8f972f1e19fb to your computer and use it in GitHub Desktop.
scala combinator library for db results
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. combinator library for transforming and combining sql results to query result models | |
// 2. usage of library resides at the bottom of this gist | |
package object mapping { | |
type Mapper[+A] = String => A | |
type ToValueClass[+A] = Long => A | |
type ToEnum[+A] = Int => A | |
case class Ops[+A](mapper: Mapper[A]) { | |
def optional() = _optional(mapper) | |
def map[B](f: A => B): Mapper[B] = _map(mapper)(f) | |
def flatMap[B](f: A => Mapper[B]): Mapper[B] = _flatMap(mapper)(f) | |
def log():Mapper[A] = _log(mapper) | |
def apply(on: String) = mapper.apply(on) | |
} | |
implicit def ops[A](a: Mapper[A]) = Ops(a) | |
def _log[A](mapper:Mapper[A]):Mapper[A] = { in => | |
val result = mapper(in) | |
Log.d("MAPPING", "result is: " + result) | |
result | |
} | |
def enum[A](toEnum: ToEnum[A]):Mapper[A] = int().map(toEnum) | |
def controlactiontype():Mapper[ControlActionType.Value] = enum(ControlActionType.apply) | |
def inspectionstatus():Mapper[InspectionStatus.Value] = enum(InspectionStatus.apply) | |
def valueclass[A](toValueClass:ToValueClass[A]):Mapper[A] = long().map(toValueClass) | |
def playgroundId() = valueclass(PlaygroundId.apply) | |
def damageId() = valueclass(DamageId.apply) | |
def damagestatusId() = valueclass(DamageStatusId.apply) | |
def playobjectId() = valueclass(PlayobjectId.apply) | |
def controltaskId() = valueclass(ControltaskId.apply) | |
def damagetypeId() = valueclass(DamagetypeId.apply) | |
def inspectiontype() = enum(InspectionType.apply) | |
def inspectionobjectId() = valueclass(InspectionObjectId.apply) | |
def inspectionobjectdetailId() = valueclass(InspectionObjectDetailId.apply) | |
def controlobjecttypeId() = valueclass(ControlObjectTypeId.apply) | |
def inspectionId() = valueclass(InspectionId.apply) | |
def long(): Mapper[Long] = _.toLong | |
def int(): Mapper[Int] = _.toInt | |
def string(): Mapper[String] = in => in | |
def boolean(): Mapper[Boolean] = { | |
case "FALSE" | "0" => false | |
case "TRUE" | "1" => true | |
} | |
def double():Mapper[Double] = _.toDouble | |
def float():Mapper[Float] = _.toFloat | |
def date(): Mapper[java.sql.Date] = in => java.sql.Date.valueOf(in) | |
def timestamp(): Mapper[java.sql.Timestamp] = in => java.sql.Timestamp.valueOf(in) | |
def bytes():Mapper[Array[Byte]] = _.getBytes | |
def _optional[A](mapper: Mapper[A]): Mapper[Option[A]] = in => Option(in).map(mapper) | |
def _run[A](mapper: Mapper[A], on: String) = mapper(on) | |
def _map[A, B](mapper: Mapper[A])(f: A => B): Mapper[B] = _flatMap(mapper)(f.andThen(unit)) | |
def unit[A](a: A): Mapper[A] = in => a | |
def _flatMap[A, B](mapper: Mapper[A])(f: A => Mapper[B]): Mapper[B] = { in => | |
val value = mapper.apply(in) | |
f(value).apply(in) | |
} | |
class MappingString(str:String) { | |
def ->[T](mapper:Mapper[T]) = mapper.apply(str) | |
} | |
implicit def string2MappingString(str:String) = new MappingString(str) | |
import collection.JavaConversions._ | |
private def results[T](results:GenericRawResults[T]):Seq[T] = { | |
results.getResults | |
} | |
private val dao = DaoInspection.getInstance() | |
object DB { | |
case class WrappedArray(values:Array[String]) { | |
def val0 = values(0) | |
def val1 = values(1) | |
def val2 = values(2) | |
def val3 = values(3) | |
def val4 = values(4) | |
def val5 = values(5) | |
def val6 = values(6) | |
} | |
def select[T](sql: String)(f: WrappedArray => T): Seq[T] = { | |
val result = dao.queryRaw(sql, new RawRowMapper[T] { | |
override def mapRow(columnNames: Array[String], values: Array[String]) = f(WrappedArray(values)) | |
}) | |
results(result) | |
} | |
def executeRaw(sql: String): Int = dao.executeRaw(sql) | |
def block[T](f: => T) = DbHelper.block(new Callable[T] { | |
def call(): T = f | |
}) | |
def run[T](f: => T) = DbHelper.run(new Callable[T] { | |
def call(): T = f | |
}) | |
def transaction[T](f: => T) = DbHelper.transaction(new Callable[T] { | |
def call():T = f | |
}) | |
} | |
} | |
// usage of combinator library | |
def findOverview(playgroundId:PlaygroundId) = { | |
val sql = | |
s""" | |
select i.id, i.name, isc.duedate, insp.startdate is not null and insp.enddate is null as paused | |
from xxx i | |
left join xxx isc on isc.inspectiontype_id = i.id and isc.controlobject_id = ${playgroundId.get} | |
left join xxx insp on insp.controlobject_id = ${playgroundId.get} and insp.inspectiontype_id = i.id and insp.startdate is not null and insp.enddate is null | |
where i.moduleroottype = 1 and i.id <> 5 | |
order by name | |
""" | |
DB.select(sql) { row => | |
ControltypesOverviewDTO( | |
row.val0 -> inspectiontype(), | |
row.val1 -> string(), | |
row.val2 -> date().optional(), | |
row.val3 -> boolean() | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment