Repo

zio.blocks.sql.Repo
See theRepo companion object
abstract class Repo[E, ID]

A type-safe repository that provides standard CRUD operations for entities of type E identified by a primary key of type ID.

Repo wraps a Table and a description of its identity column, and generates all SQL at construction time so query strings are not re-built on every call.

==Construction== Use the companion constructors, or subclass Repo directly:

  • Repo.apply — fully explicit (table, id column, codec, getter)
  • Repo.derived — derived from a zio.blocks.schema.Schema
  • class UserRepo extends Repo[User, UserId] — derives from the contextual Schema and DbCodec and inherits all default CRUD operations.

==Thread safety== Repo is immutable and safe for concurrent use. Individual operations require a DbCon or DbTx given context which is not shared across threads unless the caller arranges it.

==Empty-input policy==

  • Builders throw on empty input (require): insertAll (empty rows), Frag.values (empty rows). An empty multi-row VALUES list is invalid SQL, so construction fails fast.
  • Executors return 0 (or List.empty for reads) on empty input without touching the database: insertBatch, insertOrUpdateBatch, deleteAll, findAll.
  • update returns 0 both when no row matches the ID and when the entity carries only the ID column (nothing to set) — callers cannot distinguish the two cases from the return value alone.

==Identifier quoting== Every identifier this repository renders — table and column names in SELECT/INSERT/UPDATE/DELETE and in the IN-list prefixes — is validated and wrapped in standard double quotes, matching zio.blocks.sql.query.QueryRenderer and the query IR (zio.blocks.sql.query.SqlQuery). Both dialects (PostgreSQL, SQLite) accept double-quoted identifiers, so there is no per-dialect quoting exception anywhere on these paths.

Attributes

Companion
object
Source
Repo.scala
Graph
Supertypes
class Object
trait Matchable
class Any

Members list

Value members

Concrete methods

final def all(using con: DbCon): List[E]

Returns all rows in the table.

Returns all rows in the table.

Attributes

Source
Repo.scala
final def clear()(using con: DbCon): Int

Deletes all rows in the table using DELETE FROM <table>.

Deletes all rows in the table using DELETE FROM <table>.

Attributes

Source
Repo.scala
final def count(using con: DbCon): Long

Returns the total number of rows in the table.

Returns the total number of rows in the table.

Attributes

Source
Repo.scala
final def delete(id: ID)(using con: DbCon): Int

Deletes the row with the given primary key. Returns the affected row count.

Deletes the row with the given primary key. Returns the affected row count.

Attributes

Source
Repo.scala
final def deleteAll(ids: Iterable[ID])(using con: DbCon): Int

Deletes the rows with the given primary keys. Returns the total affected row count.

Deletes the rows with the given primary keys. Returns the total affected row count.

Like findAll, renders one IN (?, ..., ?) shape per ID count; keep batch arities stable to avoid churning the memoized rendered-SQL cache.

Attributes

Source
Repo.scala
final def exists(id: ID)(using con: DbCon): Boolean

Returns true if a row with id exists.

Returns true if a row with id exists.

Attributes

Source
Repo.scala
final def find(id: ID)(using con: DbCon): Maybe[E]

Finds the row with the given primary key.

Finds the row with the given primary key.

Attributes

Source
Repo.scala
final def findAll(ids: Iterable[ID])(using con: DbCon): List[E]

Returns the rows whose primary keys match the given IDs.

Returns the rows whose primary keys match the given IDs.

Renders one IN (?, ..., ?) shape per ID count; the rendered SQL is memoized per shape, so callers with varying batch sizes should keep arities stable (or prefer keyset paging via pageAfter) to avoid churning the fragment cache.

Attributes

Source
Repo.scala
final def insert(entity: E)(using con: DbCon): Int

Inserts entity and returns the affected row count (normally 1).

Inserts entity and returns the affected row count (normally 1).

Attributes

Source
Repo.scala
final def insertAll(rows: Seq[E])(using con: DbCon): Seq[ID]

Inserts multiple entities using a single multi-row INSERT and returns the primary keys of the inserted entities in input order.

Inserts multiple entities using a single multi-row INSERT and returns the primary keys of the inserted entities in input order.

