package com.ustadmobile.core.db.dao

import androidx.paging.PagingSource
import com.ustadmobile.door.DoorDbType
import com.ustadmobile.door.EntityInsertionAdapter
import com.ustadmobile.door.PreparedStatementConfig
import com.ustadmobile.door.ext.createArrayOrProxyArrayOf
import com.ustadmobile.door.ext.prepareAndUseStatement
import com.ustadmobile.door.ext.prepareAndUseStatementAsync
import com.ustadmobile.door.flow.doorFlow
import com.ustadmobile.door.jdbc.PreparedStatement
import com.ustadmobile.door.jdbc.ext.executeQueryAsyncKmp
import com.ustadmobile.door.jdbc.ext.executeUpdateAsyncKmp
import com.ustadmobile.door.jdbc.ext.getStringNonNull
import com.ustadmobile.door.jdbc.ext.mapNextRow
import com.ustadmobile.door.jdbc.ext.mapRows
import com.ustadmobile.door.jdbc.ext.useResults
import com.ustadmobile.door.paging.DoorLimitOffsetPagingSource
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.lib.db.composites.ClazzAndDetailPermissions
import com.ustadmobile.lib.db.composites.ClazzAndDisplayDetails
import com.ustadmobile.lib.db.composites.ClazzNameAndTerminology
import com.ustadmobile.lib.db.composites.ClazzUidAndName
import com.ustadmobile.lib.db.entities.Clazz
import com.ustadmobile.lib.db.entities.ClazzEnrolment
import com.ustadmobile.lib.db.entities.ClazzWithHolidayCalendarAndAndTerminology
import com.ustadmobile.lib.db.entities.ClazzWithListDisplayDetails
import com.ustadmobile.lib.db.entities.CoursePicture
import com.ustadmobile.lib.db.entities.CourseTerminology
import com.ustadmobile.lib.db.entities.HolidayCalendar
import com.ustadmobile.lib.db.entities.UidAndLabel
import kotlin.Boolean
import kotlin.IllegalArgumentException
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow

