feat(01-02): create Quill PostgreSQL context with ZIO integration
- Add QuillContext with dataSourceLayer and quillLayer - Update application.conf for HikariCP-compatible format - Export combined quillLive layer for database access
This commit is contained in:
@@ -5,6 +5,7 @@ server {
|
||||
port = ${?SERVER_PORT}
|
||||
}
|
||||
|
||||
# Database configuration for ZIO config (used by AppConfig)
|
||||
database {
|
||||
host = "localhost"
|
||||
host = ${?DB_HOST}
|
||||
@@ -17,3 +18,24 @@ database {
|
||||
password = "summercms"
|
||||
password = ${?DB_PASSWORD}
|
||||
}
|
||||
|
||||
# HikariCP configuration for Quill DataSource
|
||||
# Reads from "database" prefix via Quill.DataSource.fromPrefix
|
||||
database {
|
||||
dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource"
|
||||
dataSource {
|
||||
serverName = "localhost"
|
||||
serverName = ${?DB_HOST}
|
||||
portNumber = 5432
|
||||
portNumber = ${?DB_PORT}
|
||||
databaseName = "summercms"
|
||||
databaseName = ${?DB_NAME}
|
||||
user = "summercms"
|
||||
user = ${?DB_USER}
|
||||
password = "summercms"
|
||||
password = ${?DB_PASSWORD}
|
||||
}
|
||||
# HikariCP pool settings
|
||||
maximumPoolSize = 10
|
||||
connectionTimeout = 30000
|
||||
}
|
||||
|
||||
52
summercms/src/db/QuillContext.scala
Normal file
52
summercms/src/db/QuillContext.scala
Normal file
@@ -0,0 +1,52 @@
|
||||
package db
|
||||
|
||||
import io.getquill.*
|
||||
import io.getquill.jdbczio.Quill
|
||||
import zio.*
|
||||
import javax.sql.DataSource
|
||||
|
||||
/** Quill PostgreSQL context with ZIO integration
|
||||
*
|
||||
* Provides compile-time SQL query validation via Quill. Exports two layers:
|
||||
* - dataSourceLayer: HikariCP-managed connection pool configured from application.conf
|
||||
* - quillLayer: Quill PostgreSQL context with SnakeCase naming strategy
|
||||
*
|
||||
* Usage:
|
||||
* {{{
|
||||
* import db.QuillContext.*
|
||||
*
|
||||
* def findUser(email: String) =
|
||||
* run(query[SummerUser].filter(_.email == lift(email)))
|
||||
* .provide(quillLive)
|
||||
* }}}
|
||||
*
|
||||
* IMPORTANT: Never use "io" as a variable name in files importing Quill
|
||||
* (conflicts with io.getquill package).
|
||||
*/
|
||||
object QuillContext {
|
||||
|
||||
/** DataSource layer from HikariCP configuration
|
||||
*
|
||||
* Reads configuration from "database" prefix in application.conf.
|
||||
* HikariCP manages the connection pool.
|
||||
*/
|
||||
val dataSourceLayer: ZLayer[Any, Throwable, DataSource] =
|
||||
Quill.DataSource.fromPrefix("database")
|
||||
|
||||
/** Quill PostgreSQL context with snake_case naming
|
||||
*
|
||||
* Converts Scala camelCase field names to PostgreSQL snake_case columns.
|
||||
* Example: passwordHash -> password_hash
|
||||
*/
|
||||
val quillLayer: ZLayer[DataSource, Nothing, Quill.Postgres[SnakeCase]] =
|
||||
Quill.Postgres.fromNamingStrategy(SnakeCase)
|
||||
|
||||
/** Combined layer for full Quill PostgreSQL access
|
||||
*
|
||||
* Provides both DataSource and Quill context.
|
||||
* Use this when you need to run queries.
|
||||
*/
|
||||
val quillLive: ZLayer[Any, Throwable, Quill.Postgres[SnakeCase]] =
|
||||
dataSourceLayer >>> quillLayer
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user