__PACKAGE__

import io.getquill.NamingStrategy
__SQL_IDIOM_IMPORT__
__MONAD_IMPORT__
__BEAN_CLASS_IMPORT__
__ID_CLASS_IMPORT__
__REPOSITORY_TRAIT_IMPORT__
__REPOSITORY_MACRO_TRAIT_IMPORT__
__REPOSITORY_IMPORT__
__EXECUTION_CONTEXT_IMPORT__
__CONNECTION_IMPORT__

final class __REPOSITORY_NAME__[__ALIAS_GENERIC_DECLARATION__](
    protected val context: __CONTEXT_ALIAS__[__GENERIC_DECLARATION__],
    protected val tableName: String = "__TABLE_NAME__"
)__IMPLICIT_BASE_VARIABLE__
  extends __REPOSITORY_TRAIT_SIMPLE_NAME__ {

  __IMPORT_CONTEXT__

  protected lazy val dynamicSchema: context.DynamicEntityQuery[__BEAN__] = {
      context.dynamicQuerySchema[__BEAN__](tableName__COLUMN_MAPPING__)
  }

  private def find(id: __ID__) = {
      dynamicSchema.__FIND_BY_KEY__
  }

  override def all: __MONAD__[Seq[__BEAN__]] =
      for {
        all <- __TRY_START__run(dynamicSchema)__TRY_END__
      } yield {
        all
      }

 override def create(entity: __BEAN__, generateId: Boolean = true): __MONAD__[__ID__] =
     __TRY_START__if (generateId) {
       run(dynamicSchema.insertValue(entity).returningGenerated(_.id))
     } else {
       run(dynamicSchema.insertValue(entity).returning(_.id))
     }__TRY_END__

   override def createOrUpdate(entity: __BEAN__, generateId: Boolean = true): __MONAD__[__ID__] =
     inTransaction { __IMPLICIT_CONTEXT____TO_TASK__
       for {
         el <- __TRY_START__run(find(entity.id).updateValue(entity))__TRY_END__
         id <- el match {
           case 0 =>
             create(entity, generateId)
           case _ =>
             pure(entity.id)
           }
       } yield {
         id
       }
      __TO_TASK_END__}

  override def read(id: __BEAN__Id): __MONAD__[Option[__BEAN__]] =
    for {
      seq <- __TRY_START__run(find(id))__TRY_END__
    } yield {
      seq.headOption
    }

__UPDATE__

  override def delete(id: __ID__): __MONAD__[__UP__] =
    __TRY_START__run(find(id).delete)__TRY_END__

  override def deleteAll: __MONAD__[__UP__] =
    __TRY_START__run(dynamicSchema.delete)__TRY_END__


}
