-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
765da6c
commit cfc719f
Showing
8 changed files
with
268 additions
and
10 deletions.
There are no files selected for viewing
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
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
34 changes: 34 additions & 0 deletions
34
core/src/main/scala/io/github/gaelrenoux/tranzactio/DatabaseTBase.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package io.github.gaelrenoux.tranzactio | ||
|
||
import zio.{Trace, ZEnvironment, ZIO, ZLayer, Tag} | ||
|
||
/** | ||
* This is a typed database, to use when you have multiple databases in your application. Simply provide a marker type, | ||
* and ZIO will be able to differentiate between multiple DatabaseT[_] types in your environment. | ||
* @tparam M Marker type, no instances. */ | ||
class DatabaseTBase[M: Tag, Connection](underlying: DatabaseOps.ServiceOps[Connection]) extends DatabaseOps.ServiceOps[Connection] { | ||
|
||
override def transaction[R, E, A](task: => ZIO[Connection with R, E, A], commitOnFailure: => Boolean) | ||
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R with Any, Either[DbException, E], A] = | ||
underlying.transaction[R, E, A](task, commitOnFailure = commitOnFailure) | ||
|
||
|
||
override def autoCommit[R, E, A](task: => ZIO[Connection with R, E, A]) | ||
(implicit errorStrategies: ErrorStrategiesRef, trace: Trace): ZIO[R with Any, Either[DbException, E], A] = | ||
underlying.autoCommit[R, E, A](task) | ||
|
||
} | ||
|
||
object DatabaseTBase { | ||
trait Companion[Connection, DbContext] { | ||
type Module[M] = DatabaseTBase.Module[M, Connection, DbContext] | ||
|
||
def apply[M: Tag]: Module[M] | ||
} | ||
|
||
class Module[M: Tag, Connection: Tag, DbContext](underlying: DatabaseModuleBase[Connection, DatabaseOps.ServiceOps[Connection], DbContext]) | ||
extends DatabaseModuleBase[Connection, DatabaseTBase[M, Connection], DbContext] { | ||
override def fromConnectionSource(implicit dbContext: DbContext, trace: Trace): ZLayer[ConnectionSource, Nothing, DatabaseTBase[M, Connection]] = | ||
underlying.fromConnectionSource.map(env => ZEnvironment(new DatabaseTBase[M, Connection](env.get))) | ||
} | ||
} |
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
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
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
79 changes: 79 additions & 0 deletions
79
examples/src/test/scala/samples/anorm/LayeredAppMultipleDatabases.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package samples.anorm | ||
|
||
import io.github.gaelrenoux.tranzactio.{DbException, ErrorStrategies} | ||
import io.github.gaelrenoux.tranzactio.anorm._ | ||
import samples.{Conf, ConnectionPool, Person} | ||
import zio._ | ||
|
||
import javax.sql.DataSource | ||
|
||
/** A sample app where all modules are linked through ZLayer. Should run as is (make sure you have com.h2database:h2 in | ||
* your dependencies). */ | ||
object LayeredAppMultipleDatabases extends zio.ZIOAppDefault { | ||
|
||
/** Marker trait for the first DB */ | ||
trait Db1 | ||
|
||
/** Marker trait for the second DB */ | ||
trait Db2 | ||
|
||
private val database1: ZLayer[Any, Throwable, DatabaseT[Db1]] = { | ||
// Fresh calls are required so that the confs and datasource aren't conflated with the other layer's | ||
val conf = Conf.live("samble-anorm-app-1").fresh | ||
val dbRecoveryConf: ZLayer[Any, Nothing, ErrorStrategies] = conf >>> ZLayer.fromFunction((_: Conf).dbRecovery).fresh | ||
val datasource: ZLayer[Any, Throwable, DataSource] = conf >>> ConnectionPool.live.fresh | ||
(datasource ++ dbRecoveryConf) >>> DatabaseT[Db1].fromDatasourceAndErrorStrategies | ||
} | ||
|
||
private val database2: ZLayer[Any, Throwable, DatabaseT[Db2]] = { | ||
// Fresh calls are required so that the confs and datasource aren't conflated with the other layer's | ||
val conf = Conf.live("samble-anorm-app-2").fresh | ||
val dbRecoveryConf: ZLayer[Any, Nothing, ErrorStrategies] = conf >>> ZLayer.fromFunction((_: Conf).dbRecovery).fresh | ||
val datasource: ZLayer[Any, Throwable, DataSource] = conf >>> ConnectionPool.live.fresh | ||
(datasource ++ dbRecoveryConf) >>> DatabaseT[Db2].fromDatasourceAndErrorStrategies | ||
} | ||
|
||
private val personQueries = PersonQueries.live | ||
|
||
type AppEnv = DatabaseT[Db1] with DatabaseT[Db2] with PersonQueries | ||
private val appEnv = database1 ++ database2 ++ personQueries | ||
|
||
override def run: ZIO[ZIOAppArgs with Scope, Any, Any] = | ||
for { | ||
_ <- Console.printLine("Starting the app") | ||
team <- myApp().provideLayer(appEnv) | ||
_ <- Console.printLine(team.mkString(", ")) | ||
} yield ExitCode(0) | ||
|
||
/** Main code for the application. Results in a big ZIO depending on the AppEnv. */ | ||
def myApp(): ZIO[PersonQueries with DatabaseT[Db2] with DatabaseT[Db1], DbException, List[Person]] = { | ||
val queries1: ZIO[PersonQueries with Connection, DbException, List[Person]] = for { | ||
_ <- Console.printLine("Creating the table").orDie | ||
_ <- PersonQueries.setup | ||
_ <- Console.printLine("Inserting the trio").orDie | ||
_ <- PersonQueries.insert(Person("Buffy", "Summers")) | ||
_ <- PersonQueries.insert(Person("Willow", "Rosenberg")) | ||
_ <- PersonQueries.insert(Person("Alexander", "Harris")) | ||
_ <- Console.printLine("Reading the trio").orDie | ||
trio <- PersonQueries.list | ||
} yield trio | ||
|
||
val queries2: ZIO[PersonQueries with Connection, DbException, List[Person]] = for { | ||
_ <- Console.printLine("Creating the table").orDie | ||
_ <- PersonQueries.setup | ||
_ <- Console.printLine("Inserting the mentor").orDie | ||
_ <- PersonQueries.insert(Person("Rupert", "Giles")) | ||
_ <- Console.printLine("Reading the mentor").orDie | ||
mentor <- PersonQueries.list | ||
} yield mentor | ||
|
||
val zTrio: ZIO[PersonQueries with DatabaseT[Db1], DbException, List[Person]] = DatabaseT[Db1].transactionOrWiden(queries1) | ||
val zMentor: ZIO[PersonQueries with DatabaseT[Db2], DbException, List[Person]] = DatabaseT[Db2].transactionOrWiden(queries2) | ||
|
||
for { | ||
trio <- zTrio | ||
mentor <- zMentor | ||
} yield trio ++ mentor | ||
} | ||
|
||
} |
78 changes: 78 additions & 0 deletions
78
examples/src/test/scala/samples/doobie/LayeredAppMultipleDatabases.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package samples.doobie | ||
|
||
import io.github.gaelrenoux.tranzactio.{DbException, ErrorStrategies} | ||
import io.github.gaelrenoux.tranzactio.doobie._ | ||
import samples.{Conf, ConnectionPool, Person} | ||
import zio._ | ||
|
||
import javax.sql.DataSource | ||
|
||
/** A sample app with two databases for different set of queries. */ | ||
object LayeredAppMultipleDatabases extends zio.ZIOAppDefault { | ||
|
||
/** Marker trait for the first DB */ | ||
trait Db1 | ||
|
||
/** Marker trait for the second DB */ | ||
trait Db2 | ||
|
||
private val database1: ZLayer[Any, Throwable, DatabaseT[Db1]] = { | ||
// Fresh calls are required so that the confs and datasource aren't conflated with the other layer's | ||
val conf = Conf.live("samble-doobie-app-1").fresh | ||
val dbRecoveryConf: ZLayer[Any, Nothing, ErrorStrategies] = conf >>> ZLayer.fromFunction((_: Conf).dbRecovery).fresh | ||
val datasource: ZLayer[Any, Throwable, DataSource] = conf >>> ConnectionPool.live.fresh | ||
(datasource ++ dbRecoveryConf) >>> DatabaseT[Db1].fromDatasourceAndErrorStrategies | ||
} | ||
|
||
private val database2: ZLayer[Any, Throwable, DatabaseT[Db2]] = { | ||
// Fresh calls are required so that the confs and datasource aren't conflated with the other layer's | ||
val conf = Conf.live("samble-doobie-app-2").fresh | ||
val dbRecoveryConf: ZLayer[Any, Nothing, ErrorStrategies] = conf >>> ZLayer.fromFunction((_: Conf).dbRecovery).fresh | ||
val datasource: ZLayer[Any, Throwable, DataSource] = conf >>> ConnectionPool.live.fresh | ||
(datasource ++ dbRecoveryConf) >>> DatabaseT[Db2].fromDatasourceAndErrorStrategies | ||
} | ||
|
||
private val personQueries = PersonQueries.live | ||
|
||
type AppEnv = DatabaseT[Db1] with DatabaseT[Db2] with PersonQueries | ||
private val appEnv = database1 ++ database2 ++ personQueries | ||
|
||
override def run: ZIO[ZIOAppArgs with Scope, Any, Any] = | ||
for { | ||
_ <- Console.printLine("Starting the app") | ||
team <- myApp().provideLayer(appEnv) | ||
_ <- Console.printLine(team.mkString(", ")) | ||
} yield ExitCode(0) | ||
|
||
/** Main code for the application. Results in a big ZIO depending on the AppEnv. */ | ||
def myApp(): ZIO[PersonQueries with DatabaseT[Db2] with DatabaseT[Db1], DbException, List[Person]] = { | ||
val queries1: ZIO[PersonQueries with Connection, DbException, List[Person]] = for { | ||
_ <- Console.printLine("Creating the table").orDie | ||
_ <- PersonQueries.setup | ||
_ <- Console.printLine("Inserting the trio").orDie | ||
_ <- PersonQueries.insert(Person("Buffy", "Summers")) | ||
_ <- PersonQueries.insert(Person("Willow", "Rosenberg")) | ||
_ <- PersonQueries.insert(Person("Alexander", "Harris")) | ||
_ <- Console.printLine("Reading the trio").orDie | ||
trio <- PersonQueries.list | ||
} yield trio | ||
|
||
val queries2: ZIO[PersonQueries with Connection, DbException, List[Person]] = for { | ||
_ <- Console.printLine("Creating the table").orDie | ||
_ <- PersonQueries.setup | ||
_ <- Console.printLine("Inserting the mentor").orDie | ||
_ <- PersonQueries.insert(Person("Rupert", "Giles")) | ||
_ <- Console.printLine("Reading the mentor").orDie | ||
mentor <- PersonQueries.list | ||
} yield mentor | ||
|
||
val zTrio: ZIO[PersonQueries with DatabaseT[Db1], DbException, List[Person]] = DatabaseT[Db1].transactionOrWiden(queries1) | ||
val zMentor: ZIO[PersonQueries with DatabaseT[Db2], DbException, List[Person]] = DatabaseT[Db2].transactionOrWiden(queries2) | ||
|
||
for { | ||
trio <- zTrio | ||
mentor <- zMentor | ||
} yield trio ++ mentor | ||
} | ||
|
||
} |