Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version app #3

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version=2.3.2
style = defaultWithAlign
danglingParentheses = true
indentOperator = spray
Expand Down
54 changes: 32 additions & 22 deletions app/controllers/BookController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,52 @@ import models.repositories.BookRepository
import play.api.Logging
import play.api.i18n.I18nSupport
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}
import scala.util.{Failure, Success}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal

@Singleton
class BookController @Inject()(cc: ControllerComponents, bookRepository: BookRepository)
extends AbstractController(cc)
class BookController @Inject() (cc: ControllerComponents, bookRepository: BookRepository)(
implicit ec: ExecutionContext
) extends AbstractController(cc)
with I18nSupport
with Logging {

def index(): Action[AnyContent] = Action { implicit request =>
bookRepository.findAll() match {
case Success(books) => {
val bookDTOs = books.map(BookDTO(_))
Ok(views.html.book.index(bookDTOs))
def index(): Action[AnyContent] = Action.async { implicit request =>
bookRepository
.findAll()
.map { books =>
{
val bookDTOs = books.map(BookDTO(_))
Ok(views.html.book.index(bookDTOs))
}
}
case Failure(ex) => {
logger.error(s"index occurred error", ex)
InternalServerError(ex.getMessage)
.recover {
case NonFatal(e) => {
logger.error(s"index occurred error", e)
InternalServerError(e.getMessage)
}
}
}
}

def search(): Action[AnyContent] = Action { implicit request =>
def search(): Action[AnyContent] = Action.async { implicit request =>
BookSearch.form.bindFromRequest.fold(
_ => Redirect("/books"),
_ => Future.successful(Redirect("/books")),
bookName => {
bookRepository
.searchName(bookName.name) match {
case Success(books) => {
val bookDTOs = books.map(BookDTO(_))
Ok(views.html.book.index(bookDTOs))
.searchName(bookName.name)
.map { books =>
{
val bookDTOs = books.map(BookDTO(_))
Ok(views.html.book.index(bookDTOs))
}
}
case Failure(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
.recover {
case NonFatal(e) => {
logger.error(s"index occurred error", e)
InternalServerError(e.getMessage)
}
}
}
}
)
}
Expand Down
25 changes: 16 additions & 9 deletions app/controllers/DeleteBookController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,28 @@ import models.repositories.BookRepository
import play.api.Logging
import play.api.i18n.I18nSupport
import play.api.mvc.{AbstractController, ControllerComponents, _}
import scala.util.{Failure, Success}

import scala.concurrent.ExecutionContext
import scala.util.control.NonFatal

@Singleton
class DeleteBookController @Inject()(cc: ControllerComponents, bookRepository: BookRepository)
extends AbstractController(cc)
class DeleteBookController @Inject() (cc: ControllerComponents, bookRepository: BookRepository)(
implicit ec: ExecutionContext
) extends AbstractController(cc)
with I18nSupport
with Logging {

def delete(bookId: String): Action[AnyContent] = Action { implicit request =>
bookRepository.delete(bookId) match {
case Success(_) => Redirect("/books")
case Failure(ex) => {
logger.error(s"occurred error", ex)
def delete(bookId: String): Action[AnyContent] = Action.async { implicit request =>
bookRepository
.delete(bookId)
.map { _ =>
Redirect("/books")
}
}
.recover {
case NonFatal(e) => {
logger.error(s"occurred error", e)
Redirect("/books")
}
}
}
}
42 changes: 24 additions & 18 deletions app/controllers/RegisterBookController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,43 @@ import models.repositories.BookRepository
import play.api.Logging
import play.api.i18n.I18nSupport
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}
import util.EitherOps._

import scala.util.{Failure, Success}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal

@Singleton
class RegisterBookController @Inject()(cc: ControllerComponents, bookRepository: BookRepository)
extends AbstractController(cc)
class RegisterBookController @Inject() (cc: ControllerComponents, bookRepository: BookRepository)(
implicit ec: ExecutionContext
) extends AbstractController(cc)
with I18nSupport
with Logging {

def index(): Action[AnyContent] = Action { implicit request =>
Ok(views.html.book.register(BookRegister.form))
}

def register() = Action { implicit request =>
def register() = Action.async { implicit request =>
BookRegister.form.bindFromRequest.fold(
error => BadRequest(views.html.book.register(error)),
error => Future.successful(BadRequest(views.html.book.register(error))),
book => {
(for {
books <- bookRepository.findByName(book.name)
_ <- Book.canRegister(books).toTry
result <- bookRepository.add(Book(book.name, book.author, book.publishedDate, book.description))
} yield result) match {
case Success(_) => Redirect("/books")

case Failure(ex: DuplicateBookNameException) =>
BadRequest(views.html.book.register(BookRegister.form.withGlobalError(ex.getMessage)))
case Failure(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
val result: Future[Unit] = for {
books <- bookRepository.findByName(book.name)
_ <- Book.canRegister(books).toFuture()
_ <- bookRepository.add(Book(book.name, book.author, book.publishedDate, book.description))
} yield ()
result
.map { _ =>
Redirect("/books")
}
.recover {
case e: DuplicateBookNameException =>
BadRequest(views.html.book.register(BookRegister.form.withGlobalError(e.getMessage)))
case NonFatal(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
}
}
}
}
)
}
Expand Down
53 changes: 32 additions & 21 deletions app/controllers/UpdateBookController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,51 @@ import models.repositories.BookRepository
import play.api.Logging
import play.api.i18n.I18nSupport
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}
import scala.util.{Failure, Success}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal

@Singleton
class UpdateBookController @Inject()(cc: ControllerComponents, bookRepository: BookRepository)
extends AbstractController(cc)
class UpdateBookController @Inject() (cc: ControllerComponents, bookRepository: BookRepository)(
implicit ec: ExecutionContext
) extends AbstractController(cc)
with I18nSupport
with Logging {

def index(id: String): Action[AnyContent] = Action { implicit request =>
bookRepository.findById(id) match {
case Success(Some(book)) => {
val editForm = BookUpdate.form.fill(BookUpdate(book))
Ok(views.html.book.update(editForm))
def index(id: String): Action[AnyContent] = Action.async { implicit request =>
bookRepository
.findById(id)
.map {
case Some(book) => {
val editForm = BookUpdate.form.fill(BookUpdate(book))
Ok(views.html.book.update(editForm))
}
case None => NotFound("idが見つかりませんでした。")
}
case Success(None) => NotFound("idが見つかりませんでした。")
case Failure(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
.recover {
case NonFatal(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
}
}
}
}

def update(): Action[AnyContent] = Action { implicit request =>
def update(): Action[AnyContent] = Action.async { implicit request =>
BookUpdate.form.bindFromRequest.fold(
error => BadRequest(views.html.book.update(error)),
error => Future.successful(BadRequest(views.html.book.update(error))),
updatingBook => {
val book = updatingBook.toBookModel
bookRepository.update(book) match {
case Success(_) => Redirect("/books")
case Failure(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
bookRepository
.update(book)
.map { _ =>
Redirect("/books")
}
.recover {
case NonFatal(ex) => {
logger.error(s"occurred error", ex)
InternalServerError(ex.getMessage)
}
}
}
}
)
}
Expand Down
12 changes: 7 additions & 5 deletions app/controllers/dtos/BookDTO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package controllers.dtos
import java.time.LocalDate
import models.Book

case class BookDTO(id: String,
name: String,
author: Option[String],
publishedDate: Option[LocalDate],
description: Option[String])
case class BookDTO(
id: String,
name: String,
author: Option[String],
publishedDate: Option[LocalDate],
description: Option[String]
)

object BookDTO {

Expand Down
12 changes: 7 additions & 5 deletions app/controllers/forms/BookRegister.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import java.time.LocalDate
import play.api.data.Form
import play.api.data.Forms.{localDate, mapping, nonEmptyText, optional, text}

case class BookRegister(name: String,
author: Option[String],
publishedDate: Option[LocalDate],
description: Option[String])
case class BookRegister(
name: String,
author: Option[String],
publishedDate: Option[LocalDate],
description: Option[String]
)

object BookRegister {

Expand All @@ -17,7 +19,7 @@ object BookRegister {
"name" -> nonEmptyText,
"author" -> optional(text),
"publishedDate" -> optional(localDate("yyyy-MM-dd")),
"description" -> optional(text),
"description" -> optional(text)
)(BookRegister.apply)(BookRegister.unapply)
)

Expand Down
14 changes: 8 additions & 6 deletions app/controllers/forms/BookUpdate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import models.Book
import play.api.data.Form
import play.api.data.Forms.{localDate, mapping, nonEmptyText, optional, text}

case class BookUpdate(id: String,
name: String,
author: Option[String],
publishedDate: Option[LocalDate],
description: Option[String]) {
case class BookUpdate(
id: String,
name: String,
author: Option[String],
publishedDate: Option[LocalDate],
description: Option[String]
) {

def toBookModel: Book = {
Book(this.id, this.name, this.author, this.publishedDate, this.description)
Expand All @@ -35,7 +37,7 @@ object BookUpdate {
"name" -> nonEmptyText,
"author" -> optional(text),
"publishedDate" -> optional(localDate("yyyy-MM-dd")),
"description" -> optional(text),
"description" -> optional(text)
)(BookUpdate.apply)(BookUpdate.unapply)
)

Expand Down
20 changes: 11 additions & 9 deletions app/infra/rdb/BookRepositoryOnJDBC.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package infra.rdb

import infra.rdb.records.BookRecord
import javax.inject.{Inject, Singleton}
import models._
import models.repositories.BookRepository
import scalikejdbc.{DB, _}

import scala.util.Try
import scala.concurrent.Future

class BookRepositoryOnJDBC extends BookRepository {
@Singleton
class BookRepositoryOnJDBC @Inject() (implicit ec: ExecutionContextOnJDBC) extends BookRepository {

val b: scalikejdbc.QuerySQLSyntaxProvider[scalikejdbc.SQLSyntaxSupport[BookRecord], BookRecord] =
BookRecord.syntax("b")

def findAll(): Try[Seq[Book]] = Try {
def findAll(): Future[Seq[Book]] = Future {
DB readOnly { implicit session =>
sql"select * from books as b LIMIT 200 "
.map(BookRecord(b.resultName))
Expand All @@ -22,7 +24,7 @@ class BookRepositoryOnJDBC extends BookRepository {
}
}

def add(book: Book): Try[Unit] = Try {
def add(book: Book): Future[Unit] = Future {
val record = BookRecord(book)
DB localTx { implicit session =>
sql"""insert into books (id, name, author, published_date, description)
Expand All @@ -39,13 +41,13 @@ class BookRepositoryOnJDBC extends BookRepository {
}
}

def findByName(name: String): Try[Seq[Book]] = Try {
def findByName(name: String): Future[Seq[Book]] = Future {
DB readOnly { implicit session =>
sql"select b.* from books as b where name = $name".map(BookRecord(b.resultName)).list().apply().map(toModel)
}
}

def update(book: Book): Try[Unit] = Try {
def update(book: Book): Future[Unit] = Future {
val record = BookRecord(book)
DB localTx { implicit session =>
sql"""update books
Expand All @@ -61,19 +63,19 @@ class BookRepositoryOnJDBC extends BookRepository {
}
}

def findById(bookId: String): Try[Option[Book]] = Try {
def findById(bookId: String): Future[Option[Book]] = Future {
DB readOnly { implicit session =>
sql"select b.* from books as b where id = $bookId".map(BookRecord(b.resultName)).headOption().apply().map(toModel)
}
}

def delete(bookId: String): Try[Unit] = Try {
def delete(bookId: String): Future[Unit] = Future {
DB localTx { implicit session =>
sql"delete from books where id = $bookId".update().apply()
}
}

def searchName(name: String): Try[Seq[Book]] = Try {
def searchName(name: String): Future[Seq[Book]] = Future {
DB readOnly { implicit session =>
val searchName = s"%$name%"
sql"select b.* from books as b where name like $searchName"
Expand Down
Loading