parent
1967f96d7c
commit
8dd85bc9ff
|
@ -2,9 +2,7 @@ package lila.db
|
|||
|
||||
import com.typesafe.config.Config
|
||||
import dsl.Coll
|
||||
import reactivemongo.api.{ DefaultDB, MongoConnection, MongoDriver, FailoverStrategy, ReadPreference }
|
||||
import reactivemongo.api.commands.Command
|
||||
import reactivemongo.api.BSONSerializationPack
|
||||
import reactivemongo.api.{ DefaultDB, MongoConnection, MongoDriver }
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ Await, ExecutionContext, Future }
|
||||
import scala.util.{ Failure, Success }
|
||||
|
@ -45,11 +43,6 @@ final class Env(
|
|||
def apply(name: String)(implicit ec: ExecutionContext): Coll =
|
||||
db(ec).apply(name)
|
||||
|
||||
val runCommand: RunCommand = (command, readPreference) => {
|
||||
val runner = Command.run(BSONSerializationPack, FailoverStrategy.strict)
|
||||
runner(db, runner.rawCommand(command)).one[dsl.Bdoc](readPreference)
|
||||
}
|
||||
|
||||
object image {
|
||||
private lazy val imageColl = apply(config getString "image.collection")
|
||||
import dsl._
|
||||
|
|
|
@ -2,6 +2,7 @@ package lila.db
|
|||
package paginator
|
||||
|
||||
import dsl._
|
||||
import reactivemongo.api.collections.bson.BSONCollection
|
||||
import reactivemongo.api._
|
||||
import reactivemongo.bson._
|
||||
|
||||
|
@ -17,10 +18,10 @@ final class CachedAdapter[A](
|
|||
}
|
||||
|
||||
final class Adapter[A: BSONDocumentReader](
|
||||
collection: Coll,
|
||||
selector: Bdoc,
|
||||
projection: Bdoc,
|
||||
sort: Bdoc,
|
||||
collection: BSONCollection,
|
||||
selector: BSONDocument,
|
||||
projection: BSONDocument,
|
||||
sort: BSONDocument,
|
||||
readPreference: ReadPreference = ReadPreference.primary
|
||||
) extends AdapterLike[A] {
|
||||
|
||||
|
@ -30,29 +31,6 @@ final class Adapter[A: BSONDocumentReader](
|
|||
collection.find(selector, projection)
|
||||
.sort(sort)
|
||||
.skip(offset)
|
||||
.list[A](length, readPreference)
|
||||
}
|
||||
|
||||
final class MapReduceAdapter[A: BSONDocumentReader](
|
||||
collection: Coll,
|
||||
selector: Bdoc,
|
||||
runCommand: RunCommand,
|
||||
command: MapReduceAdapter.Command,
|
||||
readPreference: ReadPreference = ReadPreference.primary
|
||||
) extends AdapterLike[A] {
|
||||
|
||||
def nbResults: Fu[Int] = collection.countSel(selector, readPreference)
|
||||
|
||||
def slice(offset: Int, length: Int): Fu[List[A]] =
|
||||
runCommand(
|
||||
command(offset) ++ $doc("limit" -> (offset + length)),
|
||||
readPreference
|
||||
) map { res =>
|
||||
res.getAs[List[Bdoc]]("results").??(_ map implicitly[BSONDocumentReader[A]].read)
|
||||
}
|
||||
}
|
||||
|
||||
object MapReduceAdapter {
|
||||
// offset -> doc
|
||||
type Command = Int => Bdoc
|
||||
.cursor[A](readPreference = readPreference)
|
||||
.gather[List](length)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package lila
|
||||
|
||||
import reactivemongo.api.ReadPreference
|
||||
import reactivemongo.api.commands.WriteResult
|
||||
|
||||
package object db extends PackageObject {
|
||||
|
||||
type RunCommand = (dsl.Bdoc, ReadPreference) => Fu[dsl.Bdoc]
|
||||
|
||||
def recoverDuplicateKey[A](f: WriteResult => A): PartialFunction[Throwable, A] = {
|
||||
case wr: WriteResult if isDuplicateKey(wr) => f(wr)
|
||||
}
|
||||
|
|
|
@ -165,7 +165,6 @@ final class Env(
|
|||
)
|
||||
|
||||
lazy val multiBoard = new StudyMultiBoard(
|
||||
runCommand = db.runCommand,
|
||||
chapterColl = chapterColl,
|
||||
maxPerPage = lila.common.MaxPerPage(9)
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package lila.study
|
||||
|
||||
import play.api.libs.json._
|
||||
import reactivemongo.api.ReadPreference
|
||||
import reactivemongo.bson._
|
||||
|
||||
import chess.Color
|
||||
|
@ -10,14 +9,12 @@ import chess.format.{ FEN, Uci }
|
|||
|
||||
import BSONHandlers._
|
||||
import JsonView._
|
||||
import lila.db.dsl._
|
||||
import lila.common.MaxPerPage
|
||||
import lila.common.paginator.{ Paginator, PaginatorJson }
|
||||
import lila.db.dsl._
|
||||
import lila.db.paginator.{ Adapter, MapReduceAdapter }
|
||||
import lila.game.BSONHandlers.FENBSONHandler
|
||||
import lila.db.paginator.Adapter
|
||||
|
||||
final class StudyMultiBoard(
|
||||
runCommand: lila.db.RunCommand,
|
||||
chapterColl: Coll,
|
||||
maxPerPage: MaxPerPage
|
||||
) {
|
||||
|
@ -28,54 +25,43 @@ final class StudyMultiBoard(
|
|||
PaginatorJson(p)
|
||||
}
|
||||
|
||||
private def get(study: Study, page: Int, playing: Boolean): Fu[Paginator[ChapterPreview]] = {
|
||||
|
||||
val selector = $doc("studyId" -> study.id) ++ playing.??(playingSelector)
|
||||
|
||||
/* If players are found in the tags,
|
||||
* return the last mainline node.
|
||||
* Else, return the root node without its children.
|
||||
*/
|
||||
val command: MapReduceAdapter.Command = offset => $doc(
|
||||
"mapreduce" -> chapterColl.name,
|
||||
"map" -> """var node = this.root, child, result = {name:this.name,orientation:this.setup.orientation,tags:this.tags};
|
||||
if (this.tags.filter(t => t.indexOf('White:') === 0 || t.indexOf('Black:') === 0).length === 2) {
|
||||
while(child = node.n[0]) { node = child };
|
||||
}
|
||||
result.fen = node.f;
|
||||
result.uci = node.u;
|
||||
emit(this._id, result)""",
|
||||
"reduce" -> """function(key, values) { return key; }""",
|
||||
"out" -> $doc("inline" -> true),
|
||||
"query" -> selector,
|
||||
"sort" -> $sort.asc("order"),
|
||||
"jsMode" -> true
|
||||
)
|
||||
Paginator(
|
||||
adapter = new MapReduceAdapter[ChapterPreview](
|
||||
collection = chapterColl,
|
||||
selector = selector,
|
||||
runCommand = runCommand,
|
||||
command = command
|
||||
),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage
|
||||
)
|
||||
}
|
||||
private def get(study: Study, page: Int, playing: Boolean): Fu[Paginator[ChapterPreview]] = Paginator(
|
||||
adapter = new Adapter[ChapterPreview](
|
||||
collection = chapterColl,
|
||||
selector = $doc("studyId" -> study.id) ++ playing.??(playingSelector),
|
||||
projection = projection,
|
||||
sort = $sort asc "order"
|
||||
),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage
|
||||
)
|
||||
|
||||
private val playingSelector = $doc("tags" -> "Result:*")
|
||||
|
||||
private val projection = $doc(
|
||||
"name" -> true,
|
||||
"tags" -> true,
|
||||
"root" -> true,
|
||||
"setup.orientation" -> true
|
||||
)
|
||||
|
||||
private implicit val previewBSONReader = new BSONDocumentReader[ChapterPreview] {
|
||||
def read(result: BSONDocument) = {
|
||||
val doc = result.getAs[List[Bdoc]]("value").flatMap(_.headOption) err "No mapReduce value?!"
|
||||
def read(doc: BSONDocument) = {
|
||||
val tags = doc.getAs[Tags]("tags")
|
||||
val players = tags flatMap ChapterPreview.players
|
||||
val root = doc.getAs[Node.Root]("root").err("Preview missing root")
|
||||
val node =
|
||||
if (players.isDefined) root.lastMainlineNode
|
||||
else root
|
||||
ChapterPreview(
|
||||
id = result.getAs[Chapter.Id]("_id") err "Preview missing id",
|
||||
id = doc.getAs[Chapter.Id]("_id") err "Preview missing id",
|
||||
name = doc.getAs[Chapter.Name]("name") err "Preview missing name",
|
||||
players = tags flatMap ChapterPreview.players,
|
||||
orientation = doc.getAs[Color]("orientation") getOrElse Color.White,
|
||||
fen = doc.getAs[FEN]("fen") err "Preview missing FEN",
|
||||
lastMove = doc.getAs[Uci]("uci"),
|
||||
players = players,
|
||||
orientation = doc.getAs[Bdoc]("setup") flatMap { setup =>
|
||||
setup.getAs[Color]("orientation")
|
||||
} getOrElse Color.White,
|
||||
fen = node.fen,
|
||||
lastMove = node.moveOption.map(_.uci),
|
||||
playing = tags.flatMap(_(_.Result)) has "*"
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue