Skip to content

Instantly share code, notes, and snippets.

@ludovicc
Created December 7, 2017 11:17
Show Gist options
  • Save ludovicc/ff7bc61754fea00d0846e7dbc3feded4 to your computer and use it in GitHub Desktop.
Save ludovicc/ff7bc61754fea00d0846e7dbc3feded4 to your computer and use it in GitHub Desktop.
package eu.hbp.mip.woken.dao
import java.sql.{ Connection, DriverManager, ResultSet, ResultSetMetaData }
import java.time.{ OffsetDateTime, ZoneOffset }
import cats.Monad
import doobie.util.transactor.Transactor
import eu.hbp.mip.woken.config.DbConnectionConfiguration
import spray.json._
import eu.hbp.mip.woken.core.model._
import eu.hbp.mip.woken.json.yaml
import eu.hbp.mip.woken.json.yaml.Yaml
/**
* Data Access Layer
*/
trait DAL {}
object Shapes {
val error = "error"
val pfa_json = "pfa_json"
val pfa_experiment_json = "pfa_experiment_json"
val pfa_yaml = "pfa_yaml"
val html = "html"
val svg = "svg"
val highcharts = "highcharts"
val highcharts_mime = "application/highcharts+json"
}
object JobResultsDAO {
import Shapes._
import doobie._
import doobie.implicits._
implicit val DateTimeMeta: Meta[OffsetDateTime] =
Meta[java.sql.Timestamp].xmap(ts => OffsetDateTime.of(ts.toLocalDateTime, ZoneOffset.UTC),
dt => java.sql.Timestamp.valueOf(dt.toLocalDateTime))
type JobResultColumns =
(String, String, OffsetDateTime, String, String, Option[String], Option[String])
// TODO: read experiments
private val unsafeFromColumns: JobResultColumns => JobResult = {
case (jobId, node, timestamp, _, function, _, Some(errorMessage)) =>
ErrorJobResult(jobId, node, timestamp, function, errorMessage)
case (jobId, node, timestamp, shape, function, Some(data), None) if shape == pfa_json =>
PfaJobResult(jobId, node, timestamp, function, data.parseJson.asJsObject)
case (jobId, node, timestamp, shape, _, Some(data), None) if shape == pfa_experiment_json =>
PfaExperimentJobResult(jobId, node, timestamp, data.parseJson.asInstanceOf[JsArray])
case (jobId, node, timestamp, shape, function, Some(data), None) if shape == pfa_yaml =>
PfaJobResult(jobId, node, timestamp, function, yaml.yaml2Json(Yaml(data)).asJsObject)
case (jobId, node, timestamp, shape, function, Some(data), None) if shape == highcharts =>
JsonDataJobResult(jobId, node, timestamp, shape, function, data.parseJson.asJsObject)
case (jobId, node, timestamp, shape, function, Some(data), None)
if shape == svg || shape == html =>
OtherDataJobResult(jobId, node, timestamp, shape, function, data)
case (_, _, _, shape, _, _, _) =>
throw new IllegalArgumentException(s"Cannot handle job results of shape $shape")
}
private val jobResultToColumns: JobResult => JobResultColumns = {
case j: PfaJobResult =>
(j.jobId, j.node, j.timestamp, pfa_json, j.function, Some(j.model.compactPrint), None)
case j: PfaExperimentJobResult =>
(j.jobId,
j.node,
j.timestamp,
pfa_experiment_json,
j.function,
Some(j.models.compactPrint),
None)
case j: ErrorJobResult =>
(j.jobId, j.node, j.timestamp, pfa_json, j.function, None, Some(j.error))
case j: JsonDataJobResult =>
(j.jobId, j.node, j.timestamp, j.shape, j.function, Some(j.data.compactPrint), None)
case j: OtherDataJobResult =>
(j.jobId, j.node, j.timestamp, j.shape, j.function, Some(j.data), None)
}
// TODO: need to master Doobie...
//implicit val JobResultMeta: Meta[JobResult] =
// Meta[JobResultColumns].xmap(unsafeFromColumns, jobResultToColumns)
def queryJobResults(jobId: String): ConnectionIO[List[JobResult]] =
sql"select job_id, node, timestamp, shape, function, data, error from job_result where job_id = $jobId"
.query[JobResultColumns]
.list
.map(_.map(unsafeFromColumns))
}
trait JobResultsDAL extends DAL {
def findJobResults(jobId: String): List[JobResult]
}
class NodeDAL[M: Monad](xa: Transactor[M]) extends JobResultsDAL {
import doobie.implicits._
override def findJobResults(jobId: String) =
JobResultsDAO.queryJobResults(jobId).transact(xa).unsafePerformIO
}
@ludovicc
Copy link
Author

ludovicc commented Dec 7, 2017

[error] /home/ludovic/Projects/algorithm-factory/woken/src/main/scala/eu/hbp/mip/woken/dao/DAL.scala:119: ambiguous implicit values:
[error] both value AsyncBlobIO in trait Instances of type => cats.effect.Async[doobie.free.BlobIO]
[error] and value AsyncCallableStatementIO in trait Instances of type => cats.effect.Async[doobie.free.CallableStatementIO]
[error] match expected type cats.Monad[M]
[error] JobResultsDAO.queryJobResults(jobId).transact(xa).unsafePerformIO
[error]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment