lila/modules/simul/src/main/SimulRepo.scala

172 lines
5.0 KiB
Scala
Raw Normal View History

2015-04-03 07:33:31 -06:00
package lila.simul
2015-04-04 03:04:50 -06:00
import org.joda.time.DateTime
2019-11-29 19:16:11 -07:00
import reactivemongo.api.bson._
2015-04-03 07:33:31 -06:00
import chess.Status
2015-04-03 07:33:31 -06:00
import chess.variant.Variant
import lila.db.BSON
2019-04-05 19:12:01 -06:00
import lila.db.BSON.BSONJodaDateTimeHandler
import lila.db.dsl._
2020-08-02 09:49:15 -06:00
import lila.user.User
2015-04-03 07:33:31 -06:00
2020-08-26 05:00:53 -06:00
final private[simul] class SimulRepo(val coll: Coll)(implicit ec: scala.concurrent.ExecutionContext) {
2015-04-03 07:33:31 -06:00
2019-12-13 07:30:20 -07:00
implicit private val SimulStatusBSONHandler = tryHandler[SimulStatus](
2019-12-02 10:15:29 -07:00
{ case BSONInteger(v) => SimulStatus(v) toTry s"No such simul status: $v" },
x => BSONInteger(x.id)
)
2019-12-13 07:30:20 -07:00
implicit private val ChessStatusBSONHandler = lila.game.BSONHandlers.StatusBSONHandler
implicit private val VariantBSONHandler = tryHandler[Variant](
2019-12-02 10:15:29 -07:00
{ case BSONInteger(v) => Variant(v) toTry s"No such variant: $v" },
x => BSONInteger(x.id)
)
2020-07-08 12:47:36 -06:00
import chess.Clock.Config
implicit private val clockHandler = Macros.handler[Config]
implicit private val ClockBSONHandler = Macros.handler[SimulClock]
2019-12-13 07:30:20 -07:00
implicit private val PlayerBSONHandler = Macros.handler[SimulPlayer]
implicit private val ApplicantBSONHandler = Macros.handler[SimulApplicant]
implicit private val SimulPairingBSONHandler = new BSON[SimulPairing] {
2020-05-05 22:11:15 -06:00
def reads(r: BSON.Reader) =
SimulPairing(
player = r.get[SimulPlayer]("player"),
gameId = r str "gameId",
status = r.get[Status]("status"),
wins = r boolO "wins",
2020-09-21 03:31:16 -06:00
hostColor = r.strO("hostColor").flatMap(chess.Color.fromName) | chess.White
2020-05-05 22:11:15 -06:00
)
def writes(w: BSON.Writer, o: SimulPairing) =
$doc(
"player" -> o.player,
"gameId" -> o.gameId,
"status" -> o.status,
"wins" -> o.wins,
"hostColor" -> o.hostColor.name
)
}
2019-12-13 07:30:20 -07:00
implicit private val SimulBSONHandler = Macros.handler[Simul]
2015-04-03 07:33:31 -06:00
2020-05-05 22:11:15 -06:00
private val createdSelect = $doc("status" -> SimulStatus.Created.id)
private val startedSelect = $doc("status" -> SimulStatus.Started.id)
private val finishedSelect = $doc("status" -> SimulStatus.Finished.id)
2020-06-06 08:28:22 -06:00
private val createdSort = $sort desc "createdAt"
2015-04-03 07:33:31 -06:00
def find(id: Simul.ID): Fu[Option[Simul]] =
2020-08-26 05:00:53 -06:00
coll.byId[Simul](id)
2015-04-03 07:33:31 -06:00
2017-07-20 06:12:24 -06:00
def byIds(ids: List[Simul.ID]): Fu[List[Simul]] =
2020-08-26 05:00:53 -06:00
coll.byIds[Simul](ids)
2017-07-20 06:12:24 -06:00
2015-04-03 07:33:31 -06:00
def exists(id: Simul.ID): Fu[Boolean] =
2020-08-26 05:00:53 -06:00
coll.exists($id(id))
2015-04-03 07:33:31 -06:00
def findStarted(id: Simul.ID): Fu[Option[Simul]] =
find(id) map (_ filter (_.isStarted))
def findCreated(id: Simul.ID): Fu[Option[Simul]] =
find(id) map (_ filter (_.isCreated))
2020-08-02 09:49:15 -06:00
def findPending(hostId: User.ID): Fu[List[Simul]] =
2020-08-26 05:00:53 -06:00
coll.list[Simul](createdSelect ++ $doc("hostId" -> hostId))
2020-04-06 17:02:44 -06:00
2020-08-02 09:49:15 -06:00
def byTeamLeaders(teamId: String, hostIds: Seq[User.ID]): Fu[List[Simul]] =
2020-08-26 05:00:53 -06:00
coll
2020-08-02 09:49:15 -06:00
.find(
createdSelect ++
$doc("hostId" $in hostIds, "team" $in List(BSONString(teamId)))
)
2020-08-26 05:00:53 -06:00
.hint(coll hint $doc("hostId" -> 1))
2020-08-02 09:49:15 -06:00
.cursor[Simul]()
.list()
def hostId(id: Simul.ID): Fu[Option[User.ID]] =
coll.primitiveOne[User.ID]($id(id), "hostId")
2020-06-06 08:28:22 -06:00
private val featurableSelect = $doc("featurable" -> true)
2020-04-19 12:55:51 -06:00
2019-12-13 07:30:20 -07:00
def allCreatedFeaturable: Fu[List[Simul]] =
2020-08-26 05:00:53 -06:00
coll
2020-04-19 12:55:51 -06:00
.find(
2020-06-06 08:28:22 -06:00
// hits partial index hostSeenAt_-1
createdSelect ++ featurableSelect ++ $doc(
2020-08-21 06:18:24 -06:00
"hostSeenAt" $gte DateTime.now.minusSeconds(12),
"createdAt" $gte DateTime.now.minusHours(1)
2020-04-19 12:55:51 -06:00
)
)
2019-12-13 07:30:20 -07:00
.sort(createdSort)
2020-08-26 05:00:53 -06:00
.hint(coll hint $doc("hostSeenAt" -> -1))
2020-07-19 09:03:06 -06:00
.cursor[Simul]()
.list() map {
_.foldLeft(List.empty[Simul]) {
case (acc, sim) if acc.exists(_.hostId == sim.hostId) => acc
case (acc, sim) => sim :: acc
}.reverse
}
2019-12-13 07:30:20 -07:00
def allStarted: Fu[List[Simul]] =
2020-08-26 05:00:53 -06:00
coll
2020-06-06 08:28:22 -06:00
.find(startedSelect)
2019-12-13 07:30:20 -07:00
.sort(createdSort)
2020-07-19 09:03:06 -06:00
.cursor[Simul]()
.list()
2019-12-13 07:30:20 -07:00
2020-04-19 12:55:51 -06:00
def allFinishedFeaturable(max: Int): Fu[List[Simul]] =
2020-08-26 05:00:53 -06:00
coll
2020-04-19 12:55:51 -06:00
.find(finishedSelect ++ featurableSelect)
2020-06-15 10:48:58 -06:00
.sort($sort desc "finishedAt")
2020-07-19 09:03:06 -06:00
.cursor[Simul]()
.list(max)
2015-04-03 07:33:31 -06:00
def allNotFinished =
2020-08-26 05:00:53 -06:00
coll.list[Simul]($doc("status" $ne SimulStatus.Finished.id))
2015-04-03 07:33:31 -06:00
2021-04-01 18:50:06 -06:00
def create(simul: Simul): Funit =
2020-08-26 05:00:53 -06:00
coll.insert one {
2021-04-01 18:50:06 -06:00
SimulBSONHandler.writeTry(simul).get
2020-06-06 08:28:22 -06:00
} void
2015-04-03 07:33:31 -06:00
2021-04-01 18:50:06 -06:00
def update(simul: Simul) =
2020-08-26 05:00:53 -06:00
coll.update
.one(
$id(simul.id),
$set(SimulBSONHandler writeTry simul get) ++
2021-05-23 11:06:44 -06:00
simul.estimatedStartAt.isEmpty ?? ($unset("estimatedStartAt"))
)
.void
2015-04-03 17:50:27 -06:00
def remove(simul: Simul) =
2020-08-26 05:00:53 -06:00
coll.delete.one($id(simul.id)).void
2019-12-13 07:30:20 -07:00
def setHostGameId(simul: Simul, gameId: String) =
2020-08-26 05:00:53 -06:00
coll.update
2019-12-13 07:30:20 -07:00
.one(
$id(simul.id),
$set("hostGameId" -> gameId)
)
.void
def setHostSeenNow(simul: Simul) =
2020-08-26 05:00:53 -06:00
coll.update
2019-12-13 07:30:20 -07:00
.one(
$id(simul.id),
$set("hostSeenAt" -> DateTime.now)
)
.void
def setText(simul: Simul, text: String) =
2020-08-26 05:00:53 -06:00
coll.update
2019-12-13 07:30:20 -07:00
.one(
$id(simul.id),
$set("text" -> text)
)
.void
2020-05-05 22:11:15 -06:00
def cleanup =
2020-08-26 05:00:53 -06:00
coll.delete.one(
2020-05-05 22:11:15 -06:00
createdSelect ++ $doc(
"createdAt" -> $doc("$lt" -> (DateTime.now minusMinutes 60))
)
)
2015-04-03 07:33:31 -06:00
}