Skip to content

Commit

Permalink
refactor: use cats.data.ContT instead of Action
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshinorin committed Jul 15, 2024
1 parent 77ac627 commit 2449a39
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 158 deletions.
18 changes: 0 additions & 18 deletions src/main/scala/net/yoshinorin/qualtet/actions/Action.scala

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package net.yoshinorin.qualtet.domains.archives

import cats.Monad
import cats.data.ContT
import cats.effect.IO
import net.yoshinorin.qualtet.actions.Action.*
import net.yoshinorin.qualtet.actions.{Action, Continue}
import net.yoshinorin.qualtet.domains.contentTypes.ContentTypeService
import net.yoshinorin.qualtet.message.Fail.NotFound
import net.yoshinorin.qualtet.infrastructure.db.Executer
import net.yoshinorin.qualtet.domains.contentTypes.ContentTypeId
import net.yoshinorin.qualtet.syntax.*
import cats.Monad

class ArchiveService[F[_]: Monad](
archiveRepository: ArchiveRepository[F],
contentTypeService: ContentTypeService[F]
)(using executer: Executer[F, IO]) {

def actions(contentTypeId: ContentTypeId): Action[Seq[ResponseArchive]] = {
Continue(archiveRepository.get(contentTypeId), Action.done[Seq[ResponseArchive]])
def actions(contentTypeId: ContentTypeId): ContT[F, Seq[ResponseArchive], Seq[ResponseArchive]] = {
ContT.apply[F, Seq[ResponseArchive], Seq[ResponseArchive]] { next =>
archiveRepository.get(contentTypeId)
}
}

def get: IO[Seq[ResponseArchive]] = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package net.yoshinorin.qualtet.domains.articles

import cats.data.ContT
import cats.effect.IO
import cats.Monad
import net.yoshinorin.qualtet.actions.Action.*
import net.yoshinorin.qualtet.actions.{Action, Continue}
import net.yoshinorin.qualtet.domains.contentTypes.{ContentTypeId, ContentTypeService}
import net.yoshinorin.qualtet.message.Fail.NotFound
import net.yoshinorin.qualtet.domains.tags.TagName
Expand All @@ -21,36 +20,36 @@ class ArticleService[F[_]: Monad](
contentTypeId: ContentTypeId,
none: Unit = (),
queryParams: ArticlesQueryParameter
): Action[Seq[(Int, ResponseArticle)]] = {
Continue(articleRepository.getWithCount(contentTypeId, queryParams), Action.done[Seq[(Int, ResponseArticle)]])
): ContT[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]] = {
ContT.apply[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]] { next =>
articleRepository.getWithCount(contentTypeId, queryParams)
}
}

def tagActions(
contentTypeId: ContentTypeId,
tagName: TagName,
queryParams: ArticlesQueryParameter
): Action[Seq[(Int, ResponseArticle)]] = {
Continue(
articleRepository.findByTagNameWithCount(contentTypeId, tagName, queryParams),
Action.done[Seq[(Int, ResponseArticle)]]
)
): ContT[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]] = {
ContT.apply[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]] { next =>
articleRepository.findByTagNameWithCount(contentTypeId, tagName, queryParams)
}
}

def seriesActions(
contentTypeId: ContentTypeId,
seriesName: SeriesName,
queryParams: ArticlesQueryParameter // TODO: `Optional`
): Action[Seq[(Int, ResponseArticle)]] = {
Continue(
articleRepository.findBySeriesNameWithCount(contentTypeId, seriesName),
Action.done[Seq[(Int, ResponseArticle)]]
)
): ContT[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]] = {
ContT.apply[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]] { next =>
articleRepository.findBySeriesNameWithCount(contentTypeId, seriesName)
}
}

