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
type Tagged[U] = { type Tag = U } | |
type @@[T, U] = T with Tagged[U] | |
trait NameTag | |
trait SurnameTag | |
type Name = String @@ NameTag | |
type Surname = String @@ SurnameTag | |
(...) |
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
case class Person(name: Name, surname: Surname) | |
def getPerson(name: Name, surname: Surname) | |
val person = Person("manuel", "Rodriguez") | |
getPerson(person.surname, person.name) | |
//DOES NOT COMPILE, THANK YOU GODS OF SCALA | |
getPerson(person.name, person.surname) |
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
case class Person(name: String, surname: String) | |
def getPerson(name: String, surname: String): Person = ??? | |
val person = Person("manuel", "rodriguez") | |
getPerson(person.surname, person.name) | |
//doesn't find anything because name and surname are in wrong order |
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
object DoobiePersistenceServiceTest extends DefaultRunnableSpec { | |
def beforeEach: ZIO[DBTransactor, Throwable, Unit] = dropUserTable.flatMap(_ => createUserTable) | |
def spec: ZSpec[TestEnvironment, Failure] = | |
suite("DoobiePersistenceService unit test")( | |
testM("GET should return a UserNotFound if the element does not exist") { | |
for { | |
_ <- beforeEach | |
notFound <- RIO.accessM[UserPersistence](_.get.get(100).either) |
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
val live: ZLayer[DBTransactor, Throwable, UserPersistence] = | |
ZLayer.fromService(new DoobiePersistenceService(_)) | |
val transactorLive: ZLayer[Has[DbConfig] with Blocking, Throwable, DBTransactor] = | |
ZLayer.fromManaged(for { | |
config <- configuration.dbConfig.toManaged_ | |
connectEC <- ZIO.descriptor.map(_.executor.asEC).toManaged_ | |
blockingEC <- blocking.blocking { ZIO.descriptor.map(_.executor.asEC) }.toManaged_ | |
transactor <- mkTransactor(config, connectEC, blockingEC) | |
} yield transactor) |
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
final class DoobiePersistenceService(tnx: Transactor[Task]) extends StoragePort { | |
import DoobiePersistenceService._ | |
override def create(user: User): IO[AppError, User] = | |
SQL | |
.create(UserStored.fromDomainUser(user)) | |
.run | |
.transact(tnx) | |
.foldM(err => IO.fail(DBError(err.getMessage)), _ => IO.succeed(user)) | |
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
import doobie.h2.H2Transactor | |
import scala.concurrent.ExecutionContext | |
import zio.Task | |
import zio.interop.catz._ | |
object DoobiePersistenceService { | |
def mkTransactor( | |
conf: DbConfig, | |
connectEC: ExecutionContext, |
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
import zio.experiment.adapter.model.{User => UserStored} | |
object SQL { | |
def get(id: Int): Query0[UserStored] = | |
sql"""SELECT * FROM USERS WHERE ID = $id """.query[UserStored] | |
def create(user: UserStored): Update0 = | |
sql"""INSERT INTO USERS (id, name) VALUES (${user.id}, ${user.name})""".update | |
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
import zio.experiment.domain.model.AppError | |
import zio.experiment.domain.model.User.{ User => UserDomain } | |
case class User(id: Int, name: String) | |
object User { | |
implicit class UserConversions(user: User) { | |
def toDomainUser: Either[AppError, UserDomain] = | |
UserDomain.build(user.id, user.name) | |
} |
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
import zio.experiment.domain.model.AppError | |
import zio.experiment.domain.model.User.{ User => UserDomain } | |
case class User(id: Int, name: String) | |
object User { | |
implicit class UserConversions(user: User) { | |
def toDomainUser: Either[AppError, UserDomain] = | |
UserDomain.build(user.id, user.name) | |
} |
NewerOlder