ajozwik / quill-generic   1.2.5

MIT License GitHub

Library of generic CRUD operation for https://github.com/getquill/quill library

Scala versions: 2.13 2.12
sbt plugins: 1.x

quill-generic support

Library of generic CRUD operation for quill library. Only dynamic queries are supported.

Codacy Badge Maven Central Maven Central Coverage Status Scala CI codecov

Always when you start new project you must to write a lot of boilerplate code for handling simple CRUD operations. Purpose of this library is to support creating CRUD repository with Quill library.

Purpose of CRUD operations - Repository - where F is monad like scala.util.Try/monix.eval.Task/scala.concurrent.Future :

package pl.jozwik.quillgeneric.repository


trait WithTransaction[F[_]] {
  def inTransaction[A](task: F[A]): F[A]
}

trait RepositoryWithGeneratedId[F[_], K, T <: WithId[K], UP] extends BaseRepository[F, K, T, UP] {
  def create(entity: T, generatedId: Boolean = true): F[K]

  def createAndRead(entity: T, generatedId: Boolean = true): F[T]

  def createOrUpdate(entity: T, generatedId: Boolean = true): F[K]

  def createOrUpdateAndRead(entity: T, generatedId: Boolean = true): F[T]
}


trait Repository[F[_], K, T <: WithId[K], UP] extends BaseRepository[F, K, T, UP] {
  def create(entity: T): F[K]

  def createAndRead(entity: T): F[T]

  def createOrUpdate(entity: T): F[K]

  def createOrUpdateAndRead(entity: T): F[T]
}

trait BaseRepository[F[_], K, T <: WithId[K], UP] {

  def all: F[Seq[T]]

  def read(id: K): F[Option[T]]

  def readUnsafe(id: K): F[T]

  def update(t: T): F[UP]

  def updateAndRead(t: T): F[T]

  def delete(id: K): F[UP]

  def deleteAll: F[UP]

}

trait RepositoryWithTransaction[F[_], K, T <: WithId[K], UP] extends Repository[F, K, T, UP] with WithTransaction[F]

trait RepositoryWithTransactionWithGeneratedId[F[_], K, T <: WithId[K], UP] extends RepositoryWithGeneratedId[F, K, T, UP] with WithTransaction[F]

Because protoquill-macro's are created in compile time - we need to know primary key. Case class for database entity has to have field id - the primary key WithId If you have composite key you need to create case class like Cell4dId:

For table

CREATE TABLE IF NOT EXISTS CELL4D (
    `X`  INT NOT NULL,
    `Y`  INT NOT NULL,
    `Z`  INT NOT NULL,
    `T`  INT NOT NULL,
    `OCCUPIED` BOOLEAN,
    PRIMARY KEY (`X`, `Y`, `Z`, `T`)
)

Compose key can look like:

final case class Cell4dId(fk1: Int, fk2: Int, fk3: Int, fk4: Long) {
  def x: Int = fk1

  def y: Int = fk2

  def z: Int = fk3

  def t: Long = fk4

}

General Repository is designed for manual handling of primary key. If database generate for you key - use RepositoryWithGeneratedId

Current we support Try:

And monix Task:

Synchronized and monix repositories are generated automatically by sbt-quill-crud-generic, see build.sbt in quill-macro-example