From f296b03e32607d0224782af8556bf86fe033c1df Mon Sep 17 00:00:00 2001 From: rawtoast Date: Sun, 25 Mar 2018 14:32:45 +0100 Subject: [PATCH] Automatically generate entry IDs --- dokusho-server/src/main/scala/Main.scala | 4 +-- .../main/scala/dokusho/MongoRepository.scala | 28 ++----------------- ...point.scala => ReadingHistoryRouter.scala} | 6 ++-- .../scala/dokusho/ReadingHistoryService.scala | 26 +++++++++++------ .../src/main/scala/dokusho/package.scala | 3 +- 5 files changed, 28 insertions(+), 39 deletions(-) rename dokusho-server/src/main/scala/dokusho/{ReadingHistoryEndpoint.scala => ReadingHistoryRouter.scala} (86%) diff --git a/dokusho-server/src/main/scala/Main.scala b/dokusho-server/src/main/scala/Main.scala index 56b03b1..7fc1219 100644 --- a/dokusho-server/src/main/scala/Main.scala +++ b/dokusho-server/src/main/scala/Main.scala @@ -1,5 +1,5 @@ import cats.effect._ -import dokusho.{MongoRepository, ReadingHistoryEndpoint, ReadingHistoryService} +import dokusho.{MongoRepository, ReadingHistoryRouter, ReadingHistoryService} import fs2.StreamApp.ExitCode import fs2.{Stream, StreamApp} import org.http4s.server.ServerBuilder @@ -16,7 +16,7 @@ object Main extends StreamApp[IO] { "dokusho") val readingHistoryService = new ReadingHistoryService(mongo) - val historyService = new ReadingHistoryEndpoint(readingHistoryService) + val historyService = new ReadingHistoryRouter(readingHistoryService) override def stream(args: List[String], requestShutdown: IO[Unit]): Stream[IO, ExitCode] = diff --git a/dokusho-server/src/main/scala/dokusho/MongoRepository.scala b/dokusho-server/src/main/scala/dokusho/MongoRepository.scala index 6abe682..0007b63 100644 --- a/dokusho-server/src/main/scala/dokusho/MongoRepository.scala +++ b/dokusho-server/src/main/scala/dokusho/MongoRepository.scala @@ -26,13 +26,13 @@ class MongoRepository(connectionString: String, databaseName: String, collection .getCollection(collectionName) def get(userId: String): IO[Option[UserReadingHistory]] = - OptionT(getDocumentIoOpt(userId)) + OptionT(getDocument(userId).asIOOpt) .semiflatMap(toUserReadingHistory) .value - def getUnsafe(userId: String): IO[UserReadingHistory] = - getDocumentIO(userId) + getDocument(userId) + .asIO .flatMap(toUserReadingHistory) def put(g: UserReadingHistory): IO[UserReadingHistory] = @@ -40,30 +40,8 @@ class MongoRepository(connectionString: String, databaseName: String, collection model.UpdateOptions().upsert(true)).asIO .map(_ => g) - def addEntry(userId: String, date: String, entry: Entry): IO[UserReadingHistory] = { - for { - urh <- getUnsafe(userId) - days = urh.readingHistory.days - dayToUpdate = days.find(_.date == date).getOrElse(Day(date, Seq.empty)) - updatedDay = entriesLens.modify(_ :+ entry)(dayToUpdate) - doc = daysLens.modify(upsertDay(updatedDay))(urh) - } yield doc - } - - private def upsertDay(day: Day)(days: Seq[Day]): Seq[Day] = - if (days.exists(_.date == day.date)) { - days.withFilter(_.date == day.date) - .map(_ => day) - } else { - days :+ day - } - private def getDocument(id: String): FindObservable[Document] = collection.find(equal("userId", id)) - private def getDocumentIO(id: String): IO[Document] = getDocument(id).asIO - - private def getDocumentIoOpt(id: String): IO[Option[Document]] = getDocument(id).asIOOpt - private def toUserReadingHistory(task: Document): IO[UserReadingHistory] = { for { json <- parseJson(task.toJson) diff --git a/dokusho-server/src/main/scala/dokusho/ReadingHistoryEndpoint.scala b/dokusho-server/src/main/scala/dokusho/ReadingHistoryRouter.scala similarity index 86% rename from dokusho-server/src/main/scala/dokusho/ReadingHistoryEndpoint.scala rename to dokusho-server/src/main/scala/dokusho/ReadingHistoryRouter.scala index 853bcbd..fd868fa 100644 --- a/dokusho-server/src/main/scala/dokusho/ReadingHistoryEndpoint.scala +++ b/dokusho-server/src/main/scala/dokusho/ReadingHistoryRouter.scala @@ -8,7 +8,7 @@ import org.http4s._ import org.http4s.circe._ import org.http4s.dsl.io.{->, /, GET, Ok, Root, _} -class ReadingHistoryEndpoint(readingHistoryService: ReadingHistoryService) { +class ReadingHistoryRouter(readingHistoryService: ReadingHistoryService) { case class SuccessfulPut(userId: String) @@ -28,9 +28,9 @@ class ReadingHistoryEndpoint(readingHistoryService: ReadingHistoryService) { response <- Ok(json) } yield response case req@POST -> Root / "history" / userId / "add" => - implicit val entryDecoder: EntityDecoder[IO, Entry] = jsonOf[IO, Entry] + implicit val entryDecoder: EntityDecoder[IO, NewEntry] = jsonOf[IO, NewEntry] for { - entry <- req.as[Entry] + entry <- req.as[NewEntry] storedHistory <- readingHistoryService.addNewEntry(userId, entry ) json = storedHistory.map(_.asJson) result <- json.fold(NotFound())(j => Ok(j)) diff --git a/dokusho-server/src/main/scala/dokusho/ReadingHistoryService.scala b/dokusho-server/src/main/scala/dokusho/ReadingHistoryService.scala index 22dea97..93ec6f4 100644 --- a/dokusho-server/src/main/scala/dokusho/ReadingHistoryService.scala +++ b/dokusho-server/src/main/scala/dokusho/ReadingHistoryService.scala @@ -8,10 +8,13 @@ import monocle.macros.GenLens class ReadingHistoryService(mongoRepository: MongoRepository) { + private lazy val daysLens = GenLens[UserReadingHistory](_.readingHistory.days) + private lazy val entriesLens = GenLens[Day](_.entries) + def getReadingHistory(userId: String): IO[Option[UserReadingHistory]] = mongoRepository.get(userId) - def addNewEntry(userId: String, entry: Entry): IO[Option[UserReadingHistory]] = { + def addNewEntry(userId: String, entry: NewEntry): IO[Option[UserReadingHistory]] = { lazy val update = daysLens.modify(updateDay(entry)) OptionT(getReadingHistory(userId)) .map(update) @@ -22,13 +25,20 @@ class ReadingHistoryService(mongoRepository: MongoRepository) { def upsert(userReadingHistory: UserReadingHistory): IO[UserReadingHistory] = mongoRepository.put(userReadingHistory) - private lazy val daysLens = GenLens[UserReadingHistory](_.readingHistory.days) + private def updateDay(entry: NewEntry)(days: Seq[Day]) = { + val currentDay = Day(LocalDate.now().atStartOfDay().toString, Seq.empty) - private def updateDay(entry: Entry)(days: Seq[Day]) = { - val newDay = Day(LocalDate.now().atStartOfDay().toString, Seq.empty) - val ndays = if (days.exists(_.date == newDay.date)) days else newDay +: days + val daysWithUpdatedDay = + if (days.exists(_.date == currentDay.date)) days + else currentDay +: days - ndays.withFilter(_.date == newDay.date) - .map(d => d.copy(entries = entry +: d.entries)) + daysWithUpdatedDay.withFilter(_.date == currentDay.date) + .map(addEntry(entry)) } -} \ No newline at end of file + + private def addEntry(entry: NewEntry) = entriesLens + .modify { es => Entry(getNextId(es), entry.kind, entry.value) +: es} + + private def getNextId(entries: Seq[Entry]) = + entries.foldLeft(0l)((currMax, entry) => Math.max(currMax, entry.id)) +} diff --git a/dokusho-server/src/main/scala/dokusho/package.scala b/dokusho-server/src/main/scala/dokusho/package.scala index cd41973..51d7f79 100644 --- a/dokusho-server/src/main/scala/dokusho/package.scala +++ b/dokusho-server/src/main/scala/dokusho/package.scala @@ -7,7 +7,8 @@ package object dokusho { case class Day(date: String, entries: Seq[Entry]) case class Entry(id: Long, kind: PageType, value: Int) - case class Testy(id: Long, value: Int) + + case class NewEntry(kind: PageType, value: Int) sealed trait PageType