Skip to content

Commit

Permalink
Added support for Oracle via Doobie
Browse files Browse the repository at this point in the history
  • Loading branch information
milessabin committed Oct 5, 2024
1 parent 85a3df4 commit 0e383de
Show file tree
Hide file tree
Showing 150 changed files with 7,079 additions and 552 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ jobs:
- name: Check Headers
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' headerCheckAll

- name: Start up Postgres, Oracle
run: docker compose up --force-recreate -d --wait --quiet-pull

- name: Check headers
if: matrix.java == 'temurin@11' && matrix.os == 'ubuntu-latest'
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' headerCheckAll
Expand All @@ -87,11 +90,11 @@ jobs:

- name: Make target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
run: mkdir -p modules/skunk/js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-pg/target unidocs/target modules/core/.native/target modules/sql/js/target modules/skunk/jvm/target modules/core/.js/target modules/circe/.js/target modules/sql/native/target modules/skunk/native/target modules/generic/.js/target modules/core/.jvm/target modules/sql/jvm/target modules/circe/.native/target modules/generic/.native/target project/target
run: mkdir -p modules/skunk/js/target modules/sql-core/.js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-pg/target unidocs/target modules/core/.native/target modules/skunk/jvm/target modules/core/.js/target modules/doobie-core/target modules/circe/.js/target modules/skunk/native/target modules/generic/.js/target modules/doobie-oracle/target modules/sql-core/.jvm/target modules/core/.jvm/target modules/sql-pg/native/target modules/sql-pg/js/target modules/circe/.native/target modules/generic/.native/target modules/sql-pg/jvm/target modules/sql-core/.native/target project/target

- name: Compress target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
run: tar cf targets.tar modules/skunk/js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-pg/target unidocs/target modules/core/.native/target modules/sql/js/target modules/skunk/jvm/target modules/core/.js/target modules/circe/.js/target modules/sql/native/target modules/skunk/native/target modules/generic/.js/target modules/core/.jvm/target modules/sql/jvm/target modules/circe/.native/target modules/generic/.native/target project/target
run: tar cf targets.tar modules/skunk/js/target modules/sql-core/.js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-pg/target unidocs/target modules/core/.native/target modules/skunk/jvm/target modules/core/.js/target modules/doobie-core/target modules/circe/.js/target modules/skunk/native/target modules/generic/.js/target modules/doobie-oracle/target modules/sql-core/.jvm/target modules/core/.jvm/target modules/sql-pg/native/target modules/sql-pg/js/target modules/circe/.native/target modules/generic/.native/target modules/sql-pg/jvm/target modules/sql-core/.native/target project/target

- name: Upload target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
Expand Down
136 changes: 105 additions & 31 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import nl.zolotko.sbt.jfr.{JfrRecording, JfrRecorderOptions}
import scala.concurrent.duration.DurationInt
import scala.sys.process._

val catsVersion = "2.11.0"
val catsParseVersion = "1.0.0"
Expand All @@ -17,20 +18,21 @@ val log4catsVersion = "2.7.0"
val munitVersion = "1.0.0-M11"
val munitCatsEffectVersion = "2.0.0"
val munitScalaCheckVersion = "1.0.0-M11"
val oracleDriverVersion = "23.5.0.24.07"
val skunkVersion = "0.6.4"
val shapeless2Version = "2.3.11"
val shapeless3Version = "3.4.1"
val sourcePosVersion = "1.1.0"
val typenameVersion = "1.1.0"
val whaleTailVersion = "0.0.12"

val Scala2 = "2.13.15"
val Scala3 = "3.3.4"

ThisBuild / scalaVersion := Scala2
ThisBuild / crossScalaVersions := Seq(Scala2, Scala3)
ThisBuild / tlJdkRelease := Some(11)

