package com.ustadmobile.core.db.dao

import com.ustadmobile.door.DoorDbType
import com.ustadmobile.door.EntityInsertionAdapter
import com.ustadmobile.door.PreparedStatementConfig
import com.ustadmobile.door.ext.prepareAndUseStatementAsync
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.mapNextRow
import com.ustadmobile.door.jdbc.ext.mapRows
import com.ustadmobile.door.jdbc.ext.useResults
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.lib.db.entities.ParentEnrolmentRequired
import com.ustadmobile.lib.db.entities.Person
import com.ustadmobile.lib.db.entities.PersonParentJoin
import com.ustadmobile.lib.db.entities.PersonParentJoinAndMinorPerson
import kotlin.Boolean
import kotlin.Long
import kotlin.String
import kotlin.collections.List

public class PersonParentJoinDao_JdbcImpl(
  public val _db: RoomDatabase,
) : PersonParentJoinDao() {
  public val _insertAdapterPersonParentJoin_abort: EntityInsertionAdapter<PersonParentJoin> = object
      : EntityInsertionAdapter<PersonParentJoin>(_db) {
    override fun makeSql(returnsId: Boolean): String =
        "INSERT INTO PersonParentJoin (ppjUid, ppjPcsn, ppjLcsn, ppjLcb, ppjLct, ppjParentPersonUid, ppjMinorPersonUid, ppjRelationship, ppjEmail, ppjPhone, ppjInactive, ppjStatus, ppjApprovalTiemstamp, ppjApprovalIpAddr) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement, entity: PersonParentJoin) {
      if(entity.ppjUid == 0L) {
        stmt.setObject(1, null)
      } else {
        stmt.setLong(1, entity.ppjUid)
      }
      stmt.setLong(2, entity.ppjPcsn)
      stmt.setLong(3, entity.ppjLcsn)
      stmt.setInt(4, entity.ppjLcb)
      stmt.setLong(5, entity.ppjLct)
      stmt.setLong(6, entity.ppjParentPersonUid)
      stmt.setLong(7, entity.ppjMinorPersonUid)
      stmt.setInt(8, entity.ppjRelationship)
      stmt.setString(9, entity.ppjEmail)
      stmt.setString(10, entity.ppjPhone)
      stmt.setBoolean(11, entity.ppjInactive)
      stmt.setInt(12, entity.ppjStatus)
      stmt.setLong(13, entity.ppjApprovalTiemstamp)
      stmt.setString(14, entity.ppjApprovalIpAddr)
    }
  }

  public val _insertAdapterPersonParentJoin_upsert: EntityInsertionAdapter<PersonParentJoin> =
      object : EntityInsertionAdapter<PersonParentJoin>(_db) {
    override fun makeSql(returnsId: Boolean): String =
        "INSERT OR REPLACE INTO PersonParentJoin (ppjUid, ppjPcsn, ppjLcsn, ppjLcb, ppjLct, ppjParentPersonUid, ppjMinorPersonUid, ppjRelationship, ppjEmail, ppjPhone, ppjInactive, ppjStatus, ppjApprovalTiemstamp, ppjApprovalIpAddr) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement, entity: PersonParentJoin) {
      if(entity.ppjUid == 0L) {
        stmt.setObject(1, null)
      } else {
        stmt.setLong(1, entity.ppjUid)
      }
      stmt.setLong(2, entity.ppjPcsn)
      stmt.setLong(3, entity.ppjLcsn)
      stmt.setInt(4, entity.ppjLcb)
      stmt.setLong(5, entity.ppjLct)
      stmt.setLong(6, entity.ppjParentPersonUid)
      stmt.setLong(7, entity.ppjMinorPersonUid)
      stmt.setInt(8, entity.ppjRelationship)
      stmt.setString(9, entity.ppjEmail)
      stmt.setString(10, entity.ppjPhone)
      stmt.setBoolean(11, entity.ppjInactive)
      stmt.setInt(12, entity.ppjStatus)
      stmt.setLong(13, entity.ppjApprovalTiemstamp)
      stmt.setString(14, entity.ppjApprovalIpAddr)
    }
  }

  override suspend fun insertListAsync(entityList: List<PersonParentJoin>) {
    _insertAdapterPersonParentJoin_abort.insertListAsync(entityList)
  }

  override suspend fun upsertAsync(entity: PersonParentJoin): Long {
    val _retVal = _insertAdapterPersonParentJoin_upsert.insertAndReturnIdAsync(entity)
    return _retVal
  }

  override suspend fun updateAsync(personParentJoin: PersonParentJoin) {
    val _sql =
        "UPDATE PersonParentJoin SET ppjPcsn = ?, ppjLcsn = ?, ppjLcb = ?, ppjLct = ?, ppjParentPersonUid = ?, ppjMinorPersonUid = ?, ppjRelationship = ?, ppjEmail = ?, ppjPhone = ?, ppjInactive = ?, ppjStatus = ?, ppjApprovalTiemstamp = ?, ppjApprovalIpAddr = ? WHERE ppjUid = ?"
    _db.prepareAndUseStatementAsync(_sql) {
       _stmt ->
      _stmt.setLong(1, personParentJoin.ppjPcsn)
      _stmt.setLong(2, personParentJoin.ppjLcsn)
      _stmt.setInt(3, personParentJoin.ppjLcb)
      _stmt.setLong(4, personParentJoin.ppjLct)
      _stmt.setLong(5, personParentJoin.ppjParentPersonUid)
      _stmt.setLong(6, personParentJoin.ppjMinorPersonUid)
      _stmt.setInt(7, personParentJoin.ppjRelationship)
      _stmt.setString(8, personParentJoin.ppjEmail)
      _stmt.setString(9, personParentJoin.ppjPhone)
      _stmt.setBoolean(10, personParentJoin.ppjInactive)
      _stmt.setInt(11, personParentJoin.ppjStatus)
      _stmt.setLong(12, personParentJoin.ppjApprovalTiemstamp)
      _stmt.setString(13, personParentJoin.ppjApprovalIpAddr)
      _stmt.setLong(14, personParentJoin.ppjUid)
      _stmt.executeUpdateAsyncKmp()
    }
  }

  override suspend fun findByUidWithMinorAsync(uid: Long): PersonParentJoinAndMinorPerson? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT PersonParentJoin.*, Person.*
    |          FROM PersonParentJoin
    |     LEFT JOIN Person ON Person.personUid = PersonParentJoin.ppjMinorPersonUid    
    |         WHERE PersonParentJoin.ppjUid = CAST(? AS BIGINT)
    |    
    """.trimMargin(),
    postgreSql = """
    |
    |        SELECT PersonParentJoin.*, Person.*
    |          FROM PersonParentJoin
    |     LEFT JOIN Person ON Person.personUid = PersonParentJoin.ppjMinorPersonUid    
    |         WHERE PersonParentJoin.ppjUid = ?
    |    
    |""".trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,uid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        var _tmp_PersonParentJoin_nullCount = 0
        val _tmp_ppjUid = _result.getLong("ppjUid")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjPcsn = _result.getLong("ppjPcsn")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjLcsn = _result.getLong("ppjLcsn")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjLcb = _result.getInt("ppjLcb")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjLct = _result.getLong("ppjLct")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjParentPersonUid = _result.getLong("ppjParentPersonUid")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjMinorPersonUid = _result.getLong("ppjMinorPersonUid")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjRelationship = _result.getInt("ppjRelationship")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjEmail = _result.getString("ppjEmail")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjPhone = _result.getString("ppjPhone")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjInactive = _result.getBoolean("ppjInactive")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjStatus = _result.getInt("ppjStatus")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjApprovalTiemstamp = _result.getLong("ppjApprovalTiemstamp")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjApprovalIpAddr = _result.getString("ppjApprovalIpAddr")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_PersonParentJoin_isAllNull = _tmp_PersonParentJoin_nullCount == 14
        var _tmp_Person_nullCount = 0
        val _tmp_personUid = _result.getLong("personUid")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_username = _result.getString("username")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_firstNames = _result.getString("firstNames")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_lastName = _result.getString("lastName")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_emailAddr = _result.getString("emailAddr")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_phoneNum = _result.getString("phoneNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_gender = _result.getInt("gender")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_active = _result.getBoolean("active")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_isPersonalAccount = _result.getBoolean("isPersonalAccount")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_dateOfBirth = _result.getLong("dateOfBirth")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personAddress = _result.getString("personAddress")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personOrgId = _result.getString("personOrgId")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personGroupUid = _result.getLong("personGroupUid")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personLct = _result.getLong("personLct")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personCountry = _result.getString("personCountry")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personType = _result.getInt("personType")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personMasterChangeSeqNum = _result.getLong("personMasterChangeSeqNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personLocalChangeSeqNum = _result.getLong("personLocalChangeSeqNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personLastChangedBy = _result.getInt("personLastChangedBy")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_admin = _result.getBoolean("admin")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personNotes = _result.getString("personNotes")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_fatherName = _result.getString("fatherName")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_fatherNumber = _result.getString("fatherNumber")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_motherName = _result.getString("motherName")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_motherNum = _result.getString("motherNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_Person_isAllNull = _tmp_Person_nullCount == 25
        PersonParentJoinAndMinorPerson().apply {
          if(!_tmp_PersonParentJoin_isAllNull) {
            this.personParentJoin = PersonParentJoin().apply {
              this.ppjUid = _tmp_ppjUid
              this.ppjPcsn = _tmp_ppjPcsn
              this.ppjLcsn = _tmp_ppjLcsn
              this.ppjLcb = _tmp_ppjLcb
              this.ppjLct = _tmp_ppjLct
              this.ppjParentPersonUid = _tmp_ppjParentPersonUid
              this.ppjMinorPersonUid = _tmp_ppjMinorPersonUid
              this.ppjRelationship = _tmp_ppjRelationship
              this.ppjEmail = _tmp_ppjEmail
              this.ppjPhone = _tmp_ppjPhone
              this.ppjInactive = _tmp_ppjInactive
              this.ppjStatus = _tmp_ppjStatus
              this.ppjApprovalTiemstamp = _tmp_ppjApprovalTiemstamp
              this.ppjApprovalIpAddr = _tmp_ppjApprovalIpAddr
            }
          }
          if(!_tmp_Person_isAllNull) {
            this.minorPerson = Person().apply {
              this.personUid = _tmp_personUid
              this.username = _tmp_username
              this.firstNames = _tmp_firstNames
              this.lastName = _tmp_lastName
              this.emailAddr = _tmp_emailAddr
              this.phoneNum = _tmp_phoneNum
              this.gender = _tmp_gender
              this.active = _tmp_active
              this.isPersonalAccount = _tmp_isPersonalAccount
              this.dateOfBirth = _tmp_dateOfBirth
              this.personAddress = _tmp_personAddress
              this.personOrgId = _tmp_personOrgId
              this.personGroupUid = _tmp_personGroupUid
              this.personLct = _tmp_personLct
              this.personCountry = _tmp_personCountry
              this.personType = _tmp_personType
              this.personMasterChangeSeqNum = _tmp_personMasterChangeSeqNum
              this.personLocalChangeSeqNum = _tmp_personLocalChangeSeqNum
              this.personLastChangedBy = _tmp_personLastChangedBy
              this.admin = _tmp_admin
              this.personNotes = _tmp_personNotes
              this.fatherName = _tmp_fatherName
              this.fatherNumber = _tmp_fatherNumber
              this.motherName = _tmp_motherName
              this.motherNum = _tmp_motherNum
            }
          }
        }
      }
    }
  }

  override suspend fun findByUidWithMinorAsyncFromWeb(uid: Long): PersonParentJoinAndMinorPerson? =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT PersonParentJoin.*, Person.*
    |          FROM PersonParentJoin
    |     LEFT JOIN Person ON Person.personUid = PersonParentJoin.ppjMinorPersonUid    
    |         WHERE PersonParentJoin.ppjUid = CAST(? AS BIGINT)
    |    
    """.trimMargin(),
    postgreSql = """
    |
    |        SELECT PersonParentJoin.*, Person.*
    |          FROM PersonParentJoin
    |     LEFT JOIN Person ON Person.personUid = PersonParentJoin.ppjMinorPersonUid    
    |         WHERE PersonParentJoin.ppjUid = ?
    |    
    |""".trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,uid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(null) {
        var _tmp_PersonParentJoin_nullCount = 0
        val _tmp_ppjUid = _result.getLong("ppjUid")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjPcsn = _result.getLong("ppjPcsn")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjLcsn = _result.getLong("ppjLcsn")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjLcb = _result.getInt("ppjLcb")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjLct = _result.getLong("ppjLct")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjParentPersonUid = _result.getLong("ppjParentPersonUid")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjMinorPersonUid = _result.getLong("ppjMinorPersonUid")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjRelationship = _result.getInt("ppjRelationship")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjEmail = _result.getString("ppjEmail")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjPhone = _result.getString("ppjPhone")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjInactive = _result.getBoolean("ppjInactive")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjStatus = _result.getInt("ppjStatus")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjApprovalTiemstamp = _result.getLong("ppjApprovalTiemstamp")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_ppjApprovalIpAddr = _result.getString("ppjApprovalIpAddr")
        if(_result.wasNull()) _tmp_PersonParentJoin_nullCount++
        val _tmp_PersonParentJoin_isAllNull = _tmp_PersonParentJoin_nullCount == 14
        var _tmp_Person_nullCount = 0
        val _tmp_personUid = _result.getLong("personUid")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_username = _result.getString("username")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_firstNames = _result.getString("firstNames")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_lastName = _result.getString("lastName")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_emailAddr = _result.getString("emailAddr")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_phoneNum = _result.getString("phoneNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_gender = _result.getInt("gender")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_active = _result.getBoolean("active")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_isPersonalAccount = _result.getBoolean("isPersonalAccount")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_dateOfBirth = _result.getLong("dateOfBirth")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personAddress = _result.getString("personAddress")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personOrgId = _result.getString("personOrgId")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personGroupUid = _result.getLong("personGroupUid")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personLct = _result.getLong("personLct")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personCountry = _result.getString("personCountry")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personType = _result.getInt("personType")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personMasterChangeSeqNum = _result.getLong("personMasterChangeSeqNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personLocalChangeSeqNum = _result.getLong("personLocalChangeSeqNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personLastChangedBy = _result.getInt("personLastChangedBy")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_admin = _result.getBoolean("admin")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_personNotes = _result.getString("personNotes")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_fatherName = _result.getString("fatherName")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_fatherNumber = _result.getString("fatherNumber")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_motherName = _result.getString("motherName")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_motherNum = _result.getString("motherNum")
        if(_result.wasNull()) _tmp_Person_nullCount++
        val _tmp_Person_isAllNull = _tmp_Person_nullCount == 25
        PersonParentJoinAndMinorPerson().apply {
          if(!_tmp_PersonParentJoin_isAllNull) {
            this.personParentJoin = PersonParentJoin().apply {
              this.ppjUid = _tmp_ppjUid
              this.ppjPcsn = _tmp_ppjPcsn
              this.ppjLcsn = _tmp_ppjLcsn
              this.ppjLcb = _tmp_ppjLcb
              this.ppjLct = _tmp_ppjLct
              this.ppjParentPersonUid = _tmp_ppjParentPersonUid
              this.ppjMinorPersonUid = _tmp_ppjMinorPersonUid
              this.ppjRelationship = _tmp_ppjRelationship
              this.ppjEmail = _tmp_ppjEmail
              this.ppjPhone = _tmp_ppjPhone
              this.ppjInactive = _tmp_ppjInactive
              this.ppjStatus = _tmp_ppjStatus
              this.ppjApprovalTiemstamp = _tmp_ppjApprovalTiemstamp
              this.ppjApprovalIpAddr = _tmp_ppjApprovalIpAddr
            }
          }
          if(!_tmp_Person_isAllNull) {
            this.minorPerson = Person().apply {
              this.personUid = _tmp_personUid
              this.username = _tmp_username
              this.firstNames = _tmp_firstNames
              this.lastName = _tmp_lastName
              this.emailAddr = _tmp_emailAddr
              this.phoneNum = _tmp_phoneNum
              this.gender = _tmp_gender
              this.active = _tmp_active
              this.isPersonalAccount = _tmp_isPersonalAccount
              this.dateOfBirth = _tmp_dateOfBirth
              this.personAddress = _tmp_personAddress
              this.personOrgId = _tmp_personOrgId
              this.personGroupUid = _tmp_personGroupUid
              this.personLct = _tmp_personLct
              this.personCountry = _tmp_personCountry
              this.personType = _tmp_personType
              this.personMasterChangeSeqNum = _tmp_personMasterChangeSeqNum
              this.personLocalChangeSeqNum = _tmp_personLocalChangeSeqNum
              this.personLastChangedBy = _tmp_personLastChangedBy
              this.admin = _tmp_admin
              this.personNotes = _tmp_personNotes
              this.fatherName = _tmp_fatherName
              this.fatherNumber = _tmp_fatherNumber
              this.motherName = _tmp_motherName
              this.motherNum = _tmp_motherNum
            }
          }
        }
      }
    }
  }

  override suspend fun findByMinorPersonUid(minorPersonUid: Long): List<PersonParentJoin> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT PersonParentJoin.*
    |          FROM PersonParentJoin
    |         WHERE ppjMinorPersonUid = CAST(? AS BIGINT) 
    |    
    """.trimMargin(),
    postgreSql = """
    |
    |        SELECT PersonParentJoin.*
    |          FROM PersonParentJoin
    |         WHERE ppjMinorPersonUid = ? 
    |    
    |""".trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,minorPersonUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_ppjUid = _result.getLong("ppjUid")
        val _tmp_ppjPcsn = _result.getLong("ppjPcsn")
        val _tmp_ppjLcsn = _result.getLong("ppjLcsn")
        val _tmp_ppjLcb = _result.getInt("ppjLcb")
        val _tmp_ppjLct = _result.getLong("ppjLct")
        val _tmp_ppjParentPersonUid = _result.getLong("ppjParentPersonUid")
        val _tmp_ppjMinorPersonUid = _result.getLong("ppjMinorPersonUid")
        val _tmp_ppjRelationship = _result.getInt("ppjRelationship")
        val _tmp_ppjEmail = _result.getString("ppjEmail")
        val _tmp_ppjPhone = _result.getString("ppjPhone")
        val _tmp_ppjInactive = _result.getBoolean("ppjInactive")
        val _tmp_ppjStatus = _result.getInt("ppjStatus")
        val _tmp_ppjApprovalTiemstamp = _result.getLong("ppjApprovalTiemstamp")
        val _tmp_ppjApprovalIpAddr = _result.getString("ppjApprovalIpAddr")
        PersonParentJoin().apply {
          this.ppjUid = _tmp_ppjUid
          this.ppjPcsn = _tmp_ppjPcsn
          this.ppjLcsn = _tmp_ppjLcsn
          this.ppjLcb = _tmp_ppjLcb
          this.ppjLct = _tmp_ppjLct
          this.ppjParentPersonUid = _tmp_ppjParentPersonUid
          this.ppjMinorPersonUid = _tmp_ppjMinorPersonUid
          this.ppjRelationship = _tmp_ppjRelationship
          this.ppjEmail = _tmp_ppjEmail
          this.ppjPhone = _tmp_ppjPhone
          this.ppjInactive = _tmp_ppjInactive
          this.ppjStatus = _tmp_ppjStatus
          this.ppjApprovalTiemstamp = _tmp_ppjApprovalTiemstamp
          this.ppjApprovalIpAddr = _tmp_ppjApprovalIpAddr
        }
      }
    }
  }

  override suspend fun findByMinorPersonUidWhereParentNotEnrolledInClazz(minorPersonUid: Long,
      clazzUidFilter: Long): List<ParentEnrolmentRequired> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT PersonParentJoin.ppjParentPersonUid AS parentPersonUid,
    |               ChildEnrolment.clazzEnrolmentClazzUid AS clazzUid
    |          FROM PersonParentJoin
    |               JOIN ClazzEnrolment ChildEnrolment 
    |                    ON ChildEnrolment.clazzEnrolmentPersonUid = CAST(? AS BIGINT)
    |                   AND (CAST(? AS BIGINT) = 0 OR ChildEnrolment.clazzEnrolmentClazzUid = CAST(? AS BIGINT))
    |         WHERE PersonParentJoin.ppjMinorPersonUid = CAST(? AS BIGINT)
    |           AND PersonParentJoin.ppjParentPersonUid != 0
    |           AND NOT EXISTS(
    |               SELECT clazzEnrolmentUid 
    |                 FROM ClazzEnrolment
    |                WHERE ClazzEnrolment.clazzEnrolmentPersonUid = PersonParentJoin.ppjParentPersonUid
    |                  AND ClazzEnrolment.clazzEnrolmentClazzUid = ChildEnrolment.clazzEnrolmentClazzUid
    |                  AND ClazzEnrolment.clazzEnrolmentRole = 1003
    |                  AND CAST(ClazzEnrolment.clazzEnrolmentActive AS INTEGER) = 1)
    |    
    """.trimMargin(),
    postgreSql = """
    |
    |        SELECT PersonParentJoin.ppjParentPersonUid AS parentPersonUid,
    |               ChildEnrolment.clazzEnrolmentClazzUid AS clazzUid
    |          FROM PersonParentJoin
    |               JOIN ClazzEnrolment ChildEnrolment 
    |                    ON ChildEnrolment.clazzEnrolmentPersonUid = ?
    |                   AND (? = 0 OR ChildEnrolment.clazzEnrolmentClazzUid = ?)
    |         WHERE PersonParentJoin.ppjMinorPersonUid = ?
    |           AND PersonParentJoin.ppjParentPersonUid != 0
    |           AND NOT EXISTS(
    |               SELECT clazzEnrolmentUid 
    |                 FROM ClazzEnrolment
    |                WHERE ClazzEnrolment.clazzEnrolmentPersonUid = PersonParentJoin.ppjParentPersonUid
    |                  AND ClazzEnrolment.clazzEnrolmentClazzUid = ChildEnrolment.clazzEnrolmentClazzUid
    |                  AND ClazzEnrolment.clazzEnrolmentRole = 1003
    |                  AND CAST(ClazzEnrolment.clazzEnrolmentActive AS INTEGER) = 1)
    |    
    |""".trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,minorPersonUid)
    _stmt.setLong(2,clazzUidFilter)
    _stmt.setLong(3,clazzUidFilter)
    _stmt.setLong(4,minorPersonUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_parentPersonUid = _result.getLong("parentPersonUid")
        val _tmp_clazzUid = _result.getLong("clazzUid")
        ParentEnrolmentRequired().apply {
          this.parentPersonUid = _tmp_parentPersonUid
          this.clazzUid = _tmp_clazzUid
        }
      }
    }
  }

  override suspend fun isParentOf(userPersonUid: Long, minorPersonUid: Long): Boolean =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT EXISTS(
    |               SELECT ppjUid
    |                 FROM PersonParentJoin
    |                WHERE ppjMinorPersonUid = CAST(? AS BIGINT)
    |                      AND ppjParentPersonUid = CAST(? AS BIGINT)
    |                      AND CAST(ppjInactive AS INTEGER) = 0)
    |    
    """.trimMargin(),
    postgreSql = """
    |
    |        SELECT EXISTS(
    |               SELECT ppjUid
    |                 FROM PersonParentJoin
    |                WHERE ppjMinorPersonUid = ?
    |                      AND ppjParentPersonUid = ?
    |                      AND CAST(ppjInactive AS INTEGER) = 0)
    |    
    |""".trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,minorPersonUid)
    _stmt.setLong(2,userPersonUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(false) {
        _result.getBoolean(1)
      }
    }
  }

  override suspend fun isMinorApproved(minorPersonUid: Long): Boolean =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT EXISTS(
    |               SELECT ppjUid
    |                 FROM PersonParentJoin
    |                WHERE ppjMinorPersonUid = CAST(? AS BIGINT)
    |                  AND CAST(ppjInactive AS INTEGER) = 0
    |                  AND ppjStatus = 1)
    |    
    """.trimMargin(),
    postgreSql = """
    |
    |        SELECT EXISTS(
    |               SELECT ppjUid
    |                 FROM PersonParentJoin
    |                WHERE ppjMinorPersonUid = ?
    |                  AND CAST(ppjInactive AS INTEGER) = 0
    |                  AND ppjStatus = 1)
    |    
    |""".trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,minorPersonUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapNextRow(false) {
        _result.getBoolean(1)
      }
    }
  }
}
