Skip to content

Instantly share code, notes, and snippets.

object BatchFetchable {
def user(userId: Id[User]): BatchFetchable[User] =
BatchFetchable(Keys(Set(userId), Set(), Set(), Set()), _.users(userId))
def group(groupId: Id[Group]): BatchFetchable[Group] =
BatchFetchable(Keys(Set(), Set(groupId), Set(), Set()), _.groups(groupId))
def user(postId: Id[Post]): BatchFetchable[Post] =
BatchFetchable(Keys(Set(), Set(), Set(postId), Set()), _.posts(postId))
def user(msgId: Id[Message]): BatchFetchable[Message] =
BatchFetchable(Keys(Set(), Set(), Set(), Set(msgId)), _.msgs(msgId))
}
def getUsers(userIds: Set[Id[User]]): Map[Id[User], User] = {
getManyUsersFromDatabase(userIds)
}
def getUsers(userIds: Set[Id[User]]): Map[Id[User], User] = {
userIds.map { userId =>
userId -> getUserFromDatabase(userId)
}.toMap
}
def getLatestKeeps(userId: Id[User]): Seq[Keep] = {
val teams = getTeamsForUserFromDatabase(userId)
val libraries = getLibrariesForTeamsFromDatabase(teams.map(_.id))
val keeps = getLatestKeepsForLibrariesFromDatabase(libraries.map(_.id))
keeps
}
case class BatchFetchable[T](keys: Keys, run: Entities => T)
case class Keys(users: Set[Id[User]], groups: Set[Id[Group]], posts: Set[Id[Post]], msgs: Set[Id[Message]])
case class Entities(
users: Map[Id[User], User],
groups: Map[Id[Group], Group],
posts: Map[Id[Post], Post],
msgs: Map[Id[Message], Message]))
def generateNotifications(activity: Seq[Event]): BatchFetchable[Seq[String]] = {
BatchFetchable.seq(activity.map {
case NewPost(userId, groupId, postId) =>
(BatchFetchable.user(userId) and
BatchFetchable.group(groupId) and
BatchFetchable.post(keepId)).tupled.map {
case (user, group, post) =>
s"${user.fullName} shared ${post.title} with ${group.name}"
}
case NewMessage(fromId, toId, msgId) =>
implicit val bfFCB: FunctionalCanBuild[BatchFetchable] = new FunctionalCanBuild[BatchFetchable] {
def apply[A, B](ma: BatchFetchable[A], mb: BatchFetchable[B]): BatchFetchable[~[A, B]] = {
BatchFetchable[~[A, B]](ma.keys ++ mb.keys, vs => new ~(ma.run(vs), mb.run(vs)))
}
}
implicit val bfFunctor: Functor[BatchFetchable] = new Functor[BatchFetchable] {
def fmap[A, B](ma: BatchFetchable[A], f: A => B): BatchFetchable[B] =
BatchFetchable(ma.keys, ma.run andThen f)
}
def generateNotifications(activity: Seq[Event]): Seq[BatchFetchable[String]] = {
activity.map {
case NewPost(userId, groupId, postId) => BatchFetchable[String](
keys = Keys(Set(userId), Set(groupId), Set(postId), Set()),
entities =>
val user = entities.users(userId)
val group = entities.groups(groupId)
val post = entities.posts(postId)
s"${user.fullName} shared ${post.title} with ${group.name}"
)
sealed trait Event
case class NewPost(userId: Id[User], groupId: Id[Group], postId: Id[Post]) extends Event
case class NewMessage(from: Id[User], to: Id[User], msgId: Id[Message]) extends Event
def generateNotifications(activity: Seq[Event]): Seq[String] = {
val (allUsers, allGroups, allPosts, allMsgs) = {
val userIds: Set[Id[User]] = activity.collect {
case NewPost(userId, _, _) => userId
case NewMessage(userId, _, _) => userId
}.toSet
case class NewPost(userId: Id[User], groupId: Id[Group], postId: Id[Post])
def generateNotifications(activity: Seq[NewPost]): Seq[String] = {
val (allUsers, allGroups, allPosts) = {
val usersIds = activity.map(_.userId).toSet
val groupIds = activity.map(_.groupId).toSet
val postIds = activity.map(_.postId).toSet
(getManyUsersFromDb(userIds), getManyGroupsFromDb(groupIds), getManyPostsFromDb(postIds))
}
activity.map {
case NewPost(userId, groupId, postId) =>