rewrite team DB code
parent
1b0628c168
commit
a7aa89288f
|
@ -5,8 +5,8 @@ import scala.util.Random
|
|||
import chess.format.Forsyth
|
||||
import chess.{ Color, Status }
|
||||
import org.joda.time.DateTime
|
||||
import reactivemongo.bson.BSONBinary
|
||||
import reactivemongo.api.ReadPreference
|
||||
import reactivemongo.bson.BSONBinary
|
||||
|
||||
import lila.db.BSON.BSONJodaDateTimeHandler
|
||||
import lila.db.ByteArray
|
||||
|
@ -81,9 +81,17 @@ object GameRepo {
|
|||
.cursor[Game]()
|
||||
.collect[List](nb)
|
||||
|
||||
def cursor(selector: Bdoc, readPreference: ReadPreference = ReadPreference.secondaryPreferred) =
|
||||
def cursor(
|
||||
selector: Bdoc,
|
||||
readPreference: ReadPreference = ReadPreference.secondaryPreferred) =
|
||||
coll.find(selector).cursor[Game](readPreference)
|
||||
|
||||
def sortedCursor(
|
||||
selector: Bdoc,
|
||||
sort: Bdoc,
|
||||
readPreference: ReadPreference = ReadPreference.secondaryPreferred) =
|
||||
coll.find(selector).sort(sort).cursor[Game](readPreference)
|
||||
|
||||
def unrate(gameId: String) =
|
||||
coll.update($id(gameId), $doc("$unset" -> $doc(
|
||||
F.rated -> true,
|
||||
|
|
|
@ -7,6 +7,7 @@ import play.api.libs.json._
|
|||
import scala.util.{ Try, Success, Failure }
|
||||
|
||||
import lila.common.PimpedJson._
|
||||
import lila.db.dsl._
|
||||
import lila.game.actorApi._
|
||||
import lila.game.{ Game, GameRepo }
|
||||
import lila.search._
|
||||
|
@ -17,9 +18,7 @@ final class GameSearchApi(client: ESClient) extends SearchReadApi[Game, Query] {
|
|||
|
||||
def search(query: Query, from: From, size: Size) =
|
||||
client.search(query, from, size) flatMap { res =>
|
||||
import lila.db.dsl.$find
|
||||
import lila.game.tube.gameTube
|
||||
$find.byOrderedIds[lila.game.Game](res.ids)
|
||||
GameRepo games res.ids
|
||||
}
|
||||
|
||||
def count(query: Query) =
|
||||
|
@ -106,10 +105,10 @@ final class GameSearchApi(client: ESClient) extends SearchReadApi[Game, Query] {
|
|||
val maxGames = Int.MaxValue
|
||||
// val maxGames = 10 * 1000 * 1000
|
||||
|
||||
lila.game.tube.gameTube.coll.find(BSONDocument(
|
||||
"ca" -> BSONDocument("$gt" -> since)
|
||||
)).sort(BSONDocument("ca" -> 1))
|
||||
.cursor[Game](ReadPreference.secondaryPreferred)
|
||||
GameRepo.sortedCursor(
|
||||
selector = $doc("ca" $gt since),
|
||||
sort = $doc("ca" -> 1),
|
||||
readPreference = ReadPreference.secondaryPreferred)
|
||||
.enumerate(maxGames, stopOnError = true) &>
|
||||
Enumeratee.grouped(Iteratee takeUpTo batchSize) |>>>
|
||||
Enumeratee.mapM[Seq[Game]].apply[(Seq[Game], Set[String])] { games =>
|
||||
|
|
|
@ -8,9 +8,8 @@ import org.joda.time.DateTime
|
|||
import spray.caching.{ LruCache, Cache }
|
||||
|
||||
import lila.common.paginator._
|
||||
import lila.db.BSON._
|
||||
import lila.db.paginator._
|
||||
import lila.db.Types.Coll
|
||||
import lila.db.dsl._
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
final class QaApi(
|
||||
|
@ -75,7 +74,7 @@ final class QaApi(
|
|||
|
||||
private def paginator(selector: BSONDocument, sort: BSONDocument, page: Int, perPage: Int): Fu[Paginator[Question]] =
|
||||
Paginator(
|
||||
adapter = new BSONAdapter[Question](
|
||||
adapter = new Adapter[Question](
|
||||
collection = questionColl,
|
||||
selector = selector,
|
||||
projection = BSONDocument(),
|
||||
|
|
|
@ -3,8 +3,7 @@ package lila.qa
|
|||
import reactivemongo.bson._
|
||||
import reactivemongo.core.commands._
|
||||
|
||||
import lila.db.BSON.BSONJodaDateTimeHandler
|
||||
import lila.db.Types.Coll
|
||||
import lila.db.dsl._
|
||||
|
||||
final class Search(collection: Coll) {
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package lila.team
|
||||
|
||||
private object BSONHandlers {
|
||||
|
||||
import lila.db.dsl.BSONJodaDateTimeHandler
|
||||
implicit val TeamBSONHandler = reactivemongo.bson.Macros.handler[Team]
|
||||
implicit val RequestBSONHandler = reactivemongo.bson.Macros.handler[Request]
|
||||
implicit val MemberBSONHandler = reactivemongo.bson.Macros.handler[Member]
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package lila.team
|
||||
|
||||
import lila.db.dsl.$find
|
||||
import lila.db.dsl._
|
||||
import lila.user.{ User, UserRepo }
|
||||
import tube.teamTube
|
||||
|
||||
private[team] final class Cli(api: TeamApi) extends lila.common.Cli {
|
||||
private[team] final class Cli(api: TeamApi, coll: Colls) extends lila.common.Cli {
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
def process = {
|
||||
|
||||
|
@ -21,12 +22,12 @@ private[team] final class Cli(api: TeamApi) extends lila.common.Cli {
|
|||
}
|
||||
|
||||
private def perform(teamId: String)(op: Team => Funit): Fu[String] =
|
||||
$find byId teamId flatMap {
|
||||
coll.team.byId[Team](teamId) flatMap {
|
||||
_.fold(fufail[String]("Team not found")) { u => op(u) inject "Success" }
|
||||
}
|
||||
|
||||
private def perform(teamId: String, userIds: List[String])(op: (Team, String) => Funit): Fu[String] =
|
||||
$find byId teamId flatMap {
|
||||
coll.team.byId[Team](teamId) flatMap {
|
||||
_.fold(fufail[String]("Team not found")) { team =>
|
||||
UserRepo nameds userIds flatMap { users =>
|
||||
users.map(user => {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package lila.team
|
||||
|
||||
import lila.db.dsl.Coll
|
||||
|
||||
private final class Colls(
|
||||
val team: Coll,
|
||||
val request: Coll,
|
||||
val member: Coll)
|
|
@ -4,10 +4,11 @@ import play.api.data._
|
|||
import play.api.data.Forms._
|
||||
import play.api.data.validation.Constraints._
|
||||
|
||||
import lila.db.dsl.{ $count, $select }
|
||||
import tube.teamTube
|
||||
import lila.db.dsl._
|
||||
|
||||
private[team] final class DataForm(val captcher: akka.actor.ActorSelection) extends lila.hub.CaptchedForm {
|
||||
private[team] final class DataForm(
|
||||
teamColl: Coll,
|
||||
val captcher: akka.actor.ActorSelection) extends lila.hub.CaptchedForm {
|
||||
|
||||
import lila.common.Form._
|
||||
|
||||
|
@ -61,7 +62,7 @@ private[team] final class DataForm(val captcher: akka.actor.ActorSelection) exte
|
|||
def createWithCaptcha = withCaptcha(create)
|
||||
|
||||
private def teamExists(setup: TeamSetup) =
|
||||
$count.exists[Team]($select(Team nameToId setup.trim.name))
|
||||
teamColl.exists($id(Team nameToId setup.trim.name))
|
||||
}
|
||||
|
||||
private[team] case class TeamSetup(
|
||||
|
|
|
@ -16,9 +16,15 @@ final class Env(config: Config, hub: lila.hub.Env, db: lila.db.Env) {
|
|||
}
|
||||
import settings._
|
||||
|
||||
lazy val forms = new DataForm(hub.actor.captcher)
|
||||
private[team] lazy val colls = new Colls(
|
||||
team = db(CollectionTeam),
|
||||
request = db(CollectionRequest),
|
||||
member = db(CollectionMember))
|
||||
|
||||
lazy val forms = new DataForm(colls.team, hub.actor.captcher)
|
||||
|
||||
lazy val api = new TeamApi(
|
||||
coll = colls,
|
||||
cached = cached,
|
||||
notifier = notifier,
|
||||
forum = hub.actor.forum,
|
||||
|
@ -26,17 +32,14 @@ final class Env(config: Config, hub: lila.hub.Env, db: lila.db.Env) {
|
|||
timeline = hub.actor.timeline)
|
||||
|
||||
lazy val paginator = new PaginatorBuilder(
|
||||
coll = colls,
|
||||
maxPerPage = PaginatorMaxPerPage,
|
||||
maxUserPerPage = PaginatorMaxUserPerPage)
|
||||
|
||||
lazy val cli = new Cli(api)
|
||||
lazy val cli = new Cli(api, colls)
|
||||
|
||||
lazy val cached = new Cached
|
||||
|
||||
private[team] lazy val teamColl = db(CollectionTeam)
|
||||
private[team] lazy val requestColl = db(CollectionRequest)
|
||||
private[team] lazy val memberColl = db(CollectionMember)
|
||||
|
||||
private lazy val notifier = new Notifier(
|
||||
sender = NotifierSender,
|
||||
messenger = hub.actor.messenger,
|
||||
|
|
|
@ -5,13 +5,15 @@ import org.joda.time.DateTime
|
|||
import lila.user.User
|
||||
|
||||
private[team] case class Member(
|
||||
id: String,
|
||||
_id: String,
|
||||
team: String,
|
||||
user: String,
|
||||
date: DateTime) {
|
||||
|
||||
def is(userId: String): Boolean = user == userId
|
||||
def is(user: User): Boolean = is(user.id)
|
||||
|
||||
def id = _id
|
||||
}
|
||||
|
||||
private[team] object Member {
|
||||
|
@ -19,18 +21,10 @@ private[team] object Member {
|
|||
def makeId(team: String, user: String) = user + "@" + team
|
||||
|
||||
def make(team: String, user: String): Member = new Member(
|
||||
id = makeId(team, user),
|
||||
user = user,
|
||||
team = team,
|
||||
_id = makeId(team, user),
|
||||
user = user,
|
||||
team = team,
|
||||
date = DateTime.now)
|
||||
|
||||
import lila.db.JsTube, JsTube.Helpers._
|
||||
import play.api.libs.json._
|
||||
|
||||
private[team] lazy val tube = JsTube(
|
||||
(__.json update readDate('date)) andThen Json.reads[Member],
|
||||
Json.writes[Member] andThen (__.json update writeDate('date))
|
||||
)
|
||||
}
|
||||
|
||||
case class MemberWithUser(member: Member, user: User) {
|
||||
|
|
|
@ -1,41 +1,44 @@
|
|||
package lila.team
|
||||
|
||||
import play.api.libs.json.Json
|
||||
import reactivemongo.api._
|
||||
import reactivemongo.bson._
|
||||
|
||||
import lila.db.dsl._
|
||||
import tube.memberTube
|
||||
|
||||
object MemberRepo {
|
||||
|
||||
// dirty
|
||||
private val coll = Env.current.colls.member
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
type ID = String
|
||||
|
||||
def userIdsByTeam(teamId: ID): Fu[Set[ID]] =
|
||||
memberTube.coll.distinct("user", BSONDocument("team" -> teamId).some) map lila.db.BSON.asStringSet
|
||||
coll.distinct("user", $doc("team" -> teamId).some) map lila.db.BSON.asStringSet
|
||||
|
||||
def teamIdsByUser(userId: ID): Fu[Set[ID]] =
|
||||
memberTube.coll.distinct("team", BSONDocument("user" -> userId).some) map lila.db.BSON.asStringSet
|
||||
coll.distinct("team", $doc("user" -> userId).some) map lila.db.BSON.asStringSet
|
||||
|
||||
def removeByteam(teamId: ID): Funit =
|
||||
$remove(teamQuery(teamId))
|
||||
coll.remove(teamQuery(teamId)).void
|
||||
|
||||
def removeByUser(userId: ID): Funit =
|
||||
$remove(userQuery(userId))
|
||||
coll.remove(userQuery(userId)).void
|
||||
|
||||
def exists(teamId: ID, userId: ID): Fu[Boolean] =
|
||||
$count.exists(selectId(teamId, userId))
|
||||
coll.exists(selectId(teamId, userId))
|
||||
|
||||
def add(teamId: String, userId: String): Funit =
|
||||
$insert(Member.make(team = teamId, user = userId))
|
||||
coll.insert(Member.make(team = teamId, user = userId)).void
|
||||
|
||||
def remove(teamId: String, userId: String): Funit =
|
||||
$remove(selectId(teamId, userId))
|
||||
coll.remove(selectId(teamId, userId)).void
|
||||
|
||||
def countByTeam(teamId: String): Fu[Int] =
|
||||
$count(teamQuery(teamId))
|
||||
coll.countSel(teamQuery(teamId))
|
||||
|
||||
def selectId(teamId: ID, userId: ID) = $select(Member.makeId(teamId, userId))
|
||||
def teamQuery(teamId: ID) = Json.obj("team" -> teamId)
|
||||
def userQuery(userId: ID) = Json.obj("user" -> userId)
|
||||
def selectId(teamId: ID, userId: ID) = $id(Member.makeId(teamId, userId))
|
||||
def teamQuery(teamId: ID) = $doc("team" -> teamId)
|
||||
def userQuery(userId: ID) = $doc("user" -> userId)
|
||||
}
|
||||
|
|
|
@ -2,20 +2,22 @@ package lila.team
|
|||
|
||||
import lila.common.paginator._
|
||||
import lila.db.dsl._
|
||||
import lila.db.Implicits._
|
||||
import lila.db.paginator._
|
||||
import lila.user.tube.userTube
|
||||
import lila.user.User
|
||||
import tube._
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
private[team] final class PaginatorBuilder(
|
||||
coll: Colls,
|
||||
maxPerPage: Int,
|
||||
maxUserPerPage: Int) {
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
def popularTeams(page: Int): Fu[Paginator[Team]] = Paginator(
|
||||
adapter = new Adapter[Team](
|
||||
adapter = new Adapter(
|
||||
collection = coll.team,
|
||||
selector = TeamRepo.enabledQuery,
|
||||
sort = Seq(TeamRepo.sortPopular)),
|
||||
projection = $empty,
|
||||
sort = TeamRepo.sortPopular),
|
||||
page,
|
||||
maxPerPage)
|
||||
|
||||
|
@ -29,8 +31,9 @@ private[team] final class PaginatorBuilder(
|
|||
val nbResults = fuccess(team.nbMembers)
|
||||
|
||||
def slice(offset: Int, length: Int): Fu[Seq[MemberWithUser]] = for {
|
||||
members ← $find[Member]($query[Member](selector) sort sorting skip offset, length)
|
||||
users ← $find.byOrderedIds[User](members.map(_.user))
|
||||
members ← coll.member.find(selector)
|
||||
.sort(sorting).skip(offset).cursor[Member]().collect[List](length)
|
||||
users ← UserRepo byOrderedIds members.map(_.user)
|
||||
} yield members zip users map {
|
||||
case (member, user) => MemberWithUser(member, user)
|
||||
}
|
||||
|
|
|
@ -5,11 +5,13 @@ import org.joda.time.DateTime
|
|||
import lila.user.User
|
||||
|
||||
case class Request(
|
||||
id: String,
|
||||
_id: String,
|
||||
team: String,
|
||||
user: String,
|
||||
message: String,
|
||||
date: DateTime) {
|
||||
|
||||
def id = _id
|
||||
}
|
||||
|
||||
object Request {
|
||||
|
@ -17,19 +19,11 @@ object Request {
|
|||
def makeId(team: String, user: String) = user + "@" + team
|
||||
|
||||
def make(team: String, user: String, message: String): Request = new Request(
|
||||
id = makeId(team, user),
|
||||
_id = makeId(team, user),
|
||||
user = user,
|
||||
team = team,
|
||||
message = message.trim,
|
||||
date = DateTime.now)
|
||||
|
||||
import lila.db.JsTube, JsTube.Helpers._
|
||||
import play.api.libs.json._
|
||||
|
||||
private[team] lazy val tube = JsTube(
|
||||
(__.json update readDate('date)) andThen Json.reads[Request],
|
||||
Json.writes[Request] andThen (__.json update writeDate('date))
|
||||
)
|
||||
}
|
||||
|
||||
case class RequestWithUser(request: Request, user: User) {
|
||||
|
|
|
@ -1,34 +1,37 @@
|
|||
package lila.team
|
||||
|
||||
import play.api.libs.json.Json
|
||||
import reactivemongo.api._
|
||||
|
||||
import lila.db.dsl._
|
||||
import tube.requestTube
|
||||
|
||||
object RequestRepo {
|
||||
|
||||
// dirty
|
||||
private val coll = Env.current.colls.request
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
type ID = String
|
||||
|
||||
def exists(teamId: ID, userId: ID): Fu[Boolean] =
|
||||
$count.exists(selectId(teamId, userId))
|
||||
def exists(teamId: ID, userId: ID): Fu[Boolean] =
|
||||
coll.exists(selectId(teamId, userId))
|
||||
|
||||
def find(teamId: ID, userId: ID): Fu[Option[Request]] =
|
||||
$find.one(selectId(teamId, userId))
|
||||
def find(teamId: ID, userId: ID): Fu[Option[Request]] =
|
||||
coll.one[Request](selectId(teamId, userId))
|
||||
|
||||
def countByTeam(teamId: ID): Fu[Int] =
|
||||
$count(teamQuery(teamId))
|
||||
def countByTeam(teamId: ID): Fu[Int] =
|
||||
coll.countSel(teamQuery(teamId))
|
||||
|
||||
def countByTeams(teamIds: List[ID]): Fu[Int] =
|
||||
$count(teamsQuery(teamIds))
|
||||
def countByTeams(teamIds: List[ID]): Fu[Int] =
|
||||
coll.countSel(teamsQuery(teamIds))
|
||||
|
||||
def findByTeam(teamId: ID): Fu[List[Request]] =
|
||||
$find(teamQuery(teamId))
|
||||
def findByTeam(teamId: ID): Fu[List[Request]] =
|
||||
coll.list[Request](teamQuery(teamId))
|
||||
|
||||
def findByTeams(teamIds: List[ID]): Fu[List[Request]] =
|
||||
$find(teamsQuery(teamIds))
|
||||
def findByTeams(teamIds: List[ID]): Fu[List[Request]] =
|
||||
coll.list[Request](teamsQuery(teamIds))
|
||||
|
||||
def selectId(teamId: ID, userId: ID) = $select(Request.makeId(teamId, userId))
|
||||
def teamQuery(teamId: ID) = Json.obj("team" -> teamId)
|
||||
def teamsQuery(teamIds: List[ID]) = Json.obj("team" -> $in(teamIds))
|
||||
def selectId(teamId: ID, userId: ID) = $id(Request.makeId(teamId, userId))
|
||||
def teamQuery(teamId: ID) = $doc("team" -> teamId)
|
||||
def teamsQuery(teamIds: List[ID]) = $doc("team" $in teamIds)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import ornicar.scalalib.Random
|
|||
import lila.user.User
|
||||
|
||||
case class Team(
|
||||
id: String, // also the url slug
|
||||
_id: String, // also the url slug
|
||||
name: String,
|
||||
location: Option[String],
|
||||
description: String,
|
||||
|
@ -16,6 +16,8 @@ case class Team(
|
|||
createdAt: DateTime,
|
||||
createdBy: String) {
|
||||
|
||||
def id = _id
|
||||
|
||||
def slug = id
|
||||
|
||||
def disabled = !enabled
|
||||
|
@ -31,7 +33,7 @@ object Team {
|
|||
description: String,
|
||||
open: Boolean,
|
||||
createdBy: User): Team = new Team(
|
||||
id = nameToId(name),
|
||||
_id = nameToId(name),
|
||||
name = name,
|
||||
location = location,
|
||||
description = description,
|
||||
|
@ -45,12 +47,4 @@ object Team {
|
|||
// if most chars are not latin, go for random slug
|
||||
(slug.size > (name.size / 2)).fold(slug, Random nextStringUppercase 8)
|
||||
}
|
||||
|
||||
import lila.db.JsTube, JsTube.Helpers._
|
||||
import play.api.libs.json._
|
||||
|
||||
private[team] lazy val tube = JsTube(
|
||||
(__.json update readDate('createdAt)) andThen Json.reads[Team],
|
||||
Json.writes[Team] andThen (__.json update writeDate('createdAt))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,23 +5,24 @@ import akka.actor.ActorSelection
|
|||
import lila.db.dsl._
|
||||
import lila.hub.actorApi.forum.MakeTeam
|
||||
import lila.hub.actorApi.timeline.{ Propagate, TeamJoin, TeamCreate }
|
||||
import lila.user.tube.userTube
|
||||
import lila.user.{ User, UserContext }
|
||||
import lila.user.{ User, UserRepo, UserContext }
|
||||
import org.joda.time.Period
|
||||
import tube._
|
||||
|
||||
final class TeamApi(
|
||||
coll: Colls,
|
||||
cached: Cached,
|
||||
notifier: Notifier,
|
||||
forum: ActorSelection,
|
||||
indexer: ActorSelection,
|
||||
timeline: ActorSelection) {
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
val creationPeriod = Period weeks 1
|
||||
|
||||
def team(id: String) = $find.byId[Team](id)
|
||||
def team(id: String) = coll.team.byId[Team](id)
|
||||
|
||||
def request(id: String) = $find.byId[Request](id)
|
||||
def request(id: String) = coll.request.byId[Request](id)
|
||||
|
||||
def create(setup: TeamSetup, me: User): Option[Fu[Team]] = me.canTeam option {
|
||||
val s = setup.trim
|
||||
|
@ -31,7 +32,7 @@ final class TeamApi(
|
|||
description = s.description,
|
||||
open = s.isOpen,
|
||||
createdBy = me)
|
||||
$insert(team) >>
|
||||
coll.team.insert(team) >>
|
||||
MemberRepo.add(team.id, me.id) >>- {
|
||||
(cached.teamIdsCache invalidate me.id)
|
||||
(forum ! MakeTeam(team.id, team.name))
|
||||
|
@ -46,10 +47,12 @@ final class TeamApi(
|
|||
team.copy(
|
||||
location = e.location,
|
||||
description = e.description,
|
||||
open = e.isOpen) |> { team => $update(team) >>- (indexer ! InsertTeam(team)) }
|
||||
open = e.isOpen) |> { team =>
|
||||
coll.team.update($id(team.id), team).void >>- (indexer ! InsertTeam(team))
|
||||
}
|
||||
}
|
||||
|
||||
def mine(me: User): Fu[List[Team]] = $find.byIds[Team](cached teamIds me.id)
|
||||
def mine(me: User): Fu[List[Team]] = coll.team.byIds[Team](cached teamIds me.id)
|
||||
|
||||
def hasTeams(me: User): Boolean = cached.teamIds(me.id).nonEmpty
|
||||
|
||||
|
@ -58,7 +61,7 @@ final class TeamApi(
|
|||
|
||||
def requestsWithUsers(team: Team): Fu[List[RequestWithUser]] = for {
|
||||
requests ← RequestRepo findByTeam team.id
|
||||
users ← $find.byOrderedIds[User](requests map (_.user))
|
||||
users ← UserRepo byOrderedIds requests.map(_.user)
|
||||
} yield requests zip users map {
|
||||
case (request, user) => RequestWithUser(request, user)
|
||||
}
|
||||
|
@ -66,13 +69,13 @@ final class TeamApi(
|
|||
def requestsWithUsers(user: User): Fu[List[RequestWithUser]] = for {
|
||||
teamIds ← TeamRepo teamIdsByCreator user.id
|
||||
requests ← RequestRepo findByTeams teamIds
|
||||
users ← $find.byOrderedIds[User](requests map (_.user))
|
||||
users ← UserRepo byOrderedIds requests.map(_.user)
|
||||
} yield requests zip users map {
|
||||
case (request, user) => RequestWithUser(request, user)
|
||||
}
|
||||
|
||||
def join(teamId: String)(implicit ctx: UserContext): Fu[Option[Requesting]] = for {
|
||||
teamOption ← $find.byId[Team](teamId)
|
||||
teamOption ← coll.team.byId[Team](teamId)
|
||||
result ← ~(teamOption |@| ctx.me.filter(_.canTeam))({
|
||||
case (team, user) if team.open =>
|
||||
(doJoin(team, user.id) inject Joined(team).some): Fu[Option[Requesting]]
|
||||
|
@ -82,7 +85,7 @@ final class TeamApi(
|
|||
} yield result
|
||||
|
||||
def requestable(teamId: String, user: User): Fu[Option[Team]] = for {
|
||||
teamOption ← $find.byId[Team](teamId)
|
||||
teamOption ← coll.team.byId[Team](teamId)
|
||||
able ← teamOption.??(requestable(_, user))
|
||||
} yield teamOption filter (_ => able)
|
||||
|
||||
|
@ -97,14 +100,14 @@ final class TeamApi(
|
|||
_ ?? {
|
||||
val request = Request.make(team = team.id, user = user.id, message = setup.message)
|
||||
val rwu = RequestWithUser(request, user)
|
||||
$insert(request) >> (cached.nbRequests remove team.createdBy)
|
||||
coll.request.insert(request).void >> (cached.nbRequests remove team.createdBy)
|
||||
}
|
||||
}
|
||||
|
||||
def processRequest(team: Team, request: Request, accept: Boolean): Funit = for {
|
||||
_ ← $remove(request)
|
||||
_ ← coll.request.remove(request)
|
||||
_ ← cached.nbRequests remove team.createdBy
|
||||
userOption ← $find.byId[User](request.user)
|
||||
userOption ← UserRepo byId request.user
|
||||
_ ← userOption.filter(_ => accept).??(user =>
|
||||
doJoin(team, user.id) >>- notifier.acceptRequest(team, request)
|
||||
)
|
||||
|
@ -119,7 +122,7 @@ final class TeamApi(
|
|||
} recover lila.db.recoverDuplicateKey(e => ())
|
||||
|
||||
def quit(teamId: String)(implicit ctx: UserContext): Fu[Option[Team]] = for {
|
||||
teamOption ← $find.byId[Team](teamId)
|
||||
teamOption ← coll.team.byId[Team](teamId)
|
||||
result ← ~(teamOption |@| ctx.me)({
|
||||
case (team, user) => doQuit(team, user.id) inject team.some
|
||||
})
|
||||
|
@ -136,14 +139,14 @@ final class TeamApi(
|
|||
def kick(team: Team, userId: String): Funit = doQuit(team, userId)
|
||||
|
||||
def enable(team: Team): Funit =
|
||||
TeamRepo.enable(team) >>- (indexer ! InsertTeam(team))
|
||||
TeamRepo.enable(team).void >>- (indexer ! InsertTeam(team))
|
||||
|
||||
def disable(team: Team): Funit =
|
||||
TeamRepo.disable(team) >>- (indexer ! RemoveTeam(team.id))
|
||||
TeamRepo.disable(team).void >>- (indexer ! RemoveTeam(team.id))
|
||||
|
||||
// delete for ever, with members but not forums
|
||||
def delete(team: Team): Funit =
|
||||
$remove(team) >>
|
||||
coll.team.remove($id(team.id)) >>
|
||||
MemberRepo.removeByteam(team.id) >>-
|
||||
(indexer ! RemoveTeam(team.id))
|
||||
|
||||
|
@ -159,10 +162,13 @@ final class TeamApi(
|
|||
|
||||
def nbRequests(teamId: String) = cached nbRequests teamId
|
||||
|
||||
import play.api.libs.iteratee._
|
||||
def recomputeNbMembers =
|
||||
$enumerate.over[Team]($query.all[Team]) { team =>
|
||||
MemberRepo.countByTeam(team.id) flatMap { nb =>
|
||||
$update.field[String, Team, Int](team.id, "nbMembers", nb)
|
||||
coll.team.find($empty).cursor[Team]()
|
||||
.enumerate(Int.MaxValue, stopOnError = true) |>>>
|
||||
Iteratee.foldM[Team, Unit](()) {
|
||||
case (_, team) => MemberRepo.countByTeam(team.id) flatMap { nb =>
|
||||
coll.team.updateField($id(team.id), "nbMembers", nb).void
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +1,56 @@
|
|||
package lila.team
|
||||
|
||||
import org.joda.time.{ DateTime, Period }
|
||||
import play.api.libs.json.Json
|
||||
import play.modules.reactivemongo.json.ImplicitBSONHandlers.JsObjectWriter
|
||||
import reactivemongo.api._
|
||||
import reactivemongo.bson._
|
||||
|
||||
import lila.db.dsl._
|
||||
import lila.user.User
|
||||
import tube.teamTube
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
object TeamRepo {
|
||||
|
||||
// dirty
|
||||
private val coll = Env.current.colls.team
|
||||
|
||||
import BSONHandlers._
|
||||
|
||||
type ID = String
|
||||
|
||||
def byOrderedIds(ids: Seq[String]) = coll.byOrderedIds[Team](ids)(_.id)
|
||||
|
||||
def cursor(selector: Bdoc) = coll.find(selector).cursor[Team]()
|
||||
|
||||
def owned(id: String, createdBy: String): Fu[Option[Team]] =
|
||||
$find.one($select(id) ++ Json.obj("createdBy" -> createdBy))
|
||||
coll.one[Team]($id(id) ++ $doc("createdBy" -> createdBy))
|
||||
|
||||
def teamIdsByCreator(userId: String): Fu[List[String]] =
|
||||
teamTube.coll.distinct("_id", BSONDocument("createdBy" -> userId).some) map lila.db.BSON.asStrings
|
||||
coll.distinct("_id", BSONDocument("createdBy" -> userId).some) map lila.db.BSON.asStrings
|
||||
|
||||
def name(id: String): Fu[Option[String]] =
|
||||
$primitive.one($select(id), "name")(_.asOpt[String])
|
||||
coll.primitiveOne[String]($id(id), "name")
|
||||
|
||||
def userHasCreatedSince(userId: String, duration: Period): Fu[Boolean] =
|
||||
$count.exists(Json.obj(
|
||||
"createdAt" -> $gt($date(DateTime.now minus duration)),
|
||||
coll.exists($doc(
|
||||
"createdAt" $gt DateTime.now.minus(duration),
|
||||
"createdBy" -> userId
|
||||
))
|
||||
|
||||
def ownerOf(teamId: String): Fu[Option[String]] =
|
||||
$primitive.one($select(teamId), "createdBy")(_.asOpt[String])
|
||||
coll.primitiveOne[String]($id(teamId), "createdBy")
|
||||
|
||||
def incMembers(teamId: String, by: Int): Funit =
|
||||
$update($select(teamId), $inc("nbMembers" -> by))
|
||||
coll.update($id(teamId), $inc("nbMembers" -> by)).void
|
||||
|
||||
def enable(team: Team) = $update.field(team.id, "enabled", true)
|
||||
def enable(team: Team) = coll.updateField($id(team.id), "enabled", true)
|
||||
|
||||
def disable(team: Team) = $update.field(team.id, "enabled", false)
|
||||
def disable(team: Team) = coll.updateField($id(team.id), "enabled", false)
|
||||
|
||||
def addRequest(teamId: String, request: Request): Funit =
|
||||
$update(
|
||||
$select(teamId) ++ Json.obj("requests.user" -> $ne(request.user)),
|
||||
$push("requests", request.user))
|
||||
coll.update(
|
||||
$id(teamId) ++ $doc("requests.user" $ne request.user),
|
||||
$push("requests", request.user)).void
|
||||
|
||||
val enabledQuery = Json.obj("enabled" -> true)
|
||||
val enabledQuery = $doc("enabled" -> true)
|
||||
|
||||
val sortPopular = $sort desc "nbMembers"
|
||||
}
|
||||
|
|
|
@ -2,14 +2,5 @@ package lila
|
|||
|
||||
package object team extends PackageObject with WithPlay {
|
||||
|
||||
object tube {
|
||||
|
||||
implicit lazy val teamTube = Team.tube inColl Env.current.teamColl
|
||||
|
||||
private[team] implicit lazy val requestTube = Request.tube inColl Env.current.requestColl
|
||||
|
||||
private[team] implicit lazy val memberTube = Member.tube inColl Env.current.memberColl
|
||||
}
|
||||
|
||||
private[team] def logger = lila.log("team")
|
||||
}
|
||||
|
|
|
@ -3,9 +3,8 @@ package lila.teamSearch
|
|||
import akka.actor._
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import lila.db.dsl.{ $find, $cursor }
|
||||
import lila.db.dsl._
|
||||
import lila.search._
|
||||
import lila.team.tube.teamTube
|
||||
|
||||
final class Env(
|
||||
config: Config,
|
||||
|
@ -18,7 +17,7 @@ final class Env(
|
|||
|
||||
private val client = makeClient(Index(IndexName))
|
||||
|
||||
val api = new TeamSearchApi(client, $find.byOrderedIds[lila.team.Team] _)
|
||||
val api = new TeamSearchApi(client)
|
||||
|
||||
def apply(text: String, page: Int) = paginatorBuilder(Query(text), page)
|
||||
|
||||
|
|
|
@ -2,17 +2,16 @@ package lila.teamSearch
|
|||
|
||||
import lila.search._
|
||||
import lila.team.actorApi._
|
||||
import lila.team.Team
|
||||
import lila.team.{ Team, TeamRepo }
|
||||
|
||||
import play.api.libs.json._
|
||||
import play.api.libs.iteratee._
|
||||
|
||||
final class TeamSearchApi(
|
||||
client: ESClient,
|
||||
fetcher: Seq[String] => Fu[List[Team]]) extends SearchReadApi[Team, Query] {
|
||||
final class TeamSearchApi(client: ESClient) extends SearchReadApi[Team, Query] {
|
||||
|
||||
def search(query: Query, from: From, size: Size) =
|
||||
client.search(query, from, size) flatMap { res =>
|
||||
fetcher(res.ids)
|
||||
TeamRepo byOrderedIds res.ids
|
||||
}
|
||||
|
||||
def count(query: Query) = client.count(query) map (_.count)
|
||||
|
@ -29,10 +28,12 @@ final class TeamSearchApi(
|
|||
case c: ESClientHttp => c.putMapping >> {
|
||||
lila.log("teamSearch").info(s"Index to ${c.index.name}")
|
||||
import lila.db.dsl._
|
||||
import lila.team.tube.teamTube
|
||||
$enumerate.bulk[Option[Team]]($query[Team](Json.obj("enabled" -> true)), 300) { teamOptions =>
|
||||
c.storeBulk(teamOptions.flatten map (t => Id(t.id) -> toDoc(t)))
|
||||
}
|
||||
TeamRepo.cursor($doc("enabled" -> true))
|
||||
.enumerateBulks(Int.MaxValue) |>>>
|
||||
Iteratee.foldM[Iterator[Team], Unit](()) {
|
||||
case (_, teams) =>
|
||||
c.storeBulk(teams.toList map (t => Id(t.id) -> toDoc(t)))
|
||||
}
|
||||
}
|
||||
case _ => funit
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue