Getting Started
Installation
Add Saferis to your build.sbt:
libraryDependencies += "rocks.earlyeffect" %% "saferis" % "0.18.0"
Saferis requires ZIO as a provided dependency:
libraryDependencies += "dev.zio" %% "zio" % "2.1.24"
Quick Example
Saferis operations are plain ZIO effects. Throughout these docs the examples are
real ZIO programs run against a live PostgreSQL database: xa is a Transactor
connected to a test container, and .debug prints each effect's result:
Define a table with the Table typeclass, then create it, insert rows, and query
it, all type-safe, all against a real database:
xa
.run(for
_ <- ddl.createTable[QuickUser](ifNotExists = true)
_ <- dml.insert(QuickUser(-1, "Alice", "alice@example.com"))
_ <- dml.insert(QuickUser(-1, "Bob", "bob@example.com"))
users <- sql"SELECT * FROM ${Table[QuickUser]}".query[QuickUser]
yield users)
.eitherRight(Chunk(QuickUser(1,Alice,alice@example.com),QuickUser(2,Bob,bob@example.com)))Anatomy of an Application
In a real application you provide the Transactor as a layer and let your
ZIOAppDefault run the program: xa.run(...) turns a database program into an
ordinary ZIO effect:
import saferis.*
import zio.*
import javax.sql.DataSource
@tableName("getting_started_app_users")
case class AppUser(@generated @key id: Int, name: String) derives Table
object MyApp extends ZIOAppDefault:
val program: ZIO[Transactor, SaferisError, Chunk[AppUser]] =
for
xa <- ZIO.service[Transactor]
users <- xa.run(for
_ <- ddl.createTable[AppUser](ifNotExists = true)
_ <- dml.insert(AppUser(-1, "Alice"))
users <- sql"SELECT * FROM ${Table[AppUser]}".query[AppUser]
yield users)
yield users
// Your DataSource (e.g. a HikariCP pool) becomes a ConnectionProvider,
// which Transactor.layer turns into a Transactor.
def dataSource: DataSource = ???
val connectionProvider = ZLayer.succeed(ConnectionProvider.FromDataSource(dataSource))
def run = program.provide(connectionProvider, Transactor.layer())
Next, read Core Concepts to understand table definitions, the
sql"..." interpolator, and the Transactor.