Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new zio-blocks-sql module with schema-driven SQL building/execution primitives (fragments, dialects, codecs, DDL, and JDBC/ZIO transactors) plus a broad test suite.
Changes:
- Introduces core SQL abstractions (
Frag,SqlDialect,DbValue,DbCodec+ derivation,Table,Ddl,SqlOps) insql/shared. - Adds a JDBC backend (
JdbcTransactor, readers/writers, connection wrappers) insql/jvmand ZIO wrappers insql-zio. - Wires new modules into the build and adds extensive unit/integration tests.
Reviewed changes
Copilot reviewed 28 out of 33 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/shared/src/main/scala/zio/blocks/sql/Transactor.scala | Adds the core transactor interface using context functions. |
| sql/shared/src/main/scala/zio/blocks/sql/Table.scala | Adds schema-derived table naming, pluralization, and basic DDL helpers. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlOps.scala | Adds query/update helpers over DbCon/DbTx. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlNameMapper.scala | Adds name mapping strategies (snake_case, identity, custom). |
| sql/shared/src/main/scala/zio/blocks/sql/SqlInterpolator.scala | Adds sql"" interpolator plumbing and parameter typeclass. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlDialect.scala | Adds PostgreSQL/SQLite dialects (types + placeholders). |
| sql/shared/src/main/scala/zio/blocks/sql/Frag.scala | Adds SQL fragment representation and dialect rendering. |
| sql/shared/src/main/scala/zio/blocks/sql/Ddl.scala | Adds basic CREATE/DROP table DDL generation. |
| sql/shared/src/main/scala/zio/blocks/sql/DbValue.scala | Adds a sum type for DB values (params + type mapping). |
| sql/shared/src/main/scala/zio/blocks/sql/DbTx.scala | Adds a transaction marker context (DbTx). |
| sql/shared/src/main/scala/zio/blocks/sql/DbConnection.scala | Adds backend-agnostic connection/statement/resultset interfaces. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCon.scala | Adds connection + dialect context type. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCodecDeriver.scala | Implements Schema-driven derivation of DbCodec. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCodec.scala | Defines DbCodec, result reading, and param writing interfaces. |
| sql/shared/src/test/scala/zio/blocks/sql/TableSpec.scala | Tests for table naming/pluralization and DDL helpers. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlNameMapperSpec.scala | Tests naming mappers, especially snake_case rules. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlInterpolatorSpec.scala | Tests DbParam conversions and basic sql"" behavior. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlDialectSpec.scala | Tests dialect type mapping and placeholders. |
| sql/shared/src/test/scala/zio/blocks/sql/FragSpec.scala | Tests fragment rendering, composition, and parameterization safety. |
| sql/shared/src/test/scala/zio/blocks/sql/DdlSpec.scala | Tests CREATE/DROP DDL formatting and nullability. |
| sql/shared/src/test/scala/zio/blocks/sql/DbValueSpec.scala | Tests DbValue constructors/extraction. |
| sql/shared/src/test/scala/zio/blocks/sql/DbCodecSpec.scala | Tests codec derivation, options, rename/transient modifiers, mappers. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcTransactor.scala | Adds JDBC transactor implementation. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcResultReader.scala | Adds JDBC ResultSet adapter for DbResultReader. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcParamWriter.scala | Adds JDBC PreparedStatement adapter for DbParamWriter. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcConnection.scala | Adds JDBC connection/statement/resultset adapters. |
| sql/jvm/src/test/scala/zio/blocks/sql/TransactorSpec.scala | Adds SQLite in-memory integration tests for queries/transactions/types. |
| sql-zio/src/main/scala/zio/blocks/sql/zio/TransactorZIO.scala | Adds ZIO Task wrappers and layer helper for transactors. |
| build.sbt | Adds sql/sql-zio modules and wires them into test/doc aliases. |
| def createTable: Frag = { | ||
| val columnDefs = codec.columns.map { col => | ||
| ColumnDef(col, dialect.typeName(DbValue.DbString("")), nullable = false) | ||
| } | ||
| Ddl.createTable(name, columnDefs) | ||
| } |
| trait DbParam[A] { | ||
| def toDbValue(value: A): DbValue | ||
| } |
| implicit class SqlStringContext(val sc: StringContext) extends AnyVal { | ||
| def sql(args: DbValue*): Frag = | ||
| Frag(sc.parts.toIndexedSeq, args.toIndexedSeq) | ||
| } |
| implicit class SqlStringContext(val sc: StringContext) extends AnyVal { | ||
| def sql(args: DbValue*): Frag = | ||
| Frag(sc.parts.toIndexedSeq, args.toIndexedSeq) | ||
| } |
| )(implicit F: HasBinding[F], D: HasInstance[F]): Lazy[DbCodec[A]] = Lazy { | ||
| if (isOptionType(typeId, cases)) { | ||
| val someCase = cases(1) | ||
| val someRecord = someCase.value.asRecord.get | ||
| val innerField = someRecord.fields(0) | ||
| val innerCodec = D.instance(innerField.value.metadata).force.asInstanceOf[DbCodec[Any]] | ||
|
|
||
| new DbCodec[A] { | ||
| val columns: IndexedSeq[String] = innerCodec.columns | ||
|
|
||
| def readValue(reader: DbResultReader, startIndex: Int): A = { | ||
| val innerValue = innerCodec.readValue(reader, startIndex) | ||
| val result: Any = if (reader.wasNull) None else Some(innerValue) | ||
| result.asInstanceOf[A] | ||
| } |
| private[sql] def pluralize(s: String): String = | ||
| if (s.isEmpty) s | ||
| else if (s.endsWith("s") || s.endsWith("x") || s.endsWith("ch") || s.endsWith("sh")) s + "es" | ||
| else if (s.endsWith("z")) s + "zes" // quiz -> quizzes, buzz -> buzzes |
There was a problem hiding this comment.
I am not sure this is a good idea at all
…iases" This reverts commit b4c2113.
…oc aliases These aliases are used by CI across ALL Scala versions (2.13, 3.3, 3.7). The sql module only supports Scala 3.3+ (crossScalaVersions does not include 2.13). This matches how other Scala-3-only modules (scope-examples, schema-examples) are also excluded from these aliases.
There was a problem hiding this comment.
Pull request overview
Adds a new zio-blocks-sql module (plus sql-zio wrapper) to provide schema-driven, type-safe SQL fragments, codec derivation, DDL helpers, and JDBC-backed transacting/connecting, integrated with zio-blocks-schema.
Changes:
- Introduces core SQL types (
Frag,DbValue,DbCodec,SqlDialect) plus interpolation and basic execution helpers (SqlOps). - Adds JDBC implementation (
JdbcTransactor, JDBC readers/writers) and ZIO wrappers (TransactorZIO). - Adds a comprehensive test suite for naming, interpolation, dialect behavior, DDL generation, codec derivation, and JDBC roundtrips; wires new modules into
build.sbt.
Reviewed changes
Copilot reviewed 28 out of 33 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/shared/src/test/scala/zio/blocks/sql/TableSpec.scala | Tests table-name derivation, pluralization, and DDL fragments from Table. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlNameMapperSpec.scala | Tests snake_case/identity/custom name mappers. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlInterpolatorSpec.scala | Tests DbParam conversions and sql"" parameter capture. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlDialectSpec.scala | Tests dialect type-name mapping and placeholder rendering. |
| sql/shared/src/test/scala/zio/blocks/sql/FragSpec.scala | Tests Frag rendering, composition, and SQL injection avoidance via params. |
| sql/shared/src/test/scala/zio/blocks/sql/DdlSpec.scala | Tests DDL generation formatting and nullability handling. |
| sql/shared/src/test/scala/zio/blocks/sql/DbValueSpec.scala | Tests DbValue constructors/extractors. |
| sql/shared/src/test/scala/zio/blocks/sql/DbCodecSpec.scala | Tests schema-driven DbCodec derivation and modifiers (rename/transient). |
| sql/shared/src/test/scala/zio/blocks/sql/.gitkeep | Placeholder file for test directory. |
| sql/shared/src/main/scala/zio/blocks/sql/Transactor.scala | Core direct-style transactor API using context functions. |
| sql/shared/src/main/scala/zio/blocks/sql/Table.scala | Derived table metadata + DDL helpers (create/drop). |
| sql/shared/src/main/scala/zio/blocks/sql/SqlOps.scala | Minimal query/update execution helpers over DbCon. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlNameMapper.scala | Field-to-column naming strategy implementations. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlInterpolator.scala | DbParam type class + sql"" interpolator + conversion to DbValue. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlDialect.scala | Dialect-specific type-name and placeholder rendering. |
| sql/shared/src/main/scala/zio/blocks/sql/Frag.scala | SQL fragment structure, rendering, and concatenation. |
| sql/shared/src/main/scala/zio/blocks/sql/Ddl.scala | DDL fragment constructors and column definitions. |
| sql/shared/src/main/scala/zio/blocks/sql/DbValue.scala | ADT for parameter values and type mapping input. |
| sql/shared/src/main/scala/zio/blocks/sql/DbTx.scala | Transaction context marker extending DbCon. |
| sql/shared/src/main/scala/zio/blocks/sql/DbConnection.scala | Backend-agnostic connection/statement/result abstractions. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCon.scala | Connection context (dialect + connection handle). |
| sql/shared/src/main/scala/zio/blocks/sql/DbCodecDeriver.scala | Deriver[DbCodec] implementation based on schema reflection/binding. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCodec.scala | Core codec interface + reader/writer traits. |
| sql/jvm/src/test/scala/zio/blocks/sql/TransactorSpec.scala | SQLite in-memory integration tests for transactor/query/update + roundtrips. |
| sql/jvm/src/test/scala/zio/blocks/sql/.gitkeep | Placeholder file for JVM test directory. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcTransactor.scala | JDBC transactor implementation for connect/transact. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcResultReader.scala | JDBC ResultSet to DbResultReader adapter. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcParamWriter.scala | JDBC PreparedStatement to DbParamWriter adapter. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcConnection.scala | JDBC connection/statement/result wrappers. |
| sql/jvm/src/main/scala/zio/blocks/sql/.gitkeep | Placeholder file for JVM main directory. |
| sql/js/src/main/scala/zio/blocks/sql/.gitkeep | Placeholder file for JS main directory. |
| sql-zio/src/main/scala/zio/blocks/sql/zio/TransactorZIO.scala | ZIO Task wrappers over blocking Transactor operations. |
| build.sbt | Adds sql crossProject and sql-zio project; aggregates them in root; adds test deps. |
|
|
||
| def createTable: Frag = { | ||
| val columnDefs = codec.columns.map { col => | ||
| ColumnDef(col, dialect.typeName(DbValue.DbString("")), nullable = false) |
|
|
||
| trait Transactor { | ||
| def connect[A](f: DbCon ?=> A): A |
| def readValue(reader: DbResultReader, startIndex: Int): A = { | ||
| val innerValue = innerCodec.readValue(reader, startIndex) | ||
| val result: Any = if (reader.wasNull) None else Some(innerValue) | ||
| result.asInstanceOf[A] | ||
| } |
| trait DbCodec[A] { | ||
| def columns: IndexedSeq[String] | ||
| def readValue(reader: DbResultReader, startIndex: Int): A | ||
| def writeValue(writer: DbParamWriter, startIndex: Int, value: A): Unit | ||
| def toDbValues(value: A): IndexedSeq[DbValue] |
| Frag(sc.parts.toIndexedSeq, args.toIndexedSeq) | ||
| } | ||
|
|
||
| given dbParamToDbValue[A](using p: DbParam[A]): Conversion[A, DbValue] = p.toDbValue(_) |
| params(i) match { | ||
| case DbValue.DbNull => writer.setNull(idx, 0) | ||
| case DbValue.DbInt(v) => writer.setInt(idx, v) | ||
| case DbValue.DbLong(v) => writer.setLong(idx, v) |
| def createTable(tableName: String, columns: IndexedSeq[ColumnDef]): Frag = { | ||
| val colDefs = columns.map { col => | ||
| val nullStr = if (col.nullable) "" else " NOT NULL" | ||
| s" ${col.name} ${col.sqlType}$nullStr" | ||
| } | ||
| Frag.const(s"CREATE TABLE IF NOT EXISTS $tableName (\n${colDefs.mkString(",\n")}\n)") | ||
| } | ||
|
|
||
| def dropTable(tableName: String): Frag = | ||
| Frag.const(s"DROP TABLE IF EXISTS $tableName") |
| SqlOps.update(Frag.const("CREATE TABLE rt_multi (id INTEGER NOT NULL, name TEXT NOT NULL)")) | ||
| SqlOps.update(sql"INSERT INTO rt_multi VALUES (${DbValue.DbInt(1)}, ${DbValue.DbString("a")})") | ||
| SqlOps.update(sql"INSERT INTO rt_multi VALUES (${DbValue.DbInt(2)}, ${DbValue.DbString("b")})") | ||
| SqlOps.update(sql"INSERT INTO rt_multi VALUES (${DbValue.DbInt(3)}, ${DbValue.DbString("c")})") | ||
| val results = SqlOps.query[User]( | ||
| sql"SELECT id, name, name FROM rt_multi ORDER BY id" | ||
| ) | ||
| assertTrue( | ||
| results.length == 3, | ||
| results(0).id == 1, | ||
| results(1).id == 2, | ||
| results(2).id == 3 |
….derived, remove default pluralization
…te) and optimize queryLimit
…ty, DataSource support
There was a problem hiding this comment.
Pull request overview
Adds a new zio-blocks-sql module (plus sql-zio) that provides schema-driven, type-safe SQL fragments, codec derivation, JDBC execution, and optional ZIO wrappers, integrating with existing zio-blocks-schema + zio-blocks-scope.
Changes:
- Introduces core SQL abstractions (
DbValue,Frag,SqlDialect,DbCodec+ derivation,Repo,Transactor) insql/shared. - Adds JVM JDBC backend (
JdbcTransactor, JDBC adapters) and integration tests using SQLite in-memory. - Adds ZIO wrapper module
sql-zio(TransactorZIO) and wires new modules intobuild.sbt.
Reviewed changes
Copilot reviewed 32 out of 37 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/shared/src/test/scala/zio/blocks/sql/TableSpec.scala | Tests for table name derivation, pluralization helper, and DDL rendering. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlNameMapperSpec.scala | Tests for snake_case/identity/custom name mappers. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlInterpolatorSpec.scala | Tests for DbParam conversions and sql"..." interpolation behavior. |
| sql/shared/src/test/scala/zio/blocks/sql/SqlDialectSpec.scala | Tests for dialect type-name mapping and parameter placeholder style. |
| sql/shared/src/test/scala/zio/blocks/sql/RepoSpec.scala | Unit tests for Repo SQL fragment builders and basic repo metadata. |
| sql/shared/src/test/scala/zio/blocks/sql/FragSpec.scala | Tests for Frag composition, rendering, and parameter handling. |
| sql/shared/src/test/scala/zio/blocks/sql/DdlSpec.scala | Tests for basic DDL generation helpers. |
| sql/shared/src/test/scala/zio/blocks/sql/DbValueSpec.scala | Tests for DbValue constructors/extractors. |
| sql/shared/src/test/scala/zio/blocks/sql/DbCodecSpec.scala | Tests for schema-driven DbCodec derivation across primitives/records/enums/options/modifiers. |
| sql/shared/src/test/scala/zio/blocks/sql/.gitkeep | Keeps test package directory in VCS. |
| sql/shared/src/main/scala/zio/blocks/sql/Transactor.scala | Defines direct-style transactor API (connect/transact). |
| sql/shared/src/main/scala/zio/blocks/sql/Table.scala | Adds Table metadata/DDL helpers and name derivation + pluralization helper. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlOps.scala | Implements query/update execution against DbCon with logging and param binding. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlNameMapper.scala | Implements column-name mapping strategies (snake_case, identity, custom). |
| sql/shared/src/main/scala/zio/blocks/sql/SqlLogger.scala | Adds logging interface/events and a noop implementation. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlInterpolator.scala | Adds DbParam type class, sql"..." interpolator, and conversions to DbValue. |
| sql/shared/src/main/scala/zio/blocks/sql/SqlDialect.scala | Defines PostgreSQL/SQLite type mapping and placeholder style. |
| sql/shared/src/main/scala/zio/blocks/sql/Repo.scala | Adds a simple CRUD repository built on Frag + DbCodec. |
| sql/shared/src/main/scala/zio/blocks/sql/Frag.scala | Represents composable SQL fragments with dialect rendering and extension ops. |
| sql/shared/src/main/scala/zio/blocks/sql/Ddl.scala | Provides basic CREATE/DROP TABLE fragment builders. |
| sql/shared/src/main/scala/zio/blocks/sql/DbValue.scala | Defines DbValue ADT for SQL parameter values. |
| sql/shared/src/main/scala/zio/blocks/sql/DbTx.scala | Transaction context marker trait extending DbCon. |
| sql/shared/src/main/scala/zio/blocks/sql/DbConnection.scala | Backend-agnostic connection/statement/resultset interfaces. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCon.scala | Connection context containing connection, dialect, and logger. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCodecDeriver.scala | Implements Deriver[DbCodec] based on Schema reflection/bindings. |
| sql/shared/src/main/scala/zio/blocks/sql/DbCodec.scala | Defines DbCodec plus reader/writer interfaces. |
| sql/jvm/src/test/scala/zio/blocks/sql/TransactorSpec.scala | JDBC transactor integration tests (SQLite in-memory) and type roundtrips. |
| sql/jvm/src/test/scala/zio/blocks/sql/RepoIntegrationSpec.scala | End-to-end CRUD tests for Repo + logging using SQLite in-memory. |
| sql/jvm/src/test/scala/zio/blocks/sql/.gitkeep | Keeps JVM test package directory in VCS. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcTransactor.scala | JDBC implementation of Transactor using java.sql.Connection. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcResultReader.scala | JDBC ResultSet adapter to DbResultReader. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcParamWriter.scala | JDBC PreparedStatement adapter to DbParamWriter. |
| sql/jvm/src/main/scala/zio/blocks/sql/JdbcConnection.scala | JDBC adapters for connection/prepared-statement/resultset. |
| sql/jvm/src/main/scala/zio/blocks/sql/.gitkeep | Keeps JVM main package directory in VCS. |
| sql/js/src/main/scala/zio/blocks/sql/.gitkeep | Keeps JS main package directory in VCS. |
| sql-zio/src/main/scala/zio/blocks/sql/zio/TransactorZIO.scala | Adds blocking ZIO wrapper for Transactor. |
| build.sbt | Registers sql crossProject + sql-zio project and dependencies. |
| partsB += s"UPDATE $tableName SET ${columns(0)} = " | ||
|
|
||
| var i = 1 | ||
| while (i < columns.size) { | ||
| partsB += s", ${columns(i)} = " | ||
| i += 1 |
| def transact[A](f: DbTx ?=> A): A = { | ||
| val conn = connectionFactory() | ||
| val dbConn = new JdbcConnection(conn) | ||
| conn.setAutoCommit(false) | ||
| try { | ||
| given tx: DbTx = new DbTx { | ||
| val connection: DbConnection = dbConn | ||
| val dialect: SqlDialect = JdbcTransactor.this.dialect | ||
| val logger: SqlLogger = JdbcTransactor.this.sqlLogger | ||
| } | ||
| val result = f | ||
| conn.commit() | ||
| result | ||
| } catch { | ||
| case e: Throwable => | ||
| try conn.rollback() | ||
| catch { case rb: Throwable => e.addSuppressed(rb) } | ||
| throw e | ||
| } finally { | ||
| try dbConn.close() | ||
| catch { case _: Throwable => () } | ||
| } |
| // Note: wasNull reflects the last column read by the inner codec. | ||
| // For single-column types (the common case), this is correct. | ||
| // For multi-column inner types, wasNull only reflects the last column, | ||
| // so a NULL in an earlier column may not be detected. | ||
| def readValue(reader: DbResultReader, startIndex: Int): A = { | ||
| val innerValue = innerCodec.readValue(reader, startIndex) | ||
| val result: Any = if (reader.wasNull) None else Some(innerValue) | ||
| result.asInstanceOf[A] | ||
| } |
|
|
||
| trait Transactor { | ||
| def connect[A](f: DbCon ?=> A): A |
|
|
||
| trait DbCodec[A] { | ||
| def columns: IndexedSeq[String] | ||
| def readValue(reader: DbResultReader, startIndex: Int): A | ||
| def writeValue(writer: DbParamWriter, startIndex: Int, value: A): Unit | ||
| def toDbValues(value: A): IndexedSeq[DbValue] | ||
| def columnCount: Int = columns.size | ||
| } | ||
|
|
||
| object DbCodec { | ||
| def apply[A](implicit codec: DbCodec[A]): DbCodec[A] = codec | ||
| } | ||
|
|
||
| trait DbResultReader { | ||
| def getInt(index: Int): Int | ||
| def getLong(index: Int): Long | ||
| def getDouble(index: Int): Double | ||
| def getFloat(index: Int): Float | ||
| def getBoolean(index: Int): Boolean | ||
| def getString(index: Int): String | ||
| def getBigDecimal(index: Int): java.math.BigDecimal | ||
| def getBytes(index: Int): Array[Byte] | ||
| def getShort(index: Int): Short | ||
| def getByte(index: Int): Byte | ||
| def getLocalDate(index: Int): java.time.LocalDate | ||
| def getLocalDateTime(index: Int): java.time.LocalDateTime | ||
| def getLocalTime(index: Int): java.time.LocalTime | ||
| def getInstant(index: Int): java.time.Instant | ||
| def getDuration(index: Int): java.time.Duration | ||
| def getUUID(index: Int): java.util.UUID | ||
| def wasNull: Boolean | ||
| } | ||
|
|
||
| trait DbParamWriter { | ||
| def setInt(index: Int, value: Int): Unit | ||
| def setLong(index: Int, value: Long): Unit | ||
| def setDouble(index: Int, value: Double): Unit | ||
| def setFloat(index: Int, value: Float): Unit | ||
| def setBoolean(index: Int, value: Boolean): Unit | ||
| def setString(index: Int, value: String): Unit | ||
| def setBigDecimal(index: Int, value: java.math.BigDecimal): Unit | ||
| def setBytes(index: Int, value: Array[Byte]): Unit | ||
| def setShort(index: Int, value: Short): Unit | ||
| def setByte(index: Int, value: Byte): Unit | ||
| def setLocalDate(index: Int, value: java.time.LocalDate): Unit | ||
| def setLocalDateTime(index: Int, value: java.time.LocalDateTime): Unit | ||
| def setLocalTime(index: Int, value: java.time.LocalTime): Unit | ||
| def setInstant(index: Int, value: java.time.Instant): Unit | ||
| def setDuration(index: Int, value: java.time.Duration): Unit | ||
| def setUUID(index: Int, value: java.util.UUID): Unit |
| def createTable: Frag = { | ||
| val columnDefs = codec.columns.map { col => | ||
| ColumnDef(col, dialect.typeName(DbValue.DbString("")), nullable = false) | ||
| } | ||
| Ddl.createTable(name, columnDefs) | ||
| } |
| configured.getOrElse { | ||
| val typeName = schema.reflect.typeId.name | ||
| SqlNameMapper.SnakeCase(typeName) | ||
| } |
| def findById(id: ID)(using con: DbCon): Option[E] = { | ||
| val frag = Frag( | ||
| IndexedSeq(s"SELECT $allCols FROM $tbl WHERE $idColumn = ", ""), | ||
| idCodec.toDbValues(id) | ||
| ) | ||
| SqlOps.queryOne[E](frag)(using con, codec) | ||
| } |
| def update(entity: E)(using con: DbCon): Int = { | ||
| val entityValues = codec.toDbValues(entity) | ||
| val idValues = idCodec.toDbValues(getId(entity)) | ||
| val frag = Repo.buildUpdateFrag(tbl, table.columns, entityValues, idColumn, idValues) |
| private[sql] def buildInsertFrag( | ||
| tableName: String, | ||
| allColumns: String, | ||
| values: IndexedSeq[DbValue] | ||
| ): Frag = | ||
| if (values.isEmpty) Frag.const(s"INSERT INTO $tableName ($allColumns) VALUES ()") | ||
| else { | ||
| val parts = | ||
| IndexedSeq(s"INSERT INTO $tableName ($allColumns) VALUES (") ++ | ||
| IndexedSeq.fill(values.size - 1)(", ") :+ | ||
| ")" | ||
| Frag(parts, values) | ||
| } |
Summary
Adds a new
zio-blocks-sqlmodule providing schema-driven, type-safe SQL database access that integrates with zio-blocks' existing Schema, Scope, and optics infrastructure. Inspired by Magnum.Closes #1216
Modules
sqlsql-zioTransactorZIO)Key Features
Schema-Driven DbCodec Derivation
Safe SQL Interpolation
Transactor with Context Functions
DDL Generation
ZIO Integration
Architecture
sqldepends only onzio-blocks-schema+zio-blocks-scopeDbCon ?=> A/DbTx ?=> Acontext functionsgiven,extension, context functionsDialect Support
$N?Test Coverage
Non-Goals (explicitly out of scope)
Related
derives Repository)