Ehud Kaldor
Ehud Kaldor

Reputation: 793

in Slick 3.0, how to I get from a query to a case class?

I am trying to use Slick for database in a Scala application, and running into some issues (or my misunderstandings) of how to query (find) and convert the result to a case class.

I am not mapping the case class, but the actual values, with the intent of creating the case class on the fly. so, my table is:

object Tables {

  class Names(tag: Tag) extends Table[Name](tag, "NAMES") {
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
        def first = column[String]("first")
        def middle = column[String]("last")
        def last = column[String]("last")

        def * = (id.?, first, middle.?, last) <> ((Name.apply _).tupled, Name.unapply)
  }

  object NamesQueries {

    lazy val query = TableQuery[Names]

    val findById = Compiled { k: Rep[Long] =>
      query.filter(_.id === k)
    }
  }
}

and here is the query:

object NamesDAO {

  def insertName(name: Name) {
    NamesQueries.query += name.copy(id = None)
  }

  def findName(nameId: Long) = {
    val q = NamesQueries.findById(nameId)                         // AppliedCompiledFunction[Long, Query[Tables.Names, Tables.Names.TableElementType, Seq],Seq[Tables.Names.TableElementType]]
    val resultSeq = Database.forConfig("schoolme").run(q.result)  // Future[Seq[Tables.Names.TableElementType]]
    val result = resultSeq.map { r =>                             // val result: Future[(Option[Long], String, Option[String], String) => Name]
      val rr = r.map{ name =>                                     // val rr: Seq[(Option[Long], String, Option[String], String) => Name]
        Name.apply _
      }
      rr.head
    }
    result
  }
}

however, the findName method seems to return Future((Option[Long], String, Option[String], String) => Name) instead of a Future(Name). What am i doing wrong? Is it just a matter of just using asInstanceOf[Name]?

EDIT: expanded findName to smaller chunks with comments for each one, as sap1ens suggested.

Upvotes: 3

Views: 2115

Answers (1)

Ehud Kaldor
Ehud Kaldor

Reputation: 793

well, i'll be damned. following sap1ens comment above, I broke findName to multiple steps (and edited the question). but after that, i went back and gave my val an explicit type, and that worked. see here:

  def findName(nameId: Long) = {
    val q = NamesQueries.findById(nameId)                        
    val resultSeq: Future[Seq[Name]] = Database.forConfig("schoolme").run(q.result)  
    val result = resultSeq.map { r =>
      val rr = r.map{ name =>
        name
      }
      rr.head
    }
    result
  }

so, type inference was the (/my) culprit this time. remember, remember.

Upvotes: 1

Related Questions