ThisBuild / tlBaseVersion := "0.22"
ThisBuild / tlBaseVersion := "0.23"
ThisBuild / startYear := Some(2019)
ThisBuild / licenses := Seq(License.Apache2)
ThisBuild / developers := List(
Expand All @@ -42,10 +44,16 @@ ThisBuild / tlFatalWarnings := true
ThisBuild / tlCiScalafmtCheck := false
ThisBuild / tlCiReleaseBranches := Seq("main")
ThisBuild / githubWorkflowBuild ~= { steps =>
WorkflowStep.Sbt(
commands = List("headerCheckAll"),
name = Some("Check Headers"),
) +: steps
Seq(
WorkflowStep.Sbt(
commands = List("headerCheckAll"),
name = Some("Check Headers")
),
WorkflowStep.Run(
commands = List("docker compose up --force-recreate -d --wait --quiet-pull"),
name = Some("Start up Postgres, Oracle")
)
) ++ steps
}
ThisBuild / githubWorkflowJavaVersions := Seq(JavaSpec.temurin("11"))
ThisBuild / tlBspCrossProjectPlatforms := Set(JVMPlatform)
Expand All @@ -66,6 +74,20 @@ ThisBuild / githubWorkflowAddedJobs +=

ThisBuild / tlSitePublishBranch := Some("main")

lazy val allUp = taskKey[Unit]("Start all docker compose services")
lazy val allStop = taskKey[Unit]("Stop all docker compose services")
lazy val pgUp = taskKey[Unit]("Start Postgres")
lazy val pgStop = taskKey[Unit]("Stop Postgres")
lazy val oracleUp = taskKey[Unit]("Start Oracle")
lazy val oracleStop = taskKey[Unit]("Stop Oracle")

ThisBuild / allUp := "docker compose up -d --wait --quiet-pull".!
ThisBuild / allStop := "docker compose stop".!
ThisBuild / pgUp := "docker compose up -d --wait --quiet-pull postgres".!
ThisBuild / pgStop := "docker compose stop postgres".!
ThisBuild / oracleUp := "docker compose up -d --wait --quiet-pull oracle".!
ThisBuild / oracleStop := "docker compose stop oracle".!

lazy val commonSettings = Seq(
//scalacOptions --= Seq("-Wunused:params", "-Wunused:imports", "-Wunused:patvars", "-Wdead-code", "-Wunused:locals", "-Wunused:privates", "-Wunused:implicits"),
scalacOptions ++= Seq("-Xlint:-pattern-shadow").filterNot(_ => tlIsScala3.value),
Expand Down Expand Up @@ -103,8 +125,11 @@ lazy val commonSettings = Seq(
lazy val modules: List[CompositeProject] = List(
core,
circe,
sql,
doobie,
sqlcore,
sqlpg,
doobiecore,
doobiepg,
doobieoracle,
skunk,
generic,
docs,
Expand Down Expand Up @@ -162,46 +187,85 @@ lazy val buildInfo = crossProject(JVMPlatform, JSPlatform, NativePlatform)
buildInfoKeys += "baseDirectory" -> (LocalRootProject / baseDirectory).value.toString
)

lazy val sql = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.crossType(CrossType.Full)
.in(file("modules/sql"))
lazy val sqlcore = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.crossType(CrossType.Pure)
.in(file("modules/sql-core"))
.enablePlugins(AutomateHeaderPlugin)
.disablePlugins(RevolverPlugin)
.dependsOn(core % "test->test;compile->compile", circe, buildInfo % Test)
.settings(commonSettings)
.settings(
name := "grackle-sql",
name := "grackle-sql-core",
libraryDependencies ++= Seq(
"io.circe" %%% "circe-generic" % circeVersion % "test",
"co.fs2" %%% "fs2-io" % fs2Version % "test",
)
)
.platformsSettings(JVMPlatform, JSPlatform)(
.jvmSettings(
libraryDependencies ++= Seq(
"io.chrisdavenport" %%% "whale-tail-manager" % whaleTailVersion % "test",
"com.github.jnr" % "jnr-unixsocket" % jnrUnixsocketVersion % "test"
)
)
.jvmSettings(

lazy val sqlpg = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.crossType(CrossType.Full)
.in(file("modules/sql-pg"))
.enablePlugins(AutomateHeaderPlugin)
.disablePlugins(RevolverPlugin)
.dependsOn(sqlcore % "test->test;compile->compile", circe)
.settings(commonSettings)
.settings(
name := "grackle-sql-pg",
)

lazy val doobiecore = project
.in(file("modules/doobie-core"))
.enablePlugins(AutomateHeaderPlugin)
.disablePlugins(RevolverPlugin)
.dependsOn(sqlcore.jvm % "test->test;compile->compile", circe.jvm)
.settings(commonSettings)
.settings(
name := "grackle-doobie-core",
Test / fork := true,
Test / parallelExecution := false,
libraryDependencies ++= Seq(
"com.github.jnr" % "jnr-unixsocket" % jnrUnixsocketVersion % "test"
"org.tpolecat" %% "doobie-core" % doobieVersion,
"org.typelevel" %% "log4cats-core" % log4catsVersion,
"ch.qos.logback" % "logback-classic" % logbackVersion % "test",
// TODO: Needed temporarily for Metas in DoobieDatabaseSuite
"org.tpolecat" %% "doobie-postgres-circe" % doobieVersion % "test"
)
)

lazy val doobie = project
lazy val doobiepg = project
.in(file("modules/doobie-pg"))
.enablePlugins(AutomateHeaderPlugin)
.disablePlugins(RevolverPlugin)
.dependsOn(sql.jvm % "test->test;compile->compile", circe.jvm)
.dependsOn(doobiecore % "test->test;compile->compile", sqlpg.jvm % "test->test;compile->compile")
.settings(commonSettings)
.settings(
name := "grackle-doobie-pg",
Test / fork := true,
Test / parallelExecution := false,
Test / testOptions += Tests.Setup(_ => "docker compose up -d --wait --quiet-pull postgres".!),
libraryDependencies ++= Seq(
"org.tpolecat" %% "doobie-postgres-circe" % doobieVersion
)
)

lazy val doobieoracle = project
.in(file("modules/doobie-oracle"))
.enablePlugins(AutomateHeaderPlugin)
.disablePlugins(RevolverPlugin)
.dependsOn(doobiecore % "test->test;compile->compile")
.settings(commonSettings)
.settings(
name := "grackle-doobie-oracle",
Test / fork := true,
Test / parallelExecution := false,
Test / testOptions += Tests.Setup(_ => "docker compose up -d --wait --quiet-pull oracle".!),
libraryDependencies ++= Seq(
"org.tpolecat" %% "doobie-core" % doobieVersion,
"org.tpolecat" %% "doobie-postgres-circe" % doobieVersion,
"org.typelevel" %% "log4cats-core" % log4catsVersion,
"ch.qos.logback" % "logback-classic" % logbackVersion % "test"
"com.oracle.database.jdbc" % "ojdbc8" % oracleDriverVersion
)
)

Expand All @@ -210,7 +274,7 @@ lazy val skunk = crossProject(JVMPlatform, JSPlatform, NativePlatform)
.in(file("modules/skunk"))
.enablePlugins(AutomateHeaderPlugin)
.disablePlugins(RevolverPlugin)
.dependsOn(sql % "test->test;compile->compile", circe)
.dependsOn(sqlpg % "test->test;compile->compile", circe)
.settings(commonSettings)
.settings(
name := "grackle-skunk",
Expand All @@ -223,6 +287,7 @@ lazy val skunk = crossProject(JVMPlatform, JSPlatform, NativePlatform)
)
.jvmSettings(
Test / fork := true,
Test / testOptions += Tests.Setup(_ => "docker compose up -d --wait --quiet-pull postgres".!),
libraryDependencies ++= Seq(
"ch.qos.logback" % "logback-classic" % logbackVersion % "test"
)
Expand All @@ -247,10 +312,12 @@ lazy val generic = crossProject(JVMPlatform, JSPlatform, NativePlatform)
})
)

import spray.revolver.Actions._

lazy val demo = project
.in(file("demo"))
.enablePlugins(NoPublishPlugin, AutomateHeaderPlugin)
.dependsOn(buildInfo.jvm, core.jvm, generic.jvm, doobie)
.dependsOn(buildInfo.jvm, core.jvm, generic.jvm, doobiepg)
.settings(commonSettings)
.settings(
name := "grackle-demo",
Expand All @@ -265,25 +332,29 @@ lazy val demo = project
"org.http4s" %% "http4s-ember-client" % http4sVersion,
"org.http4s" %% "http4s-circe" % http4sVersion,
"org.http4s" %% "http4s-dsl" % http4sVersion,
"io.chrisdavenport" %% "whale-tail-manager" % whaleTailVersion,
"com.github.jnr" % "jnr-unixsocket" % jnrUnixsocketVersion
)
),
reStart := // Redefine reStart to depend on pgUp
Def.inputTask(reStart.evaluated)
.dependsOn(Compile / products)
.dependsOn(ThisBuild / pgUp)
.evaluated
)

lazy val benchmarks = project
.in(file("benchmarks"))
.dependsOn(core.jvm)
.enablePlugins(NoPublishPlugin, AutomateHeaderPlugin, JmhPlugin)
.settings(commonSettings)
.settings(
.settings(
coverageEnabled := false,
)
)

lazy val profile = project
.in(file("profile"))
.enablePlugins(NoPublishPlugin, AutomateHeaderPlugin)
.dependsOn(core.jvm)
.dependsOn(doobie)
.dependsOn(doobiepg)
.settings(commonSettings)
.settings(
jfrRecordings := Seq(
Expand Down Expand Up @@ -338,8 +409,11 @@ lazy val unidocs = project
ScalaUnidoc / unidoc / unidocProjectFilter := inProjects(
core.jvm,
circe.jvm,
sql.jvm,
doobie,
sqlcore.jvm,
sqlpg.jvm,
doobiecore,
doobiepg,
doobieoracle,
skunk.jvm,
generic.jvm,
)
Expand Down
34 changes: 0 additions & 34 deletions demo/src/main/scala/demo/world/WorldData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,11 @@ package demo.world
import java.util.concurrent.Executors

import scala.concurrent.ExecutionContext
import scala.concurrent.duration._

import cats.effect.{Async, Resource}
import cats.syntax.all._
import doobie.hikari.HikariTransactor
import io.chrisdavenport.whaletail.{Containers, Docker}
import io.chrisdavenport.whaletail.manager._

object WorldData {
def mkContainer[F[_]: Async]: Resource[F, PostgresConnectionInfo] =
Docker.default[F].flatMap(client =>
WhaleTailContainer.build(
client,
image = "postgres",
tag = "11.8".some,
ports = Map(PostgresConnectionInfo.DefaultPort -> None),
binds = List(Containers.Bind(bindPath("demo/src/main/resources/db/"), "/docker-entrypoint-initdb.d/", "ro")),
env = Map(
"POSTGRES_USER" -> "test",
"POSTGRES_PASSWORD" -> "test",
"POSTGRES_DB" -> "test"
),
labels = Map.empty
).evalTap(
ReadinessStrategy.checkReadiness(
client,
_,
ReadinessStrategy.LogRegex(".*database system is ready to accept connections.*".r, 2),
30.seconds
)
)
).flatMap(container =>
Resource.eval(
container.ports.get(PostgresConnectionInfo.DefaultPort).liftTo[F](new Throwable("Missing Port"))
)
).map {
case (host, port) => PostgresConnectionInfo(host, port)
}

def mkTransactor[F[_]: Async](connInfo: PostgresConnectionInfo): Resource[F, HikariTransactor[F]] = {
import connInfo._
HikariTransactor.newHikariTransactor[F](
Expand Down
12 changes: 7 additions & 5 deletions demo/src/main/scala/demo/world/WorldMapping.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ import grackle.Query._
import grackle.QueryCompiler._
import grackle.Value._
import grackle._
import grackle.doobie.postgres.{DoobieMapping, DoobieMonitor, LoggedDoobieMappingCompanion}
import grackle.doobie.{DoobieMonitor, LoggedDoobieMappingCompanion}
import grackle.doobie.postgres.{DoobiePgMapping}
import grackle.sql.Like
import grackle.syntax._
import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger

import WorldData._

trait WorldMapping[F[_]] extends DoobieMapping[F] {
trait WorldMapping[F[_]] extends DoobiePgMapping[F] {
// #db_tables
object country extends TableDef("country") {
val code = col("code", Meta[String])
Expand Down Expand Up @@ -230,17 +231,18 @@ trait WorldMapping[F[_]] extends DoobieMapping[F] {

object WorldMapping extends LoggedDoobieMappingCompanion {
def mkMapping[F[_]: Sync](transactor: Transactor[F], monitor: DoobieMonitor[F]): WorldMapping[F] =
new DoobieMapping(transactor, monitor) with WorldMapping[F]
new DoobiePgMapping(transactor, monitor) with WorldMapping[F]

def mkMappingFromTransactor[F[_]: Sync](transactor: Transactor[F]): WorldMapping[F] = {
val logger: Logger[F] = Slf4jLogger.getLoggerFromName[F]("SqlQueryLogger")
val monitor: DoobieMonitor[F] = DoobieMonitor.loggerMonitor[F](logger)
mkMapping(transactor, monitor)
}

def apply[F[_]: Async]: Resource[F, WorldMapping[F]] =
def apply[F[_]: Async]: Resource[F, WorldMapping[F]] = {
val connInfo = PostgresConnectionInfo("localhost", PostgresConnectionInfo.DefaultPort)
for {
connInfo <- mkContainer[F]
transactor <- mkTransactor[F](connInfo)
} yield mkMappingFromTransactor[F](transactor)
}
}
Loading

0 comments on commit 0e383de

Please sign in to comment.