Add route and column for get the most popular bet
continuous-integration/drone/push Build is passing Details

pull/13/head
luevard 11 months ago
parent bf9ddc93f9
commit 9ff2e8d896

@ -20,4 +20,5 @@ interface BetDataSource {
fun getWonNotifications(username: String): List<BetResultDetail> fun getWonNotifications(username: String): List<BetResultDetail>
fun getHistory(username: String): List<BetResultDetail> fun getHistory(username: String): List<BetResultDetail>
fun getCurrent(username: String): List<BetDetail> fun getCurrent(username: String): List<BetDetail>
fun getMostPopularBet(): Bet?
} }

@ -164,4 +164,8 @@ class MockBetDataSource(private val mockData: MockDataSource.MockData) : BetData
userParticipation = participation userParticipation = participation
) )
} }
override fun getMostPopularBet(): Bet? {
TODO("Not yet implemented")
}
} }

@ -110,6 +110,14 @@ class PostgresBetDataSource(private val database: Database) : BetDataSource {
} }
} }
override fun getMostPopularBet(): Bet? {
val max=database.bets.filter { (it.isPrivate eq false) and (it.status eq BetStatus.WAITING) }.maxBy { it.popularityscore }
if(max!=null){
return database.bets.filter { (it.popularityscore eq max) and (it.isPrivate eq false) and (it.status eq BetStatus.WAITING) }.map { it.toBet(database) }.first()
}
return null
}
override fun addBet(bet: Bet) { override fun addBet(bet: Bet) {
database.bets.add( database.bets.add(
BetEntity { BetEntity {
@ -172,4 +180,5 @@ class PostgresBetDataSource(private val database: Database) : BetDataSource {
} }
} }
} }
} }

@ -48,7 +48,8 @@ class PostgresDataSource : AllInDataSource() {
isprivate boolean, isprivate boolean,
createdby varchar(250), createdby varchar(250),
status varchar(20), status varchar(20),
type varchar(20) type varchar(20),
popularityscore numeric
) )
""".trimIndent() """.trimIndent()
) )
@ -124,6 +125,35 @@ class PostgresDataSource : AllInDataSource() {
) )
""".trimIndent() """.trimIndent()
) )
database.execute("""
CREATE OR REPLACE FUNCTION update_popularity_score()
RETURNS TRIGGER AS ${'$'}${'$'}
DECLARE
participant_count INT;
total_stakes INT;
BEGIN
-- Calculate participant count and total stakes for the bet
SELECT COUNT(*), COALESCE(SUM(stake), 0) INTO participant_count, total_stakes
FROM participation
WHERE bet = NEW.bet;
-- Update the popularityscore in the bet table
UPDATE bet
SET popularityscore = (participant_count * participant_count + total_stakes)
WHERE id = NEW.bet;
RETURN NEW;
END;
${'$'}${'$'} LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS update_popularity_score ON participation;
CREATE TRIGGER update_popularity_score
AFTER INSERT OR UPDATE ON participation
FOR EACH ROW
EXECUTE FUNCTION update_popularity_score();
""".trimIndent())
} }
override val userDataSource: UserDataSource by lazy { PostgresUserDataSource(database) } override val userDataSource: UserDataSource by lazy { PostgresUserDataSource(database) }

@ -5,6 +5,7 @@ import org.ktorm.database.Database
import org.ktorm.dsl.eq import org.ktorm.dsl.eq
import org.ktorm.entity.* import org.ktorm.entity.*
import org.ktorm.schema.* import org.ktorm.schema.*
import org.postgresql.util.ByteConverter.numeric
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
import java.time.ZonedDateTime import java.time.ZonedDateTime
@ -23,6 +24,7 @@ interface BetEntity : Entity<BetEntity> {
var status: BetStatus var status: BetStatus
var type: BetType var type: BetType
var createdBy: String var createdBy: String
var popularityscore: Int
fun toBet(database: Database) = fun toBet(database: Database) =
Bet( Bet(
@ -60,6 +62,7 @@ interface BetEntity : Entity<BetEntity> {
) )
} }
} }
object BetsEntity : Table<BetEntity>("bet") { object BetsEntity : Table<BetEntity>("bet") {
@ -73,6 +76,7 @@ object BetsEntity : Table<BetEntity>("bet") {
val status = enum<BetStatus>("status").bindTo { it.status } val status = enum<BetStatus>("status").bindTo { it.status }
val type = enum<BetType>("type").bindTo { it.type } val type = enum<BetType>("type").bindTo { it.type }
val createdBy = varchar("createdby").bindTo { it.createdBy } val createdBy = varchar("createdby").bindTo { it.createdBy }
val popularityscore = int("popularityscore").bindTo { it.popularityscore }
} }
val Database.bets get() = this.sequenceOf(BetsEntity) val Database.bets get() = this.sequenceOf(BetsEntity)

@ -53,7 +53,7 @@ fun Application.betRouter() {
betDataSource.getBetById(id)?.let { betDataSource.getBetById(id)?.let {
call.respond(HttpStatusCode.Conflict, ApiMessage.BET_ALREADY_EXIST) call.respond(HttpStatusCode.Conflict, ApiMessage.BET_ALREADY_EXIST)
} ?: run { } ?: run {
val betWithId = bet.copy(id = id, createdBy = user.first?.username.toString()) val betWithId = bet.copy(id = id, createdBy = user.first?.id.toString())
betDataSource.addBet(betWithId) betDataSource.addBet(betWithId)
call.respond(HttpStatusCode.Created, betWithId) call.respond(HttpStatusCode.Created, betWithId)
} }
@ -83,6 +83,33 @@ fun Application.betRouter() {
} }
} }
authenticate {
get("/bets/popular", {
description = "Allows you to recover the most popular public bets"
request {
headerParameter<JWTPrincipal>("JWT token of the logged user")
}
response {
HttpStatusCode.Accepted to {
description = "The most popular public bet is available"
body<Bet> {
description = "The most popular public bet"
}
}
}
}) {
hasToken { principal ->
verifyUserFromToken(userDataSource, principal) { _, _ ->
val bet = betDataSource.getMostPopularBet()
if (bet != null) {
call.respond(HttpStatusCode.Accepted, bet)
}
call.respond(HttpStatusCode.NotFound,"Aucun bet n'a pu être récupérer")
}
}
}
}
get("/bets/get/{id}", { get("/bets/get/{id}", {
description = "Retrieves a specific bet" description = "Retrieves a specific bet"
request { request {

Loading…
Cancel
Save