lila/modules/relation/src/main/RelationRepo.scala

133 lines
3.5 KiB
Scala
Raw Normal View History

package lila.relation
2019-11-29 19:16:11 -07:00
import reactivemongo.api.bson._
2019-11-30 15:45:44 -07:00
import reactivemongo.api.ReadPreference
import org.joda.time.DateTime
2013-05-24 11:04:49 -06:00
2016-04-01 11:50:57 -06:00
import lila.db.dsl._
import lila.user.User
final private class RelationRepo(coll: Coll, userRepo: lila.user.UserRepo)(implicit
ec: scala.concurrent.ExecutionContext
) {
2019-11-30 15:45:44 -07:00
import RelationRepo._
2016-01-23 11:58:04 -07:00
def following(userId: ID) = relating(userId, Follow)
def blockers(userId: ID) = relaters(userId, Block)
def blocking(userId: ID) = relating(userId, Block)
def freshFollowersFromSecondary(userId: ID): Fu[List[User.ID]] =
coll
.aggregateOne(readPreference = ReadPreference.secondaryPreferred) { implicit framework =>
import framework._
Match($doc("u2" -> userId, "r" -> Follow)) -> List(
PipelineOperator(
$doc(
"$lookup" -> $doc(
"from" -> userRepo.coll.name,
"let" -> $doc("uid" -> "$u1"),
"pipeline" -> $arr(
$doc(
"$match" -> $doc(
"$expr" -> $doc(
"$and" -> $arr(
$doc("$eq" -> $arr("$_id", "$$uid")),
$doc("$gt" -> $arr("$seenAt", DateTime.now.minusDays(10)))
)
)
)
),
$doc("$project" -> $id(true))
),
"as" -> "follower"
)
)
),
Match("follower" $ne $arr()),
Group(BSONNull)(
"ids" -> PushField("u1")
)
)
}
.map(~_.flatMap(_.getAsOpt[List[User.ID]]("ids")))
2018-04-05 14:21:47 -06:00
def followingLike(userId: ID, term: String): Fu[List[ID]] =
User.couldBeUsername(term) ?? {
2019-12-13 07:30:20 -07:00
coll.secondaryPreferred.distinctEasy[ID, List](
"u2",
$doc(
"u1" -> userId,
"u2" $startsWith term.toLowerCase,
"r" -> Follow
)
)
2018-04-05 14:21:47 -06:00
}
2019-12-13 07:30:20 -07:00
private def relaters(
userId: ID,
relation: Relation,
rp: ReadPreference = ReadPreference.primary
): Fu[Set[ID]] =
coll
.distinctEasy[ID, Set](
2019-12-13 07:30:20 -07:00
"u1",
$doc(
"u2" -> userId,
"r" -> relation
),
rp
2019-12-13 07:30:20 -07:00
)
2013-05-23 08:19:30 -06:00
private def relating(userId: ID, relation: Relation): Fu[Set[ID]] =
coll.distinctEasy[ID, Set](
2019-12-13 07:30:20 -07:00
"u2",
$doc(
"u1" -> userId,
"r" -> relation
)
)
2019-12-13 07:30:20 -07:00
def follow(u1: ID, u2: ID): Funit = save(u1, u2, Follow)
def unfollow(u1: ID, u2: ID): Funit = remove(u1, u2)
2019-12-13 07:30:20 -07:00
def block(u1: ID, u2: ID): Funit = save(u1, u2, Block)
def unblock(u1: ID, u2: ID): Funit = remove(u1, u2)
def unfollowMany(u1: ID, u2s: Iterable[ID]): Funit =
coll.delete.one($inIds(u2s map { makeId(u1, _) })).void
2019-11-30 15:45:44 -07:00
def unfollowAll(u1: ID): Funit = coll.delete.one($doc("u1" -> u1)).void
2019-12-13 07:30:20 -07:00
private def save(u1: ID, u2: ID, relation: Relation): Funit =
coll.update
.one(
$id(makeId(u1, u2)),
$doc("u1" -> u1, "u2" -> u2, "r" -> relation),
upsert = true
)
.void
2020-07-05 00:47:37 -06:00
.recover(lila.db.ignoreDuplicateKey)
2019-11-30 15:45:44 -07:00
def remove(u1: ID, u2: ID): Funit = coll.delete.one($id(makeId(u1, u2))).void
2014-05-02 11:39:52 -06:00
def drop(userId: ID, relation: Relation, nb: Int) =
2019-12-13 07:30:20 -07:00
coll
.find(
$doc("u1" -> userId, "r" -> relation),
$doc("_id" -> true).some
)
2020-07-19 08:00:47 -06:00
.cursor[Bdoc]()
.list(nb)
.dmap {
2019-11-30 15:45:44 -07:00
_.flatMap { _.string("_id") }
2016-04-01 23:36:30 -06:00
} flatMap { ids =>
2019-12-13 07:30:20 -07:00
coll.delete.one($inIds(ids)).void
}
2019-11-30 15:45:44 -07:00
}
object RelationRepo {
2014-05-02 11:39:52 -06:00
2019-11-30 15:45:44 -07:00
def makeId(u1: ID, u2: ID) = s"$u1/$u2"
}