def get[A](
data: A = (),
queryParam: ArticlesQueryParameter
)(f: (ContentTypeId, A, ArticlesQueryParameter) => Action[Seq[(Int, ResponseArticle)]]): IO[ResponseArticleWithCount] = {
)(f: (ContentTypeId, A, ArticlesQueryParameter) => ContT[F, Seq[(Int, ResponseArticle)], Seq[(Int, ResponseArticle)]]): IO[ResponseArticleWithCount] = {
for {
c <- contentTypeService.findByName("article").throwIfNone(NotFound(detail = "content-type not found: article"))
articlesWithCount <- executer.transact(f(c.id, data, queryParam))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,44 @@
package net.yoshinorin.qualtet.domains.authors

import cats.data.ContT
import cats.effect.IO
import cats.Monad
import net.yoshinorin.qualtet.message.Fail.InternalServerError
import net.yoshinorin.qualtet.infrastructure.db.Executer
import net.yoshinorin.qualtet.actions.Action.*
import net.yoshinorin.qualtet.actions.{Action, Continue}
import net.yoshinorin.qualtet.syntax.*

class AuthorService[F[_]: Monad](
authorRepository: AuthorRepository[F]
)(using executer: Executer[F, IO]) {

def upsertActions(data: Author): Action[Int] = {
Continue(authorRepository.upsert(data), Action.done[Int])
def upsertActions(data: Author): ContT[F, Int, Int] = {
ContT.apply[F, Int, Int] { next =>
authorRepository.upsert(data)
}
}

def fetchActions: Action[Seq[ResponseAuthor]] = {
Continue(authorRepository.getAll(), Action.done[Seq[ResponseAuthor]])
def fetchActions: ContT[F, Seq[ResponseAuthor], Seq[ResponseAuthor]] = {
ContT.apply[F, Seq[ResponseAuthor], Seq[ResponseAuthor]] { next =>
authorRepository.getAll()
}
}

def findByIdActions(id: AuthorId): Action[Option[ResponseAuthor]] = {
Continue(authorRepository.findById(id), Action.done[Option[ResponseAuthor]])
def findByIdActions(id: AuthorId): ContT[F, Option[ResponseAuthor], Option[ResponseAuthor]] = {
ContT.apply[F, Option[ResponseAuthor], Option[ResponseAuthor]] { next =>
authorRepository.findById(id)
}
}

def findByIdWithPasswordActions(id: AuthorId): Action[Option[Author]] = {
Continue(authorRepository.findByIdWithPassword(id), Action.done[Option[Author]])
def findByIdWithPasswordActions(id: AuthorId): ContT[F, Option[Author], Option[Author]] = {
ContT.apply[F, Option[Author], Option[Author]] { next =>
authorRepository.findByIdWithPassword(id)
}
}

def findByNameActions(name: AuthorName): Action[Option[ResponseAuthor]] = {
Continue(authorRepository.findByName(name), Action.done[Option[ResponseAuthor]])
def findByNameActions(name: AuthorName): ContT[F, Option[ResponseAuthor], Option[ResponseAuthor]] = {
ContT.apply[F, Option[ResponseAuthor], Option[ResponseAuthor]] { next =>
authorRepository.findByName(name)
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,59 @@
package net.yoshinorin.qualtet.domains.contentSerializing

import cats.data.ContT
import cats.Monad
import net.yoshinorin.qualtet.actions.Action.*
import net.yoshinorin.qualtet.actions.{Action, Continue}
import net.yoshinorin.qualtet.domains.contents.ContentId
import net.yoshinorin.qualtet.domains.series.SeriesId

class ContentSerializingService[F[_]: Monad](
contentSerializingRepository: ContentSerializingRepository[F]
) {

def findBySeriesIdActions(id: SeriesId): Action[Seq[ContentSerializing]] = {
Continue(contentSerializingRepository.findBySeriesId(id), Action.done[Seq[ContentSerializing]])
def findBySeriesIdActions(id: SeriesId): ContT[F, Seq[ContentSerializing], Seq[ContentSerializing]] = {
ContT.apply[F, Seq[ContentSerializing], Seq[ContentSerializing]] { next =>
contentSerializingRepository.findBySeriesId(id)
}
}

def upsertActions(data: Option[ContentSerializing]): Action[Int] = {
data match {
case Some(d) => Continue(contentSerializingRepository.upsert(d), Action.done[Int])
case None => Continue(contentSerializingRepository.fakeRequestInt, Action.done[Int])
def upsertActions(data: Option[ContentSerializing]): ContT[F, Int, Int] = {
ContT.apply[F, Int, Int] { next =>
data match {
case Some(d) => contentSerializingRepository.upsert(d)
case None => contentSerializingRepository.fakeRequestInt
}
}
}

def bulkUpsertActions(data: Option[List[ContentSerializing]]): Action[Int] = {
data match {
case Some(d) => Continue(contentSerializingRepository.bulkUpsert(d), Action.done[Int])
case None => Continue(contentSerializingRepository.fakeRequestInt, Action.done[Int])
def bulkUpsertActions(data: Option[List[ContentSerializing]]): ContT[F, Int, Int] = {
ContT.apply[F, Int, Int] { next =>
data match {
case Some(d) => contentSerializingRepository.bulkUpsert(d)
case None => contentSerializingRepository.fakeRequestInt
}
}
}

def deleteBySeriesIdActions(id: SeriesId): Action[Unit] = {
Continue(contentSerializingRepository.deleteBySeriesId(id), Action.done[Unit])
def deleteBySeriesIdActions(id: SeriesId): ContT[F, Unit, Unit] = {
ContT.apply[F, Unit, Unit] { next =>
contentSerializingRepository.deleteBySeriesId(id)
}
}

def deleteByContentIdActions(id: ContentId): Action[Unit] = {
Continue(contentSerializingRepository.deleteByContentId(id), Action.done[Unit])
def deleteByContentIdActions(id: ContentId): ContT[F, Unit, Unit] = {
ContT.apply[F, Unit, Unit] { next =>
contentSerializingRepository.deleteByContentId(id)
}
}

def deleteActions(seriesId: SeriesId, contentIds: Seq[ContentId]): Action[Unit] = {
Continue(contentSerializingRepository.delete(seriesId, contentIds), Action.done[Unit])
def deleteActions(seriesId: SeriesId, contentIds: Seq[ContentId]): ContT[F, Unit, Unit] = {
ContT.apply[F, Unit, Unit] { next =>
contentSerializingRepository.delete(seriesId, contentIds)
}
}

def bulkDeleteActions(data: (SeriesId, Seq[ContentId])): Action[Unit] = {
def bulkDeleteActions(data: (SeriesId, Seq[ContentId])): ContT[F, Unit, Unit] = {
data._2.size match {
case 0 => Continue(contentSerializingRepository.fakeRequestUnit, Action.done[Unit])
case 0 => ContT.apply[F, Unit, Unit] { next => contentSerializingRepository.fakeRequestUnit }
case _ => this.deleteActions(data._1, data._2)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package net.yoshinorin.qualtet.domains.contentTaggings

import cats.data.ContT
import cats.effect.IO
import cats.Monad
import net.yoshinorin.qualtet.actions.Action.*
import net.yoshinorin.qualtet.actions.{Action, Continue}
import net.yoshinorin.qualtet.domains.contents.ContentId
import net.yoshinorin.qualtet.domains.tags.TagId
import net.yoshinorin.qualtet.infrastructure.db.Executer
Expand All @@ -12,32 +11,42 @@ class ContentTaggingService[F[_]: Monad](
contentTaggingRepository: ContentTaggingRepository[F]
)(using executer: Executer[F, IO]) {

def findByTagIdActions(id: TagId): Action[Seq[ContentTagging]] = {
Continue(contentTaggingRepository.findByTagId(id), Action.done[Seq[ContentTagging]])
def findByTagIdActions(id: TagId): ContT[F, Seq[ContentTagging], Seq[ContentTagging]] = {
ContT.apply[F, Seq[ContentTagging], Seq[ContentTagging]] { next =>
contentTaggingRepository.findByTagId(id)
}
}

def bulkUpsertActions(data: Option[List[ContentTagging]]): Action[Int] = {
data match {
case Some(d) => Continue(contentTaggingRepository.bulkUpsert(d), Action.done[Int])
case None => Continue(contentTaggingRepository.fakeRequestInt, Action.done[Int])
def bulkUpsertActions(data: Option[List[ContentTagging]]): ContT[F, Int, Int] = {
ContT.apply[F, Int, Int] { next =>
data match {
case Some(d) => contentTaggingRepository.bulkUpsert(d)
case None => contentTaggingRepository.fakeRequestInt
}
}
}

def deleteByContentIdActions(id: ContentId): Action[Unit] = {
Continue(contentTaggingRepository.deleteByContentId(id), Action.done[Unit])
def deleteByContentIdActions(id: ContentId): ContT[F, Unit, Unit] = {
ContT.apply[F, Unit, Unit] { next =>
contentTaggingRepository.deleteByContentId(id)
}
}

def deleteByTagIdActions(id: TagId): Action[Unit] = {
Continue(contentTaggingRepository.deleteByTagId(id), Action.done[Unit])
def deleteByTagIdActions(id: TagId): ContT[F, Unit, Unit] = {
ContT.apply[F, Unit, Unit] { next =>
contentTaggingRepository.deleteByTagId(id)
}
}

def deleteActions(contentId: ContentId, tagIds: Seq[TagId]): Action[Unit] = {
Continue(contentTaggingRepository.delete(contentId, tagIds), Action.done[Unit])
def deleteActions(contentId: ContentId, tagIds: Seq[TagId]): ContT[F, Unit, Unit] = {
ContT.apply[F, Unit, Unit] { next =>
contentTaggingRepository.delete(contentId, tagIds)
}
}

def bulkDeleteActions(data: (ContentId, Seq[TagId])): Action[Unit] = {
def bulkDeleteActions(data: (ContentId, Seq[TagId])): ContT[F, Unit, Unit] = {
data._2.size match {
case 0 => Continue(contentTaggingRepository.fakeRequestUnit, Action.done[Unit])
case 0 => ContT.apply[F, Unit, Unit] { next => contentTaggingRepository.fakeRequestUnit }
case _ => this.deleteActions(data._1, data._2)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package net.yoshinorin.qualtet.domains.contentTypes

import cats.data.ContT
import cats.effect.IO
import cats.Monad
import net.yoshinorin.qualtet.cache.CacheModule
import net.yoshinorin.qualtet.actions.Action.*
import net.yoshinorin.qualtet.actions.{Action, Continue}
import net.yoshinorin.qualtet.message.Fail.InternalServerError
import net.yoshinorin.qualtet.domains.Cacheable
import net.yoshinorin.qualtet.infrastructure.db.Executer
Expand All @@ -16,12 +15,16 @@ class ContentTypeService[F[_]: Monad](
)(using executer: Executer[F, IO])
extends Cacheable {

def upsertActions(data: ContentType): Action[Int] = {
Continue(contentRepository.upsert(data), Action.done[Int])
def upsertActions(data: ContentType): ContT[F, Int, Int] = {
ContT.apply[F, Int, Int] { next =>
contentRepository.upsert(data)
}
}

def getAllActions: Action[Seq[ContentType]] = {
Continue(contentRepository.getAll(), Action.done[Seq[ContentType]])
def getAllActions: ContT[F, Seq[ContentType], Seq[ContentType]] = {
ContT.apply[F, Seq[ContentType], Seq[ContentType]] { next =>
contentRepository.getAll()
}
}

/**
Expand Down Expand Up @@ -50,8 +53,10 @@ class ContentTypeService[F[_]: Monad](
*/
def findByName(name: String): IO[Option[ContentType]] = {

def actions(name: String): Action[Option[ContentType]] = {
Continue(contentRepository.findByName(name), Action.done[Option[ContentType]])
def actions(name: String): ContT[F, Option[ContentType], Option[ContentType]] = {
ContT.apply[F, Option[ContentType], Option[ContentType]] { next =>
contentRepository.findByName(name)
}
}

def fromDB(name: String): IO[Option[ContentType]] = {
Expand Down
Loading

0 comments on commit 2449a39

Please sign in to comment.