package com.example.user.slick.dbios import slick.jdbc.JdbcProfile import com.example.models._ import io.scalaland.chimney.dsl._ import com.example.user.slick.Tables import javax.inject.Singleton // import slick.jdbc.H2Profile.api._ // import scala.concurrent.ExecutionContext @Singleton class SlickLibraryDbio extends Tables { override val profile: JdbcProfile = _root_.slick.jdbc.H2Profile import profile.api._ def findBookById(id: Long): DBIO[Option[BooksRow]] = Query.bookById(id).result.headOption def findBookById2(id: Long): DBIO[Option[BookWithoutId]] = Query.test(id).result.headOption def findBooksWithAuthor: DBIO[Seq[(BooksRow, AuthorsRow)]] = Query.booksWithAuthor.result def insertBook(book: Book): DBIO[BooksRow] = Query.writeBooks += bookToRow(book) def insertBook2(book: NewBook): DBIO[Long] = Query.writeBooks3 += book // def insertAuthor(author: Author): DBIO[AuthorsRow] = Query.writeAuthors += authorToRow(author) def insertAuthor2(author: NewAuthor): DBIO[Long] = Query.writeAuthors2 += author def authorToRow(author: Author) = author.transformInto[AuthorsRow] def bookToRow(book: Book) = book.transformInto[BooksRow] def authorsRowToAuthor(author: AuthorsRow) = author.transformInto[Author] def booksRowToBooks(book: BooksRow) = book.transformInto[Book] def booksRowToBooks2(book: BooksRow) = book.transformInto[BookWithoutId] // As mentioned under #2, we do encapsulate our queries object Query { // Return the book / author with it's auto incremented // id instead of an insert count lazy val writeBooks = Books returning Books .map(_.id) into ((book, id) => book.copy(id)) lazy val writeBooks2 = Books.map(b => (b.title, b.authorId).mapTo[BookWithoutId]) lazy val writeBooks3 = Books .map(b => (b.title, b.authorId).mapTo[NewBook]) .returning(Books.map(_.id)) lazy val writeAuthors = Authors returning Authors .map(_.id) into ((author, id) => author.copy(id)) lazy val writeAuthors2 = Authors.map(a => (a.name).mapTo[NewAuthor]) returning Authors.map(_.id) lazy val test = (givenId: Long) => Books .filter(_.id === givenId) .map(toBooksWithoutID) lazy val bookById = Books.findBy(_.id) lazy val toBooksWithoutID = (table: Books) => (table.title, table.authorId).mapTo[BookWithoutId] lazy val booksWithAuthor = for { b <- Books a <- Authors if b.authorId === a.id } yield (b, a) lazy val authorOfBook = (bookId: Long) => for { (authors, books) <- Authors join Books on (_.id === _.authorId) filter { case (authors, books) => books.id === bookId } } yield (authors, books) lazy val authorOfBook2 = (bookId: Long) => for { authorId <- Books.filter(_.id === bookId).take(1).map(_.authorId) authors <- Authors filter (_.id === authorId) } yield (authors.name) // lazy val authorOfBook3 = (bookId: Long) => // for { // authorId <- bookById(bookId).map(_.map(_.authorId)) // (authors) <- Authors filter (_.id === authorId) // } yield (authors) } case class BookWithoutId(title: String, authorId: Long) // def test() = { // val maybeBook = findBookById(1) // val x = maybeBook.map(_.map(_.title)) // db.run(x) // } }