public class ClazzDao_JdbcImpl(
  public val _db: RoomDatabase,
) : ClazzDao() {
  public val _insertAdapterClazz_abort: EntityInsertionAdapter<Clazz> = object :
      EntityInsertionAdapter<Clazz>(_db) {
    override fun makeSql(returnsId: Boolean): String = when(dbType) {
      DoorDbType.SQLITE -> {
        "INSERT INTO Clazz (clazzUid, clazzName, clazzDesc, attendanceAverage, clazzHolidayUMCalendarUid, clazzScheuleUMCalendarUid, isClazzActive, clazzLocationUid, clazzStartTime, clazzEndTime, clazzFeatures, clazzSchoolUid, clazzEnrolmentPolicy, clazzTerminologyUid, clazzMasterChangeSeqNum, clazzLocalChangeSeqNum, clazzLastChangedBy, clazzLct, clazzTimeZone, clazzStudentsPersonGroupUid, clazzTeachersPersonGroupUid, clazzPendingStudentsPersonGroupUid, clazzParentsPersonGroupUid, clazzCode, clazzOwnerPersonUid) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
      }
      DoorDbType.POSTGRES ->  {
        "INSERT INTO Clazz (clazzUid, clazzName, clazzDesc, attendanceAverage, clazzHolidayUMCalendarUid, clazzScheuleUMCalendarUid, isClazzActive, clazzLocationUid, clazzStartTime, clazzEndTime, clazzFeatures, clazzSchoolUid, clazzEnrolmentPolicy, clazzTerminologyUid, clazzMasterChangeSeqNum, clazzLocalChangeSeqNum, clazzLastChangedBy, clazzLct, clazzTimeZone, clazzStudentsPersonGroupUid, clazzTeachersPersonGroupUid, clazzPendingStudentsPersonGroupUid, clazzParentsPersonGroupUid, clazzCode, clazzOwnerPersonUid) VALUES(COALESCE(?,nextval('Clazz_clazzUid_seq')), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + if(returnsId) { " RETURNING clazzUid" } else "" 
      }
      else -> {
        throw IllegalArgumentException("Unsupported db type")
      }
    }

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement, entity: Clazz) {
      if(entity.clazzUid == 0L) {
        stmt.setObject(1, null)
      } else {
        stmt.setLong(1, entity.clazzUid)
      }
      stmt.setString(2, entity.clazzName)
      stmt.setString(3, entity.clazzDesc)
      stmt.setFloat(4, entity.attendanceAverage)
      stmt.setLong(5, entity.clazzHolidayUMCalendarUid)
      stmt.setLong(6, entity.clazzScheuleUMCalendarUid)
      stmt.setBoolean(7, entity.isClazzActive)
      stmt.setLong(8, entity.clazzLocationUid)
      stmt.setLong(9, entity.clazzStartTime)
      stmt.setLong(10, entity.clazzEndTime)
      stmt.setLong(11, entity.clazzFeatures)
      stmt.setLong(12, entity.clazzSchoolUid)
      stmt.setInt(13, entity.clazzEnrolmentPolicy)
      stmt.setLong(14, entity.clazzTerminologyUid)
      stmt.setLong(15, entity.clazzMasterChangeSeqNum)
      stmt.setLong(16, entity.clazzLocalChangeSeqNum)
      stmt.setInt(17, entity.clazzLastChangedBy)
      stmt.setLong(18, entity.clazzLct)
      stmt.setString(19, entity.clazzTimeZone)
      stmt.setLong(20, entity.clazzStudentsPersonGroupUid)
      stmt.setLong(21, entity.clazzTeachersPersonGroupUid)
      stmt.setLong(22, entity.clazzPendingStudentsPersonGroupUid)
      stmt.setLong(23, entity.clazzParentsPersonGroupUid)
      stmt.setString(24, entity.clazzCode)
      stmt.setLong(25, entity.clazzOwnerPersonUid)
    }
  }

  public override fun insert(entity: Clazz): Long {
    val _retVal = _insertAdapterClazz_abort.insertAndReturnId(entity)
    return _retVal
  }

  public override suspend fun insertAsync(entity: Clazz): Long {
    val _retVal = _insertAdapterClazz_abort.insertAndReturnIdAsync(entity)
    return _retVal
  }

  public override fun insertList(entityList: List<Clazz>) {
    _insertAdapterClazz_abort.insertList(entityList)
  }

  override suspend fun updateAsync(entity: Clazz): Int {
    var _result = 0
    val _sql =
        "UPDATE Clazz SET clazzName = ?, clazzDesc = ?, attendanceAverage = ?, clazzHolidayUMCalendarUid = ?, clazzScheuleUMCalendarUid = ?, isClazzActive = ?, clazzLocationUid = ?, clazzStartTime = ?, clazzEndTime = ?, clazzFeatures = ?, clazzSchoolUid = ?, clazzEnrolmentPolicy = ?, clazzTerminologyUid = ?, clazzMasterChangeSeqNum = ?, clazzLocalChangeSeqNum = ?, clazzLastChangedBy = ?, clazzLct = ?, clazzTimeZone = ?, clazzStudentsPersonGroupUid = ?, clazzTeachersPersonGroupUid = ?, clazzPendingStudentsPersonGroupUid = ?, clazzParentsPersonGroupUid = ?, clazzCode = ?, clazzOwnerPersonUid = ? WHERE clazzUid = ?"
    _db.prepareAndUseStatementAsync(_sql) {
       _stmt ->
      _stmt.setString(1, entity.clazzName)
      _stmt.setString(2, entity.clazzDesc)
      _stmt.setFloat(3, entity.attendanceAverage)
      _stmt.setLong(4, entity.clazzHolidayUMCalendarUid)
      _stmt.setLong(5, entity.clazzScheuleUMCalendarUid)
      _stmt.setBoolean(6, entity.isClazzActive)
      _stmt.setLong(7, entity.clazzLocationUid)
      _stmt.setLong(8, entity.clazzStartTime)
      _stmt.setLong(9, entity.clazzEndTime)
      _stmt.setLong(10, entity.clazzFeatures)
      _stmt.setLong(11, entity.clazzSchoolUid)
      _stmt.setInt(12, entity.clazzEnrolmentPolicy)
      _stmt.setLong(13, entity.clazzTerminologyUid)
      _stmt.setLong(14, entity.clazzMasterChangeSeqNum)
      _stmt.setLong(15, entity.clazzLocalChangeSeqNum)
      _stmt.setInt(16, entity.clazzLastChangedBy)
      _stmt.setLong(17, entity.clazzLct)
      _stmt.setString(18, entity.clazzTimeZone)
      _stmt.setLong(19, entity.clazzStudentsPersonGroupUid)
      _stmt.setLong(20, entity.clazzTeachersPersonGroupUid)
      _stmt.setLong(21, entity.clazzPendingStudentsPersonGroupUid)
      _stmt.setLong(22, entity.clazzParentsPersonGroupUid)
      _stmt.setString(23, entity.clazzCode)
      _stmt.setLong(24, entity.clazzOwnerPersonUid)
      _stmt.setLong(25, entity.clazzUid)
      _result += _stmt.executeUpdateAsyncKmp()
    }
    return _result
  }

  public override fun update(entity: Clazz) {
    val _sql =
        "UPDATE Clazz SET clazzName = ?, clazzDesc = ?, attendanceAverage = ?, clazzHolidayUMCalendarUid = ?, clazzScheuleUMCalendarUid = ?, isClazzActive = ?, clazzLocationUid = ?, clazzStartTime = ?, clazzEndTime = ?, clazzFeatures = ?, clazzSchoolUid = ?, clazzEnrolmentPolicy = ?, clazzTerminologyUid = ?, clazzMasterChangeSeqNum = ?, clazzLocalChangeSeqNum = ?, clazzLastChangedBy = ?, clazzLct = ?, clazzTimeZone = ?, clazzStudentsPersonGroupUid = ?, clazzTeachersPersonGroupUid = ?, clazzPendingStudentsPersonGroupUid = ?, clazzParentsPersonGroupUid = ?, clazzCode = ?, clazzOwnerPersonUid = ? WHERE clazzUid = ?"
    _db.prepareAndUseStatement(_sql) {
       _stmt ->
      _stmt.setString(1, entity.clazzName)
      _stmt.setString(2, entity.clazzDesc)
      _stmt.setFloat(3, entity.attendanceAverage)
      _stmt.setLong(4, entity.clazzHolidayUMCalendarUid)
      _stmt.setLong(5, entity.clazzScheuleUMCalendarUid)
      _stmt.setBoolean(6, entity.isClazzActive)
      _stmt.setLong(7, entity.clazzLocationUid)
      _stmt.setLong(8, entity.clazzStartTime)
      _stmt.setLong(9, entity.clazzEndTime)
      _stmt.setLong(10, entity.clazzFeatures)
      _stmt.setLong(11, entity.clazzSchoolUid)
      _stmt.setInt(12, entity.clazzEnrolmentPolicy)
      _stmt.setLong(13, entity.clazzTerminologyUid)
      _stmt.setLong(14, entity.clazzMasterChangeSeqNum)
      _stmt.setLong(15, entity.clazzLocalChangeSeqNum)
      _stmt.setInt(16, entity.clazzLastChangedBy)
      _stmt.setLong(17, entity.clazzLct)
      _stmt.setString(18, entity.clazzTimeZone)
      _stmt.setLong(19, entity.clazzStudentsPersonGroupUid)
      _stmt.setLong(20, entity.clazzTeachersPersonGroupUid)
      _stmt.setLong(21, entity.clazzPendingStudentsPersonGroupUid)
      _stmt.setLong(22, entity.clazzParentsPersonGroupUid)
      _stmt.setString(23, entity.clazzCode)
      _stmt.setLong(24, entity.clazzOwnerPersonUid)
      _stmt.setLong(25, entity.clazzUid)
      _stmt.executeUpdate()
    }
  }

  override fun findByUid(uid: Long): Clazz? = _db.prepareAndUseStatement(PreparedStatementConfig(
    sql = "SELECT * FROM Clazz WHERE clazzUid = ?",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,uid)
    _stmt.executeQuery().useResults{ _result -> 
      _result.mapNextRow(null) {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override fun findByUidLive(uid: Long): Flow<Clazz?> = _db.doorFlow(arrayOf("Clazz")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = "SELECT * From Clazz WHERE clazzUid = ?",
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,uid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          val _tmp_clazzUid = _result.getLong("clazzUid")
          val _tmp_clazzName = _result.getString("clazzName")
          val _tmp_clazzDesc = _result.getString("clazzDesc")
          val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
          val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
          val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
          val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
          val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
          val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
          val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
          val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
          val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
          val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
          val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
          val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
          val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
          val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
          val _tmp_clazzLct = _result.getLong("clazzLct")
          val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
          val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
          val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
          val _tmp_clazzPendingStudentsPersonGroupUid =
              _result.getLong("clazzPendingStudentsPersonGroupUid")
          val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
          val _tmp_clazzCode = _result.getString("clazzCode")
          val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
          Clazz().apply {
            this.clazzUid = _tmp_clazzUid
            this.clazzName = _tmp_clazzName
            this.clazzDesc = _tmp_clazzDesc
            this.attendanceAverage = _tmp_attendanceAverage
            this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
            this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
            this.isClazzActive = _tmp_isClazzActive
            this.clazzLocationUid = _tmp_clazzLocationUid
            this.clazzStartTime = _tmp_clazzStartTime
            this.clazzEndTime = _tmp_clazzEndTime
            this.clazzFeatures = _tmp_clazzFeatures
            this.clazzSchoolUid = _tmp_clazzSchoolUid
            this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
            this.clazzTerminologyUid = _tmp_clazzTerminologyUid
            this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
            this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
            this.clazzLastChangedBy = _tmp_clazzLastChangedBy
            this.clazzLct = _tmp_clazzLct
            this.clazzTimeZone = _tmp_clazzTimeZone
            this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
            this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
            this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
            this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
            this.clazzCode = _tmp_clazzCode
            this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
          }
        }
      }
    }
  }

  override suspend fun findByClazzCode(code: String): Clazz? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = "SELECT * FROM Clazz WHERE clazzCode = ?",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setString(1,code)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override suspend fun findByClazzCodeFromWeb(code: String): Clazz? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = "SELECT * FROM Clazz WHERE clazzCode = ?",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setString(1,code)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override fun findAllLive(): Flow<List<Clazz>> = _db.doorFlow(arrayOf("Clazz")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = "SELECT * FROM Clazz WHERE CAST(isClazzActive AS INTEGER) = 1",
      readOnly = true,)
    ) { _stmt -> 
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapRows {
          val _tmp_clazzUid = _result.getLong("clazzUid")
          val _tmp_clazzName = _result.getString("clazzName")
          val _tmp_clazzDesc = _result.getString("clazzDesc")
          val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
          val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
          val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
          val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
          val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
          val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
          val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
          val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
          val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
          val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
          val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
          val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
          val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
          val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
          val _tmp_clazzLct = _result.getLong("clazzLct")
          val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
          val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
          val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
          val _tmp_clazzPendingStudentsPersonGroupUid =
              _result.getLong("clazzPendingStudentsPersonGroupUid")
          val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
          val _tmp_clazzCode = _result.getString("clazzCode")
          val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
          Clazz().apply {
            this.clazzUid = _tmp_clazzUid
            this.clazzName = _tmp_clazzName
            this.clazzDesc = _tmp_clazzDesc
            this.attendanceAverage = _tmp_attendanceAverage
            this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
            this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
            this.isClazzActive = _tmp_isClazzActive
            this.clazzLocationUid = _tmp_clazzLocationUid
            this.clazzStartTime = _tmp_clazzStartTime
            this.clazzEndTime = _tmp_clazzEndTime
            this.clazzFeatures = _tmp_clazzFeatures
            this.clazzSchoolUid = _tmp_clazzSchoolUid
            this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
            this.clazzTerminologyUid = _tmp_clazzTerminologyUid
            this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
            this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
            this.clazzLastChangedBy = _tmp_clazzLastChangedBy
            this.clazzLct = _tmp_clazzLct
            this.clazzTimeZone = _tmp_clazzTimeZone
            this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
            this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
            this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
            this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
            this.clazzCode = _tmp_clazzCode
            this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
          }
        }
      }
    }
  }

  override fun findAll(): List<Clazz> = _db.prepareAndUseStatement(PreparedStatementConfig(
    sql = "SELECT * FROM Clazz WHERE CAST(isClazzActive AS INTEGER) = 1",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.executeQuery().useResults{ _result -> 
      _result.mapRows {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override suspend fun findByUidAsync(clazzUid: Long): Clazz? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = "SELECT * FROM Clazz WHERE clazzUid = ?",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,clazzUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override suspend fun clazzUidExistsAsync(clazzUid: Long): Boolean =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT EXISTS(
    |               SELECT Clazz.clazzUid
    |                 FROM Clazz
    |                WHERE Clazz.clazzUid = ?)
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,clazzUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(false) {
        _result.getBoolean(1)
      }
    }
  }

  override fun findByUidAsFlow(uid: Long): Flow<Clazz?> = _db.doorFlow(arrayOf("Clazz")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = "SELECT * FROM Clazz WHERE clazzUid = ?",
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,uid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          val _tmp_clazzUid = _result.getLong("clazzUid")
          val _tmp_clazzName = _result.getString("clazzName")
          val _tmp_clazzDesc = _result.getString("clazzDesc")
          val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
          val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
          val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
          val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
          val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
          val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
          val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
          val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
          val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
          val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
          val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
          val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
          val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
          val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
          val _tmp_clazzLct = _result.getLong("clazzLct")
          val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
          val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
          val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
          val _tmp_clazzPendingStudentsPersonGroupUid =
              _result.getLong("clazzPendingStudentsPersonGroupUid")
          val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
          val _tmp_clazzCode = _result.getString("clazzCode")
          val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
          Clazz().apply {
            this.clazzUid = _tmp_clazzUid
            this.clazzName = _tmp_clazzName
            this.clazzDesc = _tmp_clazzDesc
            this.attendanceAverage = _tmp_attendanceAverage
            this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
            this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
            this.isClazzActive = _tmp_isClazzActive
            this.clazzLocationUid = _tmp_clazzLocationUid
            this.clazzStartTime = _tmp_clazzStartTime
            this.clazzEndTime = _tmp_clazzEndTime
            this.clazzFeatures = _tmp_clazzFeatures
            this.clazzSchoolUid = _tmp_clazzSchoolUid
            this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
            this.clazzTerminologyUid = _tmp_clazzTerminologyUid
            this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
            this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
            this.clazzLastChangedBy = _tmp_clazzLastChangedBy
            this.clazzLct = _tmp_clazzLct
            this.clazzTimeZone = _tmp_clazzTimeZone
            this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
            this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
            this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
            this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
            this.clazzCode = _tmp_clazzCode
            this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
          }
        }
      }
    }
  }

  override suspend fun findByUidWithHolidayCalendarAsync(uid: Long):
      ClazzWithHolidayCalendarAndAndTerminology? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT Clazz.*, 
    |               CoursePicture.*,
    |               HolidayCalendar.*, 
    |               CourseTerminology.*
    |          FROM Clazz 
    |               LEFT JOIN HolidayCalendar 
    |                         ON Clazz.clazzHolidayUMCalendarUid = HolidayCalendar.umCalendarUid
    |
    |               LEFT JOIN CourseTerminology
    |                         ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid
    |                      
    |               LEFT JOIN CoursePicture
    |                         ON CoursePicture.coursePictureUid = ?
    |         WHERE Clazz.clazzUid = ?
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,uid)
    _stmt.setLong(2,uid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        var _tmp_HolidayCalendar_nullCount = 0
        val _tmp_umCalendarUid = _result.getLong("umCalendarUid")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarName = _result.getString("umCalendarName")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarCategory = _result.getInt("umCalendarCategory")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarActive = _result.getBoolean("umCalendarActive")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarMasterChangeSeqNum = _result.getLong("umCalendarMasterChangeSeqNum")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarLocalChangeSeqNum = _result.getLong("umCalendarLocalChangeSeqNum")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarLastChangedBy = _result.getInt("umCalendarLastChangedBy")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarLct = _result.getLong("umCalendarLct")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_HolidayCalendar_isAllNull = _tmp_HolidayCalendar_nullCount == 8
        var _tmp_CourseTerminology_nullCount = 0
        val _tmp_ctUid = _result.getLong("ctUid")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_ctTitle = _result.getString("ctTitle")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_ctTerminology = _result.getString("ctTerminology")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_ctLct = _result.getLong("ctLct")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_CourseTerminology_isAllNull = _tmp_CourseTerminology_nullCount == 4
        var _tmp_CoursePicture_nullCount = 0
        val _tmp_coursePictureUid = _result.getLong("coursePictureUid")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureLct = _result.getLong("coursePictureLct")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureUri = _result.getString("coursePictureUri")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureThumbnailUri = _result.getString("coursePictureThumbnailUri")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureActive = _result.getBoolean("coursePictureActive")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_CoursePicture_isAllNull = _tmp_CoursePicture_nullCount == 5
        ClazzWithHolidayCalendarAndAndTerminology().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
          if(!_tmp_HolidayCalendar_isAllNull) {
            this.holidayCalendar = HolidayCalendar().apply {
              this.umCalendarUid = _tmp_umCalendarUid
              this.umCalendarName = _tmp_umCalendarName
              this.umCalendarCategory = _tmp_umCalendarCategory
              this.umCalendarActive = _tmp_umCalendarActive
              this.umCalendarMasterChangeSeqNum = _tmp_umCalendarMasterChangeSeqNum
              this.umCalendarLocalChangeSeqNum = _tmp_umCalendarLocalChangeSeqNum
              this.umCalendarLastChangedBy = _tmp_umCalendarLastChangedBy
              this.umCalendarLct = _tmp_umCalendarLct
            }
          }
          if(!_tmp_CourseTerminology_isAllNull) {
            this.terminology = CourseTerminology().apply {
              this.ctUid = _tmp_ctUid
              this.ctTitle = _tmp_ctTitle
              this.ctTerminology = _tmp_ctTerminology
              this.ctLct = _tmp_ctLct
            }
          }
          if(!_tmp_CoursePicture_isAllNull) {
            this.coursePicture = CoursePicture().apply {
              this.coursePictureUid = _tmp_coursePictureUid
              this.coursePictureLct = _tmp_coursePictureLct
              this.coursePictureUri = _tmp_coursePictureUri
              this.coursePictureThumbnailUri = _tmp_coursePictureThumbnailUri
              this.coursePictureActive = _tmp_coursePictureActive
            }
          }
        }
      }
    }
  }

  override fun findClazzesWithPermission(
    searchQuery: String,
    accountPersonUid: Long,
    excludeSelectedClazzList: List<Long>,
    sortOrder: Int,
    filter: Int,
    currentTime: Long,
    permission: Long,
  ): PagingSource<Int, ClazzWithListDisplayDetails> = object :
      DoorLimitOffsetPagingSource<ClazzWithListDisplayDetails>(db = _db
  , tableNames = arrayOf("Clazz", "ClazzEnrolment", "CoursePermission", "SystemPermission",
      "CourseTerminology", "CoursePicture")
  ) {
    override suspend fun loadRows(_limit: Int, _offset: Int): List<ClazzWithListDisplayDetails> =
        _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |SELECT * FROM (
      |        SELECT Clazz.*, ClazzEnrolment.*, CoursePicture.*,
      |               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) 
      |                  FROM ClazzEnrolment 
      |                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                   AND clazzEnrolmentRole = 1000 
      |                   AND ? BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined 
      |                       AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numStudents,
      |               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) 
      |                  FROM ClazzEnrolment 
      |                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                   AND clazzEnrolmentRole = 1001
      |                   AND ? BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined 
      |                        AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numTeachers,
      |               '' AS teacherNames,
      |               0 AS lastRecorded,
      |               CourseTerminology.*
      |          FROM Clazz
      |               LEFT JOIN ClazzEnrolment 
      |                    ON ClazzEnrolment.clazzEnrolmentUid =
      |                       COALESCE(
      |                       (SELECT ClazzEnrolment.clazzEnrolmentUid 
      |                          FROM ClazzEnrolment
      |                         WHERE ClazzEnrolment.clazzEnrolmentPersonUid = ?
      |                           AND ClazzEnrolment.clazzEnrolmentActive
      |                           AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                      ORDER BY ClazzEnrolment.clazzEnrolmentDateLeft DESC   
      |                         LIMIT 1), 0)
      |                LEFT JOIN CourseTerminology   
      |                          ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid
      |                LEFT JOIN CoursePicture
      |                          ON CoursePicture.coursePictureUid = Clazz.clazzUid           
      |
      |         WHERE /* Begin permission check clause */
      |               ? != 0
      |           AND (
      |                    Clazz.clazzOwnerPersonUid = ?
      |                 OR EXISTS(SELECT CoursePermission.cpUid
      |                             FROM CoursePermission
      |                            WHERE CoursePermission.cpClazzUid = Clazz.clazzUid
      |                              AND (   CoursePermission.cpToPersonUid = ? 
      |                                   OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment.clazzEnrolmentRole )
      |                              AND (CoursePermission.cpPermissionsFlag & ?) > 0 
      |                              AND NOT CoursePermission.cpIsDeleted)   
      |                 OR (
      |        SELECT 
      |        EXISTS(SELECT 1
      |                 FROM SystemPermission
      |                WHERE ? != 0 
      |                  AND SystemPermission.spToPersonUid = ?
      |                  AND (SystemPermission.spPermissionsFlag &
      |    
      |          ?
      |        
      |        ) > 0
      |                  AND NOT SystemPermission.spIsDeleted)
      |      
      |    )             
      |                )
      |                /* End permission check clause */ 
      |           AND CAST(Clazz.isClazzActive AS INTEGER) = 1
      |           AND Clazz.clazzName like ?
      |           AND (Clazz.clazzUid NOT IN (?))
      |           AND ( ? = 0 OR (CASE WHEN ? = 5 
      |                                      THEN ? BETWEEN Clazz.clazzStartTime AND Clazz.clazzEndTime
      |                                      ELSE ? > Clazz.clazzEndTime 
      |                                      END))
      |      GROUP BY Clazz.clazzUid, ClazzEnrolment.clazzEnrolmentUid, CourseTerminology.ctUid, CoursePicture.coursePictureUid
      |      ORDER BY CASE ?
      |               WHEN 3 THEN Clazz.attendanceAverage
      |               ELSE 0
      |               END ASC,
      |               CASE ?
      |               WHEN 1 THEN Clazz.clazzName
      |               ELSE ''
      |               END ASC,
      |               CASE ?
      |               WHEN 4 THEN Clazz.attendanceAverage
      |               ELSE 0
      |               END DESC,
      |               CASE ?
      |               WHEN 2 THEN clazz.Clazzname
      |               ELSE ''
      |               END DESC
      |    ) AS _PagingData LIMIT ? OFFSET ?
      """.trimMargin(),
      hasListParams = true,
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,currentTime)
      _stmt.setLong(2,currentTime)
      _stmt.setLong(3,accountPersonUid)
      _stmt.setLong(4,accountPersonUid)
      _stmt.setLong(5,accountPersonUid)
      _stmt.setLong(6,accountPersonUid)
      _stmt.setLong(7,permission)
      _stmt.setLong(8,accountPersonUid)
      _stmt.setLong(9,accountPersonUid)
      _stmt.setLong(10,permission)
      _stmt.setString(11,searchQuery)
      _stmt.setArray(12, _stmt.getConnection().createArrayOrProxyArrayOf("BIGINT",
          excludeSelectedClazzList.toTypedArray()))
      _stmt.setInt(13,filter)
      _stmt.setInt(14,filter)
      _stmt.setLong(15,currentTime)
      _stmt.setLong(16,currentTime)
      _stmt.setInt(17,sortOrder)
      _stmt.setInt(18,sortOrder)
      _stmt.setInt(19,sortOrder)
      _stmt.setInt(20,sortOrder)
      _stmt.setInt(21,_limit)
      _stmt.setInt(22,_offset)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapRows {
          val _tmp_numStudents = _result.getInt("numStudents")
          val _tmp_numTeachers = _result.getInt("numTeachers")
          val _tmp_teacherNames = _result.getString("teacherNames")
          val _tmp_lastRecorded = _result.getLong("lastRecorded")
          val _tmp_clazzUid = _result.getLong("clazzUid")
          val _tmp_clazzName = _result.getString("clazzName")
          val _tmp_clazzDesc = _result.getString("clazzDesc")
          val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
          val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
          val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
          val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
          val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
          val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
          val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
          val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
          val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
          val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
          val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
          val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
          val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
          val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
          val _tmp_clazzLct = _result.getLong("clazzLct")
          val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
          val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
          val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
          val _tmp_clazzPendingStudentsPersonGroupUid =
              _result.getLong("clazzPendingStudentsPersonGroupUid")
          val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
          val _tmp_clazzCode = _result.getString("clazzCode")
          val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
          var _tmp_ClazzEnrolment_nullCount = 0
          val _tmp_clazzEnrolmentUid = _result.getLong("clazzEnrolmentUid")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentPersonUid = _result.getLong("clazzEnrolmentPersonUid")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentClazzUid = _result.getLong("clazzEnrolmentClazzUid")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentDateJoined = _result.getLong("clazzEnrolmentDateJoined")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentDateLeft = _result.getLong("clazzEnrolmentDateLeft")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentRole = _result.getInt("clazzEnrolmentRole")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentAttendancePercentage =
              _result.getFloat("clazzEnrolmentAttendancePercentage")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentActive = _result.getBoolean("clazzEnrolmentActive")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentLeavingReasonUid =
              _result.getLong("clazzEnrolmentLeavingReasonUid")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentOutcome = _result.getInt("clazzEnrolmentOutcome")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentLocalChangeSeqNum =
              _result.getLong("clazzEnrolmentLocalChangeSeqNum")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentMasterChangeSeqNum =
              _result.getLong("clazzEnrolmentMasterChangeSeqNum")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentLastChangedBy = _result.getInt("clazzEnrolmentLastChangedBy")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentLct = _result.getLong("clazzEnrolmentLct")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_clazzEnrolmentInviteUid = _result.getLong("clazzEnrolmentInviteUid")
          if(_result.wasNull()) _tmp_ClazzEnrolment_nullCount++
          val _tmp_ClazzEnrolment_isAllNull = _tmp_ClazzEnrolment_nullCount == 15
          var _tmp_CourseTerminology_nullCount = 0
          val _tmp_ctUid = _result.getLong("ctUid")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctTitle = _result.getString("ctTitle")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctTerminology = _result.getString("ctTerminology")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctLct = _result.getLong("ctLct")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_CourseTerminology_isAllNull = _tmp_CourseTerminology_nullCount == 4
          var _tmp_CoursePicture_nullCount = 0
          val _tmp_coursePictureUid = _result.getLong("coursePictureUid")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureLct = _result.getLong("coursePictureLct")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureUri = _result.getString("coursePictureUri")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureThumbnailUri = _result.getString("coursePictureThumbnailUri")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureActive = _result.getBoolean("coursePictureActive")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_CoursePicture_isAllNull = _tmp_CoursePicture_nullCount == 5
          ClazzWithListDisplayDetails().apply {
            this.numStudents = _tmp_numStudents
            this.numTeachers = _tmp_numTeachers
            this.teacherNames = _tmp_teacherNames
            this.lastRecorded = _tmp_lastRecorded
            this.clazzUid = _tmp_clazzUid
            this.clazzName = _tmp_clazzName
            this.clazzDesc = _tmp_clazzDesc
            this.attendanceAverage = _tmp_attendanceAverage
            this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
            this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
            this.isClazzActive = _tmp_isClazzActive
            this.clazzLocationUid = _tmp_clazzLocationUid
            this.clazzStartTime = _tmp_clazzStartTime
            this.clazzEndTime = _tmp_clazzEndTime
            this.clazzFeatures = _tmp_clazzFeatures
            this.clazzSchoolUid = _tmp_clazzSchoolUid
            this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
            this.clazzTerminologyUid = _tmp_clazzTerminologyUid
            this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
            this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
            this.clazzLastChangedBy = _tmp_clazzLastChangedBy
            this.clazzLct = _tmp_clazzLct
            this.clazzTimeZone = _tmp_clazzTimeZone
            this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
            this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
            this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
            this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
            this.clazzCode = _tmp_clazzCode
            this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
            if(!_tmp_ClazzEnrolment_isAllNull) {
              this.clazzActiveEnrolment = ClazzEnrolment().apply {
                this.clazzEnrolmentUid = _tmp_clazzEnrolmentUid
                this.clazzEnrolmentPersonUid = _tmp_clazzEnrolmentPersonUid
                this.clazzEnrolmentClazzUid = _tmp_clazzEnrolmentClazzUid
                this.clazzEnrolmentDateJoined = _tmp_clazzEnrolmentDateJoined
                this.clazzEnrolmentDateLeft = _tmp_clazzEnrolmentDateLeft
                this.clazzEnrolmentRole = _tmp_clazzEnrolmentRole
                this.clazzEnrolmentAttendancePercentage = _tmp_clazzEnrolmentAttendancePercentage
                this.clazzEnrolmentActive = _tmp_clazzEnrolmentActive
                this.clazzEnrolmentLeavingReasonUid = _tmp_clazzEnrolmentLeavingReasonUid
                this.clazzEnrolmentOutcome = _tmp_clazzEnrolmentOutcome
                this.clazzEnrolmentLocalChangeSeqNum = _tmp_clazzEnrolmentLocalChangeSeqNum
                this.clazzEnrolmentMasterChangeSeqNum = _tmp_clazzEnrolmentMasterChangeSeqNum
                this.clazzEnrolmentLastChangedBy = _tmp_clazzEnrolmentLastChangedBy
                this.clazzEnrolmentLct = _tmp_clazzEnrolmentLct
                this.clazzEnrolmentInviteUid = _tmp_clazzEnrolmentInviteUid
              }
            }
            if(!_tmp_CourseTerminology_isAllNull) {
              this.terminology = CourseTerminology().apply {
                this.ctUid = _tmp_ctUid
                this.ctTitle = _tmp_ctTitle
                this.ctTerminology = _tmp_ctTerminology
                this.ctLct = _tmp_ctLct
              }
            }
            if(!_tmp_CoursePicture_isAllNull) {
              this.coursePicture = CoursePicture().apply {
                this.coursePictureUid = _tmp_coursePictureUid
                this.coursePictureLct = _tmp_coursePictureLct
                this.coursePictureUri = _tmp_coursePictureUri
                this.coursePictureThumbnailUri = _tmp_coursePictureThumbnailUri
                this.coursePictureActive = _tmp_coursePictureActive
              }
            }
          }
        }
      }
    }

    override suspend fun countRows(): Int = _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |SELECT COUNT(*) FROM (
      |        SELECT Clazz.*, ClazzEnrolment.*, CoursePicture.*,
      |               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) 
      |                  FROM ClazzEnrolment 
      |                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                   AND clazzEnrolmentRole = 1000 
      |                   AND ? BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined 
      |                       AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numStudents,
      |               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) 
      |                  FROM ClazzEnrolment 
      |                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                   AND clazzEnrolmentRole = 1001
      |                   AND ? BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined 
      |                        AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numTeachers,
      |               '' AS teacherNames,
      |               0 AS lastRecorded,
      |               CourseTerminology.*
      |          FROM Clazz
      |               LEFT JOIN ClazzEnrolment 
      |                    ON ClazzEnrolment.clazzEnrolmentUid =
      |                       COALESCE(
      |                       (SELECT ClazzEnrolment.clazzEnrolmentUid 
      |                          FROM ClazzEnrolment
      |                         WHERE ClazzEnrolment.clazzEnrolmentPersonUid = ?
      |                           AND ClazzEnrolment.clazzEnrolmentActive
      |                           AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                      ORDER BY ClazzEnrolment.clazzEnrolmentDateLeft DESC   
      |                         LIMIT 1), 0)
      |                LEFT JOIN CourseTerminology   
      |                          ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid
      |                LEFT JOIN CoursePicture
      |                          ON CoursePicture.coursePictureUid = Clazz.clazzUid           
      |
      |         WHERE /* Begin permission check clause */
      |               ? != 0
      |           AND (
      |                    Clazz.clazzOwnerPersonUid = ?
      |                 OR EXISTS(SELECT CoursePermission.cpUid
      |                             FROM CoursePermission
      |                            WHERE CoursePermission.cpClazzUid = Clazz.clazzUid
      |                              AND (   CoursePermission.cpToPersonUid = ? 
      |                                   OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment.clazzEnrolmentRole )
      |                              AND (CoursePermission.cpPermissionsFlag & ?) > 0 
      |                              AND NOT CoursePermission.cpIsDeleted)   
      |                 OR (
      |        SELECT 
      |        EXISTS(SELECT 1
      |                 FROM SystemPermission
      |                WHERE ? != 0 
      |                  AND SystemPermission.spToPersonUid = ?
      |                  AND (SystemPermission.spPermissionsFlag &
      |    
      |          ?
      |        
      |        ) > 0
      |                  AND NOT SystemPermission.spIsDeleted)
      |      
      |    )             
      |                )
      |                /* End permission check clause */ 
      |           AND CAST(Clazz.isClazzActive AS INTEGER) = 1
      |           AND Clazz.clazzName like ?
      |           AND (Clazz.clazzUid NOT IN (?))
      |           AND ( ? = 0 OR (CASE WHEN ? = 5 
      |                                      THEN ? BETWEEN Clazz.clazzStartTime AND Clazz.clazzEndTime
      |                                      ELSE ? > Clazz.clazzEndTime 
      |                                      END))
      |      GROUP BY Clazz.clazzUid, ClazzEnrolment.clazzEnrolmentUid, CourseTerminology.ctUid, CoursePicture.coursePictureUid
      |      ORDER BY CASE ?
      |               WHEN 3 THEN Clazz.attendanceAverage
      |               ELSE 0
      |               END ASC,
      |               CASE ?
      |               WHEN 1 THEN Clazz.clazzName
      |               ELSE ''
      |               END ASC,
      |               CASE ?
      |               WHEN 4 THEN Clazz.attendanceAverage
      |               ELSE 0
      |               END DESC,
      |               CASE ?
      |               WHEN 2 THEN clazz.Clazzname
      |               ELSE ''
      |               END DESC
      |    ) AS _PagingCount
      """.trimMargin(),
      hasListParams = true,
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,currentTime)
      _stmt.setLong(2,currentTime)
      _stmt.setLong(3,accountPersonUid)
      _stmt.setLong(4,accountPersonUid)
      _stmt.setLong(5,accountPersonUid)
      _stmt.setLong(6,accountPersonUid)
      _stmt.setLong(7,permission)
      _stmt.setLong(8,accountPersonUid)
      _stmt.setLong(9,accountPersonUid)
      _stmt.setLong(10,permission)
      _stmt.setString(11,searchQuery)
      _stmt.setArray(12, _stmt.getConnection().createArrayOrProxyArrayOf("BIGINT",
          excludeSelectedClazzList.toTypedArray()))
      _stmt.setInt(13,filter)
      _stmt.setInt(14,filter)
      _stmt.setLong(15,currentTime)
      _stmt.setLong(16,currentTime)
      _stmt.setInt(17,sortOrder)
      _stmt.setInt(18,sortOrder)
      _stmt.setInt(19,sortOrder)
      _stmt.setInt(20,sortOrder)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(0) {
          _result.getInt(1)
        }
      }
    }
  }

  override suspend fun getClassNamesFromListOfIds(ids: List<Long>): List<UidAndLabel> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql =
        "SELECT Clazz.clazzUid AS uid, Clazz.clazzName AS labelName From Clazz WHERE clazzUid IN (?)",
    hasListParams = true,
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setArray(1, _stmt.getConnection().createArrayOrProxyArrayOf("BIGINT", ids.toTypedArray()))
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_uid = _result.getLong("uid")
        val _tmp_labelName = _result.getString("labelName")
        UidAndLabel().apply {
          this.uid = _tmp_uid
          this.labelName = _tmp_labelName
        }
      }
    }
  }

  override fun findByClazzName(name: String): List<Clazz> =
      _db.prepareAndUseStatement(PreparedStatementConfig(
    sql = "SELECT * FROM Clazz WHERE clazzName = ? and CAST(isClazzActive AS INTEGER) = 1",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setString(1,name)
    _stmt.executeQuery().useResults{ _result -> 
      _result.mapRows {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override suspend fun updateClazzAttendanceAverageAsync(clazzUid: Long, timeChanged: Long) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |
      |        UPDATE Clazz 
      |           SET attendanceAverage = 
      |               COALESCE(CAST(
      |                    (SELECT SUM(clazzLogNumPresent) 
      |                       FROM ClazzLog 
      |                      WHERE clazzLogClazzUid = ?
      |                       AND clazzLogStatusFlag = 4) AS REAL) /
      |                    
      |                    CAST(MAX(1.0, 
      |                        (SELECT SUM(clazzLogNumPresent) + SUM(clazzLogNumPartial) + SUM(clazzLogNumAbsent)
      |                        FROM ClazzLog 
      |                       WHERE clazzLogClazzUid = ? 
      |                        AND clazzLogStatusFlag = 4)) AS REAL), 0),
      |               clazzLct = ?         
      |         WHERE clazzUid = ?
      |    
      """.trimMargin(),
      postgreSql = """
      |
      |        UPDATE Clazz 
      |           SET attendanceAverage = 
      |               COALESCE(CAST(
      |                    (SELECT SUM(clazzLogNumPresent) 
      |                       FROM ClazzLog 
      |                      WHERE clazzLogClazzUid = ?
      |                       AND clazzLogStatusFlag = 4) AS REAL) /
      |                    
      |                    CAST(GREATEST(1.0, 
      |                        (SELECT SUM(clazzLogNumPresent) + SUM(clazzLogNumPartial) + SUM(clazzLogNumAbsent)
      |                        FROM ClazzLog 
      |                       WHERE clazzLogClazzUid = ? 
      |                        AND clazzLogStatusFlag = 4)) AS REAL), 0),
      |               clazzLct = ?         
      |         WHERE clazzUid = ?
      |    
      """.trimMargin(),
      readOnly = false,)
    ) { _stmt -> 
      _stmt.setLong(1,clazzUid)
      _stmt.setLong(2,clazzUid)
      _stmt.setLong(3,timeChanged)
      _stmt.setLong(4,clazzUid)
      _stmt.executeUpdateAsyncKmp()
    }
  }

  override fun clazzAndDetailPermissionsAsFlow(accountPersonUid: Long, clazzUid: Long):
      Flow<ClazzAndDetailPermissions?> = _db.doorFlow(arrayOf("Clazz", "CoursePermission",
      "ClazzEnrolment", "SystemPermission")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |
      |        SELECT Clazz.*,
      |               (  (
      |             /* If the accountPersonUid is the owner of the course, all permissions are granted */
      |             (COALESCE(
      |                          (SELECT _Clazz_Permission.clazzOwnerPersonUid 
      |                             FROM Clazz _Clazz_Permission
      |                            WHERE _Clazz_Permission.clazzUid = ?), 0) = ?)
      |              /* 
      |              If there is a CoursePermission entity that is for the course as per the clazzUid
      |              parameter that is granted to the person directly or to the enrolmentRole that the 
      |              person has in the course, then permission is granted.
      |              */              
      |              OR EXISTS(SELECT CoursePermission.cpUid
      |                          FROM CoursePermission
      |                               
      |        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson 
      |                        ON CoursePermission.cpToEnrolmentRole != 0
      |                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = 
      |                           (SELECT COALESCE(
      |                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid 
      |                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner
      |                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = ?
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive
      |                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   
      |                                     LIMIT 1), 0))
      |    
      |                         WHERE CoursePermission.cpClazzUid = ?
      |                           AND (CoursePermission.cpToPersonUid = ? 
      |                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)
      |                           AND (CoursePermission.cpPermissionsFlag & 
      |         
      |                  32
      |                  
      |        ) > 0)
      |              OR EXISTS(SELECT SystemPermission.spUid
      |                          FROM SystemPermission
      |                         WHERE SystemPermission.spToPersonUid = ?
      |                           AND (SystemPermission.spPermissionsFlag & 
      |    
      |                  32
      |                  
      |        ) > 0)
      |               )
      |    
      |               ) AS hasAttendancePermission,
      |               (  (
      |             /* If the accountPersonUid is the owner of the course, all permissions are granted */
      |             (COALESCE(
      |                          (SELECT _Clazz_Permission.clazzOwnerPersonUid 
      |                             FROM Clazz _Clazz_Permission
      |                            WHERE _Clazz_Permission.clazzUid = ?), 0) = ?)
      |              /* 
      |              If there is a CoursePermission entity that is for the course as per the clazzUid
      |              parameter that is granted to the person directly or to the enrolmentRole that the 
      |              person has in the course, then permission is granted.
      |              */              
      |              OR EXISTS(SELECT CoursePermission.cpUid
      |                          FROM CoursePermission
      |                               
      |        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson 
      |                        ON CoursePermission.cpToEnrolmentRole != 0
      |                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = 
      |                           (SELECT COALESCE(
      |                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid 
      |                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner
      |                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = ?
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive
      |                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   
      |                                     LIMIT 1), 0))
      |    
      |                         WHERE CoursePermission.cpClazzUid = ?
      |                           AND (CoursePermission.cpToPersonUid = ? 
      |                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)
      |                           AND (CoursePermission.cpPermissionsFlag & 
      |         
      |                  8192
      |                  
      |        ) > 0)
      |              OR EXISTS(SELECT SystemPermission.spUid
      |                          FROM SystemPermission
      |                         WHERE SystemPermission.spToPersonUid = ?
      |                           AND (SystemPermission.spPermissionsFlag & 
      |    
      |                  8192
      |                  
      |        ) > 0)
      |               )
      |    
      |               ) AS hasViewMembersPermission,
      |               (  (
      |             /* If the accountPersonUid is the owner of the course, all permissions are granted */
      |             (COALESCE(
      |                          (SELECT _Clazz_Permission.clazzOwnerPersonUid 
      |                             FROM Clazz _Clazz_Permission
      |                            WHERE _Clazz_Permission.clazzUid = ?), 0) = ?)
      |              /* 
      |              If there is a CoursePermission entity that is for the course as per the clazzUid
      |              parameter that is granted to the person directly or to the enrolmentRole that the 
      |              person has in the course, then permission is granted.
      |              */              
      |              OR EXISTS(SELECT CoursePermission.cpUid
      |                          FROM CoursePermission
      |                               
      |        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson 
      |                        ON CoursePermission.cpToEnrolmentRole != 0
      |                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = 
      |                           (SELECT COALESCE(
      |                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid 
      |                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner
      |                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = ?
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive
      |                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   
      |                                     LIMIT 1), 0))
      |    
      |                         WHERE CoursePermission.cpClazzUid = ?
      |                           AND (CoursePermission.cpToPersonUid = ? 
      |                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)
      |                           AND (CoursePermission.cpPermissionsFlag & 
      |         
      |                  128
      |                  
      |        ) > 0)
      |              OR EXISTS(SELECT SystemPermission.spUid
      |                          FROM SystemPermission
      |                         WHERE SystemPermission.spToPersonUid = ?
      |                           AND (SystemPermission.spPermissionsFlag & 
      |    
      |                  128
      |                  
      |        ) > 0)
      |               )
      |    
      |               ) AS hasLearningRecordPermission
      |          FROM Clazz
      |         WHERE Clazz.clazzUid = ?
      |           AND (  (
      |             /* If the accountPersonUid is the owner of the course, all permissions are granted */
      |             (COALESCE(
      |                          (SELECT _Clazz_Permission.clazzOwnerPersonUid 
      |                             FROM Clazz _Clazz_Permission
      |                            WHERE _Clazz_Permission.clazzUid = ?), 0) = ?)
      |              /* 
      |              If there is a CoursePermission entity that is for the course as per the clazzUid
      |              parameter that is granted to the person directly or to the enrolmentRole that the 
      |              person has in the course, then permission is granted.
      |              */              
      |              OR EXISTS(SELECT CoursePermission.cpUid
      |                          FROM CoursePermission
      |                               
      |        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson 
      |                        ON CoursePermission.cpToEnrolmentRole != 0
      |                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = 
      |                           (SELECT COALESCE(
      |                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid 
      |                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner
      |                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = ?
      |                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive
      |                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   
      |                                     LIMIT 1), 0))
      |    
      |                         WHERE CoursePermission.cpClazzUid = ?
      |                           AND (CoursePermission.cpToPersonUid = ? 
      |                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)
      |                           AND (CoursePermission.cpPermissionsFlag & 
      |         
      |                  1
      |                  
      |        ) > 0)
      |              OR EXISTS(SELECT SystemPermission.spUid
      |                          FROM SystemPermission
      |                         WHERE SystemPermission.spToPersonUid = ?
      |                           AND (SystemPermission.spPermissionsFlag & 
      |    
      |                  1
      |                  
      |        ) > 0)
      |               )
      |    
      |               )
      |    
      """.trimMargin(),
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,clazzUid)
      _stmt.setLong(2,accountPersonUid)
      _stmt.setLong(3,accountPersonUid)
      _stmt.setLong(4,clazzUid)
      _stmt.setLong(5,accountPersonUid)
      _stmt.setLong(6,accountPersonUid)
      _stmt.setLong(7,clazzUid)
      _stmt.setLong(8,accountPersonUid)
      _stmt.setLong(9,accountPersonUid)
      _stmt.setLong(10,clazzUid)
      _stmt.setLong(11,accountPersonUid)
      _stmt.setLong(12,accountPersonUid)
      _stmt.setLong(13,clazzUid)
      _stmt.setLong(14,accountPersonUid)
      _stmt.setLong(15,accountPersonUid)
      _stmt.setLong(16,clazzUid)
      _stmt.setLong(17,accountPersonUid)
      _stmt.setLong(18,accountPersonUid)
      _stmt.setLong(19,clazzUid)
      _stmt.setLong(20,clazzUid)
      _stmt.setLong(21,accountPersonUid)
      _stmt.setLong(22,accountPersonUid)
      _stmt.setLong(23,clazzUid)
      _stmt.setLong(24,accountPersonUid)
      _stmt.setLong(25,accountPersonUid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          val _tmp_hasAttendancePermission = _result.getBoolean("hasAttendancePermission")
          val _tmp_hasViewMembersPermission = _result.getBoolean("hasViewMembersPermission")
          val _tmp_hasLearningRecordPermission = _result.getBoolean("hasLearningRecordPermission")
          var _tmp_Clazz_nullCount = 0
          val _tmp_clazzUid = _result.getLong("clazzUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzName = _result.getString("clazzName")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzDesc = _result.getString("clazzDesc")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLct = _result.getLong("clazzLct")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzPendingStudentsPersonGroupUid =
              _result.getLong("clazzPendingStudentsPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzCode = _result.getString("clazzCode")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_Clazz_isAllNull = _tmp_Clazz_nullCount == 25
          ClazzAndDetailPermissions().apply {
            this.hasAttendancePermission = _tmp_hasAttendancePermission
            this.hasViewMembersPermission = _tmp_hasViewMembersPermission
            this.hasLearningRecordPermission = _tmp_hasLearningRecordPermission
            if(!_tmp_Clazz_isAllNull) {
              this.clazz = Clazz().apply {
                this.clazzUid = _tmp_clazzUid
                this.clazzName = _tmp_clazzName
                this.clazzDesc = _tmp_clazzDesc
                this.attendanceAverage = _tmp_attendanceAverage
                this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
                this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
                this.isClazzActive = _tmp_isClazzActive
                this.clazzLocationUid = _tmp_clazzLocationUid
                this.clazzStartTime = _tmp_clazzStartTime
                this.clazzEndTime = _tmp_clazzEndTime
                this.clazzFeatures = _tmp_clazzFeatures
                this.clazzSchoolUid = _tmp_clazzSchoolUid
                this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
                this.clazzTerminologyUid = _tmp_clazzTerminologyUid
                this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
                this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
                this.clazzLastChangedBy = _tmp_clazzLastChangedBy
                this.clazzLct = _tmp_clazzLct
                this.clazzTimeZone = _tmp_clazzTimeZone
                this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
                this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
                this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
                this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
                this.clazzCode = _tmp_clazzCode
                this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
              }
            }
          }
        }
      }
    }
  }

  override fun getClazzWithDisplayDetails(
    clazzUid: Long,
    currentTime: Long,
    accountPersonUid: Long,
  ): Flow<ClazzAndDisplayDetails?> = _db.doorFlow(arrayOf("CourseTerminology", "Clazz",
      "CoursePicture", "ClazzEnrolment")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |
      |        SELECT Clazz.*, 
      |               CoursePicture.*,
      |               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) 
      |                  FROM ClazzEnrolment 
      |                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                   AND clazzEnrolmentRole = 1000 
      |                   AND ? BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined 
      |                        AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numStudents,
      |               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) 
      |                  FROM ClazzEnrolment 
      |                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
      |                   AND clazzEnrolmentRole = 1001 
      |                   AND ? BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined 
      |                       AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numTeachers,
      |                CourseTerminology.*,
      |                (SELECT EXISTS(
      |                        SELECT 1
      |                          FROM ClazzEnrolment
      |                         WHERE ClazzEnrolment.clazzEnrolmentClazzUid = ?
      |                           AND ClazzEnrolment.clazzEnrolmentPersonUid = ?
      |                           AND ClazzEnrolment.clazzEnrolmentRole = 1000
      |)
      |                ) AS activeUserIsStudent
      |         FROM Clazz 
      |              LEFT JOIN CourseTerminology
      |                        ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid
      |              LEFT JOIN CoursePicture
      |                        ON CoursePicture.coursePictureUid = ?
      |        WHERE Clazz.clazzUid = ?
      """.trimMargin(),
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,currentTime)
      _stmt.setLong(2,currentTime)
      _stmt.setLong(3,clazzUid)
      _stmt.setLong(4,accountPersonUid)
      _stmt.setLong(5,clazzUid)
      _stmt.setLong(6,clazzUid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          val _tmp_numStudents = _result.getInt("numStudents")
          val _tmp_numTeachers = _result.getInt("numTeachers")
          val _tmp_activeUserIsStudent = _result.getBoolean("activeUserIsStudent")
          var _tmp_Clazz_nullCount = 0
          val _tmp_clazzUid = _result.getLong("clazzUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzName = _result.getString("clazzName")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzDesc = _result.getString("clazzDesc")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzLct = _result.getLong("clazzLct")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzPendingStudentsPersonGroupUid =
              _result.getLong("clazzPendingStudentsPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzCode = _result.getString("clazzCode")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
          if(_result.wasNull()) _tmp_Clazz_nullCount++
          val _tmp_Clazz_isAllNull = _tmp_Clazz_nullCount == 25
          var _tmp_CourseTerminology_nullCount = 0
          val _tmp_ctUid = _result.getLong("ctUid")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctTitle = _result.getString("ctTitle")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctTerminology = _result.getString("ctTerminology")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctLct = _result.getLong("ctLct")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_CourseTerminology_isAllNull = _tmp_CourseTerminology_nullCount == 4
          var _tmp_CoursePicture_nullCount = 0
          val _tmp_coursePictureUid = _result.getLong("coursePictureUid")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureLct = _result.getLong("coursePictureLct")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureUri = _result.getString("coursePictureUri")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureThumbnailUri = _result.getString("coursePictureThumbnailUri")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_coursePictureActive = _result.getBoolean("coursePictureActive")
          if(_result.wasNull()) _tmp_CoursePicture_nullCount++
          val _tmp_CoursePicture_isAllNull = _tmp_CoursePicture_nullCount == 5
          ClazzAndDisplayDetails().apply {
            this.numStudents = _tmp_numStudents
            this.numTeachers = _tmp_numTeachers
            this.activeUserIsStudent = _tmp_activeUserIsStudent
            if(!_tmp_Clazz_isAllNull) {
              this.clazz = Clazz().apply {
                this.clazzUid = _tmp_clazzUid
                this.clazzName = _tmp_clazzName
                this.clazzDesc = _tmp_clazzDesc
                this.attendanceAverage = _tmp_attendanceAverage
                this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
                this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
                this.isClazzActive = _tmp_isClazzActive
                this.clazzLocationUid = _tmp_clazzLocationUid
                this.clazzStartTime = _tmp_clazzStartTime
                this.clazzEndTime = _tmp_clazzEndTime
                this.clazzFeatures = _tmp_clazzFeatures
                this.clazzSchoolUid = _tmp_clazzSchoolUid
                this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
                this.clazzTerminologyUid = _tmp_clazzTerminologyUid
                this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
                this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
                this.clazzLastChangedBy = _tmp_clazzLastChangedBy
                this.clazzLct = _tmp_clazzLct
                this.clazzTimeZone = _tmp_clazzTimeZone
                this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
                this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
                this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
                this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
                this.clazzCode = _tmp_clazzCode
                this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
              }
            }
            if(!_tmp_CourseTerminology_isAllNull) {
              this.terminology = CourseTerminology().apply {
                this.ctUid = _tmp_ctUid
                this.ctTitle = _tmp_ctTitle
                this.ctTerminology = _tmp_ctTerminology
                this.ctLct = _tmp_ctLct
              }
            }
            if(!_tmp_CoursePicture_isAllNull) {
              this.coursePicture = CoursePicture().apply {
                this.coursePictureUid = _tmp_coursePictureUid
                this.coursePictureLct = _tmp_coursePictureLct
                this.coursePictureUri = _tmp_coursePictureUri
                this.coursePictureThumbnailUri = _tmp_coursePictureThumbnailUri
                this.coursePictureActive = _tmp_coursePictureActive
              }
            }
          }
        }
      }
    }
  }

  override fun findClazzesWithEffectiveHolidayCalendarAndFilter(filterUid: Long):
      List<ClazzWithHolidayCalendarAndAndTerminology> =
      _db.prepareAndUseStatement(PreparedStatementConfig(
    sql = """
    |
    |        SELECT Clazz.*, 
    |               HolidayCalendar.*,
    |               CourseTerminology.*,
    |               CoursePicture.*
    |         FROM Clazz 
    |              LEFT JOIN HolidayCalendar 
    |              ON ((clazz.clazzHolidayUMCalendarUid != 0 
    |                AND HolidayCalendar.umCalendarUid = clazz.clazzHolidayUMCalendarUid)
    |                OR clazz.clazzHolidayUMCalendarUid = 0 AND clazz.clazzSchoolUid = 0 
    |                AND HolidayCalendar.umCalendarUid = 0) 
    |              LEFT JOIN CourseTerminology
    |              ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid
    |              
    |              LEFT JOIN CoursePicture
    |                        ON CoursePicture.coursePictureUid = 0
    |                
    |        WHERE ? = 0 
    |           OR Clazz.clazzUid = ?
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,filterUid)
    _stmt.setLong(2,filterUid)
    _stmt.executeQuery().useResults{ _result -> 
      _result.mapRows {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        var _tmp_HolidayCalendar_nullCount = 0
        val _tmp_umCalendarUid = _result.getLong("umCalendarUid")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarName = _result.getString("umCalendarName")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarCategory = _result.getInt("umCalendarCategory")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarActive = _result.getBoolean("umCalendarActive")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarMasterChangeSeqNum = _result.getLong("umCalendarMasterChangeSeqNum")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarLocalChangeSeqNum = _result.getLong("umCalendarLocalChangeSeqNum")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarLastChangedBy = _result.getInt("umCalendarLastChangedBy")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_umCalendarLct = _result.getLong("umCalendarLct")
        if(_result.wasNull()) _tmp_HolidayCalendar_nullCount++
        val _tmp_HolidayCalendar_isAllNull = _tmp_HolidayCalendar_nullCount == 8
        var _tmp_CourseTerminology_nullCount = 0
        val _tmp_ctUid = _result.getLong("ctUid")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_ctTitle = _result.getString("ctTitle")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_ctTerminology = _result.getString("ctTerminology")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_ctLct = _result.getLong("ctLct")
        if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
        val _tmp_CourseTerminology_isAllNull = _tmp_CourseTerminology_nullCount == 4
        var _tmp_CoursePicture_nullCount = 0
        val _tmp_coursePictureUid = _result.getLong("coursePictureUid")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureLct = _result.getLong("coursePictureLct")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureUri = _result.getString("coursePictureUri")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureThumbnailUri = _result.getString("coursePictureThumbnailUri")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_coursePictureActive = _result.getBoolean("coursePictureActive")
        if(_result.wasNull()) _tmp_CoursePicture_nullCount++
        val _tmp_CoursePicture_isAllNull = _tmp_CoursePicture_nullCount == 5
        ClazzWithHolidayCalendarAndAndTerminology().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
          if(!_tmp_HolidayCalendar_isAllNull) {
            this.holidayCalendar = HolidayCalendar().apply {
              this.umCalendarUid = _tmp_umCalendarUid
              this.umCalendarName = _tmp_umCalendarName
              this.umCalendarCategory = _tmp_umCalendarCategory
              this.umCalendarActive = _tmp_umCalendarActive
              this.umCalendarMasterChangeSeqNum = _tmp_umCalendarMasterChangeSeqNum
              this.umCalendarLocalChangeSeqNum = _tmp_umCalendarLocalChangeSeqNum
              this.umCalendarLastChangedBy = _tmp_umCalendarLastChangedBy
              this.umCalendarLct = _tmp_umCalendarLct
            }
          }
          if(!_tmp_CourseTerminology_isAllNull) {
            this.terminology = CourseTerminology().apply {
              this.ctUid = _tmp_ctUid
              this.ctTitle = _tmp_ctTitle
              this.ctTerminology = _tmp_ctTerminology
              this.ctLct = _tmp_ctLct
            }
          }
          if(!_tmp_CoursePicture_isAllNull) {
            this.coursePicture = CoursePicture().apply {
              this.coursePictureUid = _tmp_coursePictureUid
              this.coursePictureLct = _tmp_coursePictureLct
              this.coursePictureUri = _tmp_coursePictureUri
              this.coursePictureThumbnailUri = _tmp_coursePictureThumbnailUri
              this.coursePictureActive = _tmp_coursePictureActive
            }
          }
        }
      }
    }
  }

  override fun getTitleByUidAsFlow(clazzUid: Long): Flow<String?> = _db.doorFlow(arrayOf("Clazz")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |
      |        SELECT Clazz.clazzName
      |          FROM Clazz
      |         WHERE Clazz.clazzUid = ?
      |    
      """.trimMargin(),
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,clazzUid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          _result.getString(1)
        }
      }
    }
  }

  override fun getClazzNameAndTerminologyAsFlow(clazzUid: Long): Flow<ClazzNameAndTerminology?> =
      _db.doorFlow(arrayOf("CourseTerminology", "Clazz")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |
      |        SELECT Clazz.clazzName AS clazzName,
      |               CourseTerminology.*
      |          FROM Clazz
      |               LEFT JOIN CourseTerminology
      |                         ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid
      |         WHERE Clazz.clazzUid = ?                
      |    
      """.trimMargin(),
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,clazzUid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          val _tmp_clazzName = _result.getString("clazzName")
          var _tmp_CourseTerminology_nullCount = 0
          val _tmp_ctUid = _result.getLong("ctUid")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctTitle = _result.getString("ctTitle")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctTerminology = _result.getString("ctTerminology")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_ctLct = _result.getLong("ctLct")
          if(_result.wasNull()) _tmp_CourseTerminology_nullCount++
          val _tmp_CourseTerminology_isAllNull = _tmp_CourseTerminology_nullCount == 4
          ClazzNameAndTerminology().apply {
            this.clazzName = _tmp_clazzName
            if(!_tmp_CourseTerminology_isAllNull) {
              this.terminology = CourseTerminology().apply {
                this.ctUid = _tmp_ctUid
                this.ctTitle = _tmp_ctTitle
                this.ctTerminology = _tmp_ctTerminology
                this.ctLct = _tmp_ctLct
              }
            }
          }
        }
      }
    }
  }

  override fun getClazzNameAsFlow(clazzUid: Long): Flow<String?> = _db.doorFlow(arrayOf("Clazz")) {
    _db.prepareAndUseStatementAsync(PreparedStatementConfig(
      sql = """
      |
      |        SELECT Clazz.clazzName AS clazzName
      |          FROM Clazz
      |         WHERE Clazz.clazzUid = ?                
      |    
      """.trimMargin(),
      readOnly = true,)
    ) { _stmt -> 
      _stmt.setLong(1,clazzUid)
      _stmt.executeQueryAsyncKmp().useResults{ _result -> 
        _result.mapNextRow(null) {
          _result.getString(1)
        }
      }
    }
  }

  override suspend fun getClazzTimeZoneByClazzUidAsync(clazzUid: Long): String? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT Clazz.clazzTimeZone
    |          FROM Clazz
    |         WHERE Clazz.clazzUid = ? 
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,clazzUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        _result.getString(1)
      }
    }
  }

  override suspend fun getCoursesByName(names: List<String>): List<Clazz> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT Clazz.*
    |          FROM Clazz
    |         WHERE Clazz.clazzName IN (?) 
    |    
    """.trimMargin(),
    hasListParams = true,
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setArray(1, _stmt.getConnection().createArrayOrProxyArrayOf("TEXT", names.toTypedArray()))
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override suspend fun findOneRosterUserClazzes(accountPersonUid: Long,
      filterByEnrolledMemberPersonUid: Long): List<Clazz> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT Clazz.*
    |          FROM CLAZZ
    |               LEFT JOIN ClazzEnrolment 
    |                    ON ClazzEnrolment.clazzEnrolmentUid =
    |                       COALESCE(
    |                       (SELECT ClazzEnrolment.clazzEnrolmentUid 
    |                          FROM ClazzEnrolment
    |                         WHERE ClazzEnrolment.clazzEnrolmentPersonUid = ?
    |                           AND ClazzEnrolment.clazzEnrolmentActive
    |                           AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid 
    |                      ORDER BY ClazzEnrolment.clazzEnrolmentDateLeft DESC   
    |                         LIMIT 1), 0)
    |          WHERE (   Clazz.clazzOwnerPersonUid = ?
    |                 OR EXISTS(SELECT CoursePermission.cpUid
    |                             FROM CoursePermission
    |                            WHERE CoursePermission.cpClazzUid = Clazz.clazzUid
    |                              AND (   CoursePermission.cpToPersonUid = ? 
    |                                   OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment.clazzEnrolmentRole )
    |                              AND (CoursePermission.cpPermissionsFlag & 1) > 0 
    |                              AND NOT CoursePermission.cpIsDeleted)   
    |                 OR (
    |        EXISTS(SELECT 1
    |                 FROM SystemPermission
    |                WHERE ? != 0 
    |                  AND SystemPermission.spToPersonUid = ?
    |                  AND (SystemPermission.spPermissionsFlag &
    |    
    |                     1
    |                     
    |        ) > 0
    |                  AND NOT SystemPermission.spIsDeleted)
    |    
    |                    )             
    |                )
    |           AND EXISTS 
    |                (SELECT ClazzEnrolment.clazzEnrolmentUid
    |                   FROM ClazzEnrolment
    |                  WHERE ClazzEnrolment.clazzEnrolmentPersonUid = ?
    |                    AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid
    |                )  
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,accountPersonUid)
    _stmt.setLong(2,accountPersonUid)
    _stmt.setLong(3,accountPersonUid)
    _stmt.setLong(4,accountPersonUid)
    _stmt.setLong(5,accountPersonUid)
    _stmt.setLong(6,filterByEnrolledMemberPersonUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getString("clazzName")
        val _tmp_clazzDesc = _result.getString("clazzDesc")
        val _tmp_attendanceAverage = _result.getFloat("attendanceAverage")
        val _tmp_clazzHolidayUMCalendarUid = _result.getLong("clazzHolidayUMCalendarUid")
        val _tmp_clazzScheuleUMCalendarUid = _result.getLong("clazzScheuleUMCalendarUid")
        val _tmp_isClazzActive = _result.getBoolean("isClazzActive")
        val _tmp_clazzLocationUid = _result.getLong("clazzLocationUid")
        val _tmp_clazzStartTime = _result.getLong("clazzStartTime")
        val _tmp_clazzEndTime = _result.getLong("clazzEndTime")
        val _tmp_clazzFeatures = _result.getLong("clazzFeatures")
        val _tmp_clazzSchoolUid = _result.getLong("clazzSchoolUid")
        val _tmp_clazzEnrolmentPolicy = _result.getInt("clazzEnrolmentPolicy")
        val _tmp_clazzTerminologyUid = _result.getLong("clazzTerminologyUid")
        val _tmp_clazzMasterChangeSeqNum = _result.getLong("clazzMasterChangeSeqNum")
        val _tmp_clazzLocalChangeSeqNum = _result.getLong("clazzLocalChangeSeqNum")
        val _tmp_clazzLastChangedBy = _result.getInt("clazzLastChangedBy")
        val _tmp_clazzLct = _result.getLong("clazzLct")
        val _tmp_clazzTimeZone = _result.getString("clazzTimeZone")
        val _tmp_clazzStudentsPersonGroupUid = _result.getLong("clazzStudentsPersonGroupUid")
        val _tmp_clazzTeachersPersonGroupUid = _result.getLong("clazzTeachersPersonGroupUid")
        val _tmp_clazzPendingStudentsPersonGroupUid =
            _result.getLong("clazzPendingStudentsPersonGroupUid")
        val _tmp_clazzParentsPersonGroupUid = _result.getLong("clazzParentsPersonGroupUid")
        val _tmp_clazzCode = _result.getString("clazzCode")
        val _tmp_clazzOwnerPersonUid = _result.getLong("clazzOwnerPersonUid")
        Clazz().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
          this.clazzDesc = _tmp_clazzDesc
          this.attendanceAverage = _tmp_attendanceAverage
          this.clazzHolidayUMCalendarUid = _tmp_clazzHolidayUMCalendarUid
          this.clazzScheuleUMCalendarUid = _tmp_clazzScheuleUMCalendarUid
          this.isClazzActive = _tmp_isClazzActive
          this.clazzLocationUid = _tmp_clazzLocationUid
          this.clazzStartTime = _tmp_clazzStartTime
          this.clazzEndTime = _tmp_clazzEndTime
          this.clazzFeatures = _tmp_clazzFeatures
          this.clazzSchoolUid = _tmp_clazzSchoolUid
          this.clazzEnrolmentPolicy = _tmp_clazzEnrolmentPolicy
          this.clazzTerminologyUid = _tmp_clazzTerminologyUid
          this.clazzMasterChangeSeqNum = _tmp_clazzMasterChangeSeqNum
          this.clazzLocalChangeSeqNum = _tmp_clazzLocalChangeSeqNum
          this.clazzLastChangedBy = _tmp_clazzLastChangedBy
          this.clazzLct = _tmp_clazzLct
          this.clazzTimeZone = _tmp_clazzTimeZone
          this.clazzStudentsPersonGroupUid = _tmp_clazzStudentsPersonGroupUid
          this.clazzTeachersPersonGroupUid = _tmp_clazzTeachersPersonGroupUid
          this.clazzPendingStudentsPersonGroupUid = _tmp_clazzPendingStudentsPersonGroupUid
          this.clazzParentsPersonGroupUid = _tmp_clazzParentsPersonGroupUid
          this.clazzCode = _tmp_clazzCode
          this.clazzOwnerPersonUid = _tmp_clazzOwnerPersonUid
        }
      }
    }
  }

  override suspend fun findClazzNamesByUids(uidList: List<Long>): List<ClazzUidAndName> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT Clazz.clazzUid, Clazz.clazzName
    |          FROM Clazz
    |         WHERE Clazz.clazzUid IN (?) 
    |    
    """.trimMargin(),
    hasListParams = true,
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setArray(1, _stmt.getConnection().createArrayOrProxyArrayOf("BIGINT",
        uidList.toTypedArray()))
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_clazzUid = _result.getLong("clazzUid")
        val _tmp_clazzName = _result.getStringNonNull("clazzName")
        ClazzUidAndName().apply {
          this.clazzUid = _tmp_clazzUid
          this.clazzName = _tmp_clazzName
        }
      }
    }
  }
}
