Skip to content

Commit

Permalink
Automatically generate entry IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
RawToast committed Mar 25, 2018
1 parent 02c7a88 commit f296b03
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 39 deletions.
4 changes: 2 additions & 2 deletions dokusho-server/src/main/scala/Main.scala
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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] =
Expand Down
28 changes: 3 additions & 25 deletions dokusho-server/src/main/scala/dokusho/MongoRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,22 @@ 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] =
collection.replaceOne(equal("userId", g.userId), Document.parse(g.asJson.spaces2),
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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))
Expand Down
26 changes: 18 additions & 8 deletions dokusho-server/src/main/scala/dokusho/ReadingHistoryService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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))
}
}

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))
}
3 changes: 2 additions & 1 deletion dokusho-server/src/main/scala/dokusho/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit f296b03

Please sign in to comment.