package fr.dcproject.repository import com.fasterxml.jackson.core.type.TypeReference import fr.dcproject.component.article.ArticleRef import fr.dcproject.component.opinion.entity.OpinionForUpdate import fr.dcproject.entity.TargetRef import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Requester import fr.postgresjson.repository.RepositoryI import net.pearx.kasechange.toSnakeCase import java.util.UUID import fr.dcproject.component.citizen.Citizen as CitizenEntity import fr.dcproject.component.opinion.entity.Opinion as OpinionEntity import fr.dcproject.component.opinion.entity.OpinionArticle as OpinionArticleEntity import fr.dcproject.component.opinion.entity.OpinionChoice as OpinionChoiceEntity open class OpinionChoiceRepository(override val requester: Requester) : RepositoryI { /** * find all opinion choices * can be filtered by target compatibility */ fun findOpinionsChoices(targets: List = emptyList()): List = requester .getFunction("find_opinion_choices") .select( "targets" to targets ) /** * find opinion choices by name */ fun findOpinionsChoiceByName(name: String): OpinionChoiceEntity? = findOpinionsChoices().first { it.name == name } /** * find one opinion choices by id */ fun findOpinionChoiceById(id: UUID): OpinionChoiceEntity? = requester .getFunction("find_opinion_choice_by_id") .selectOne( "id" to id ) /** * find one opinion choices by id */ fun findOpinionChoicesByIds(ids: List): List = requester .getFunction("find_opinion_choices_by_ids") .select( "ids" to ids ) fun upsertOpinionChoice(opinionChoice: OpinionChoiceEntity): OpinionChoiceEntity = requester .getFunction("upsert_opinion_choice") .selectOne( "resource" to opinionChoice )!! } abstract class OpinionRepository(requester: Requester) : OpinionChoiceRepository(requester) { /** * Create an Opinion on target (article,...) */ abstract fun updateOpinions(opinions: List>): List> fun updateOpinions(opinion: OpinionForUpdate<*>): List> = updateOpinions(listOf(opinion)) abstract fun addOpinion(opinion: OpinionForUpdate): OpinionEntity /** * Find opinions of one citizen filtered by target ids */ fun findCitizenOpinionsByTargets( citizen: CitizenEntity, targets: List ): List> { val typeReference = object : TypeReference>>() {} return requester.run { getFunction("find_citizen_opinions_by_target_ids") .select( typeReference, mapOf( "citizen_id" to citizen.id, "ids" to targets ) ) } } /** * find opinion of citizen filtered by one target id */ fun findCitizenOpinionsByTarget( citizen: CitizenEntity, target: UUID ): List> { val typeReference = object : TypeReference>>() {} return requester .getFunction("find_citizen_opinions_by_target_id") .select( typeReference, mapOf( "citizen_id" to citizen.id, "id" to target ) ) } /** * find paginated opinion of one citizen * can be sorted */ fun findCitizenOpinions( citizen: CitizenEntity, page: Int = 1, limit: Int = 50, sort: String? = null, direction: RepositoryI.Direction? = null ): Paginated> { return requester .getFunction("find_citizen_opinions") .select( page, limit, "sort" to sort?.toSnakeCase(), "direction" to direction, "citizen_id" to citizen.id ) } } class OpinionRepositoryArticle(requester: Requester) : OpinionRepository(requester) { /** * Update Opinions on Article (Delete old one) */ override fun updateOpinions(opinions: List>): List { return requester /* TODO change SQL function to not use .first() and pass all createdBy and target */ .getFunction("update_citizen_opinions_by_target_id") .select( "choices_ids" to opinions.map { it.choice.id }, "citizen_id" to opinions.first().createdBy.id, "target_id" to opinions.first().target.id, "target_reference" to opinions.first().target.reference ) } /** * Add Opinions on Article */ override fun addOpinion(opinion: OpinionForUpdate): OpinionArticleEntity { return requester .getFunction("upsert_opinion") .selectOne("resource" to opinion)!! } }