You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.9 KiB
103 lines
2.9 KiB
package wow.doge.http4sdemo.services
|
|
|
|
import monix.bio.IO
|
|
import monix.bio.Task
|
|
import slick.jdbc.JdbcBackend
|
|
import slick.jdbc.JdbcProfile
|
|
import wow.doge.http4sdemo.dto.Book
|
|
import wow.doge.http4sdemo.dto.BookUpdate
|
|
import wow.doge.http4sdemo.dto.NewBook
|
|
import wow.doge.http4sdemo.implicits._
|
|
import wow.doge.http4sdemo.slickcodegen.Tables
|
|
|
|
class LibraryService(
|
|
profile: JdbcProfile,
|
|
dbio: LibraryDbio,
|
|
db: JdbcBackend.DatabaseDef
|
|
) {
|
|
import profile.api._
|
|
|
|
def getBooks = db.streamO(dbio.getBooks)
|
|
|
|
def getBookById(id: Int) = db.runL(dbio.getBook(id))
|
|
|
|
// .map(b =>
|
|
// (b.title, b.authorId, b.createdAt).mapTo[BookUpdateEntity]
|
|
// )
|
|
|
|
def updateBook(id: Int, updateData: BookUpdate) =
|
|
for {
|
|
action <- IO.deferAction { implicit s =>
|
|
Task(for {
|
|
mbRow <- dbio.selectBook(id).result.headOption
|
|
updatedRow <- mbRow match {
|
|
case Some(value) =>
|
|
println(s"Original value -> $value")
|
|
println(s"Value to be updated with -> $updateData")
|
|
DBIO.successful(updateData.update(value))
|
|
case None =>
|
|
DBIO.failed(new Exception(s"Book with id $id does not exist"))
|
|
}
|
|
updateAction = dbio.selectBook(id).update(updatedRow)
|
|
_ = println(s"SQL = ${updateAction.statements}")
|
|
_ <- updateAction
|
|
} yield ())
|
|
}
|
|
_ <- db.runL(action.transactionally.asTry).flatMap(Task.fromTry)
|
|
} yield ()
|
|
|
|
def deleteBook(id: Int) = db.runL(dbio.deleteBook(id))
|
|
|
|
def insertBook(newBook: NewBook) =
|
|
Task.deferFutureAction { implicit s =>
|
|
val action = for {
|
|
id <- dbio.insertBookAndGetId(newBook)
|
|
book <- dbio.getBook(id)
|
|
} yield book.get
|
|
db.run(action.transactionally)
|
|
}
|
|
|
|
def booksForAuthor(authorId: Int) =
|
|
db.streamO(dbio.booksForAuthor(authorId)).map(Book.fromBooksRow)
|
|
|
|
}
|
|
|
|
class LibraryDbio(val profile: JdbcProfile) {
|
|
import profile.api._
|
|
|
|
def getBooks: StreamingDBIO[Seq[Book], Book] = Query.getBooksInner.result
|
|
|
|
def insertBookAndGetId(newBook: NewBook): DBIO[Int] =
|
|
Query.insertBookGetId += newBook
|
|
|
|
def insertBookAndGetBook(newBook: NewBook): DBIO[Book] =
|
|
Query.insertBookGetBook += newBook
|
|
|
|
def selectBook(id: Int) = Tables.Books.filter(_.id === id)
|
|
|
|
def deleteBook(id: Int) = selectBook(id).delete
|
|
|
|
def getBook(id: Int) = selectBook(id)
|
|
.map(Book.fromBooksTableFn)
|
|
.result
|
|
.headOption
|
|
|
|
def booksForAuthor(authorId: Int) = Query.booksForAuthorInner(authorId).result
|
|
|
|
private object Query {
|
|
|
|
val getBooksInner = Book.fromBooksTable
|
|
|
|
val insertBookGetId =
|
|
NewBook.fromBooksTable.returning(Tables.Books.map(_.id))
|
|
|
|
val insertBookGetBook = NewBook.fromBooksTable.returning(getBooksInner)
|
|
|
|
def booksForAuthorInner(authorId: Int) = for {
|
|
b <- Tables.Books
|
|
a <- selectAuthor(authorId) if b.authorId === a.id
|
|
} yield b
|
|
|
|
def selectAuthor(authorId: Int) = Tables.Authors.filter(_.id === authorId)
|
|
}
|
|
}
|