Distinct from insertBatch which uses a JDBC batch and returns row counts. insertAll uses a single VALUES (?, ?), (?, ?) statement for efficiency, then returns the IDs extracted from the entities via getId. This is suitable when the caller supplies the primary keys explicitly (as opposed to relying on database auto-generation).

Attributes

Throws
IllegalArgumentException

if rows is empty

Source
Repo.scala
final def insertBatch(entities: Iterable[E])(using con: DbCon): Int

Inserts all entities using a JDBC batch, which is significantly faster than individual inserts for large collections. Returns the total affected row count.

Inserts all entities using a JDBC batch, which is significantly faster than individual inserts for large collections. Returns the total affected row count.

Batch logging records the rendered SQL, duration, and total affected row count. Individual parameter lists are omitted because a batch may contain a large number of rows.

Attributes

Source
Repo.scala
final def insertOrUpdate(entity: E)(using con: DbCon): Int

Inserts entity or updates it if the primary key already exists, using ON CONFLICT (id) DO UPDATE SET .... All non-ID columns are overwritten with the values from entity.

Inserts entity or updates it if the primary key already exists, using ON CONFLICT (id) DO UPDATE SET .... All non-ID columns are overwritten with the values from entity.

Conflict target is the repository's validated ID column. Assignment columns are table.columns.filter(_ != validatedIdColumn).

Attributes

Returns

affected row count (normally 1 for both insert and update paths)

Throws
IllegalArgumentException

if the table has only the ID column and no non-ID columns to update

Source
Repo.scala
final def insertOrUpdateBatch(entities: Iterable[E])(using con: DbCon): Int

Upserts all entities using a JDBC batch, following the insertBatch pattern. Each row is inserted with ON CONFLICT (id) DO UPDATE SET ... where the update columns are all non-ID columns.

Upserts all entities using a JDBC batch, following the insertBatch pattern. Each row is inserted with ON CONFLICT (id) DO UPDATE SET ... where the update columns are all non-ID columns.

If entities is empty the method returns 0 without touching the database.

Batch logging mirrors insertBatch: rendered SQL, duration, and total affected count with empty param capture.

Attributes

Throws
IllegalArgumentException

if the table has only the ID column (no assignment columns)

Source
Repo.scala
final def insertReturning(entity: E)(using con: DbCon): E

Inserts entity and returns the inserted row by re-querying it via the generated or supplied primary key.

Inserts entity and returns the inserted row by re-querying it via the generated or supplied primary key.

Attributes

Throws
NoSuchElementException

if the row cannot be found after insert.

Source
Repo.scala
final def pageAfter(cursorId: ID, limit: Int)(using con: DbCon): List[E]

Keyset pagination: returns the next limit rows whose primary key is strictly greater than cursorId, ordered by the primary key ascending.

Keyset pagination: returns the next limit rows whose primary key is strictly greater than cursorId, ordered by the primary key ascending.

Uses WHERE id > ? ORDER BY id ASC LIMIT n so the cursor row itself is not repeated. When cursorId equals the last id the result is empty.

Attributes

Throws
IllegalArgumentException

if limit &lt;= 0

Source
Repo.scala
final def update(entity: E)(using con: DbCon): Int

Updates all non-ID columns for the row identified by entity's primary key. Returns the affected row count (0 if no row with that ID exists, 0 if the entity has only an ID column).

Updates all non-ID columns for the row identified by entity's primary key. Returns the affected row count (0 if no row with that ID exists, 0 if the entity has only an ID column).

Attributes

Source
Repo.scala

Concrete fields

final val getId: E => ID

Extracts the primary key from an entity value.

Extracts the primary key from an entity value.

Attributes

Source
Repo.scala
final val idCodec: DbCodec[ID]

The codec used to read and write the ID type.

The codec used to read and write the ID type.

Attributes

Source
Repo.scala
final val idColumn: String

The name of the primary-key column as it appears in SQL.

The name of the primary-key column as it appears in SQL.

Attributes

Source
Repo.scala
final val table: Table[E]

The table this repository operates on.

The table this repository operates on.

Attributes

Source
Repo.scala