Skip to content

Instantly share code, notes, and snippets.

@achinaou
Last active January 18, 2025 18:49
Show Gist options
  • Save achinaou/7f72397be84a38a2eb921d2a0827603c to your computer and use it in GitHub Desktop.
Save achinaou/7f72397be84a38a2eb921d2a0827603c to your computer and use it in GitHub Desktop.
PostgreSQL Test Container ZIO Layer
import java.sql.Connection
import javax.sql.DataSource
import org.postgresql.ds.PGSimpleDataSource
import org.testcontainers.containers.PostgreSQLContainer as OriginalPostgreSQLContainer
import zio.*
class PostgreSQLContainer(dockerImageName: String)
extends OriginalPostgreSQLContainer[PostgreSQLContainer](dockerImageName)
object PostgreSQLContainer:
val latest: URLayer[Scope, DataSource & Connection] =
withTag("latest")
val latestAlpine: URLayer[Scope, DataSource & Connection] =
withTag("alpine")
def withTag(tag: String): URLayer[Scope, DataSource & Connection] =
ZLayer(containerResource(tag)) >>> ZLayer(dataSourceResource) >+> ZLayer(connectionResource)
private def containerResource(tag: String): URIO[Scope, PostgreSQLContainer] =
ZIO
.fromAutoCloseable(ZIO.succeed(PostgreSQLContainer(s"postgres:$tag")))
.tap(container => ZIO.attemptBlockingIO(container.start))
.orDie
private def dataSourceResource: URIO[PostgreSQLContainer, DataSource] =
ZIO
.serviceWithZIO[PostgreSQLContainer]: container =>
ZIO.attemptBlockingIO:
new PGSimpleDataSource:
setUrl(container.getJdbcUrl)
setUser(container.getUsername)
setPassword(container.getPassword)
.orDie
private def connectionResource: URIO[Scope & DataSource, Connection] =
ZIO
.fromAutoCloseable(ZIO.serviceWithZIO[DataSource](dataSource => ZIO.attemptBlockingIO(dataSource.getConnection)))
.orDie
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment