Reputation: 1679
I am trying to get an underlying querys case classes from a Scala Slick query, and it seems more difficult to me than it should be. Here is my compiler error:
[info] Compiling 18 Scala sources to /home/target/scala-2.11/classes...
[error] /home/src/main/scala/com/core/address/AddressDAO.scala:30: type mismatch;
[error] found : scala.slick.lifted.Query[com.core.address.AddressDAO,com.core.protocol.Address,Seq]
[error] required: Option[com.core.protocol.Address]
[error] q
Here is the method I have written:
def getAddress(otherAddress: String): Future[Option[Address]] = {
future {
val q = for (addr <- addresses if (addr.address == otherAddress)) yield addr
q
}
Here is the Slick Schema:
class AddressDAO(tag: Tag) extends Table[Address](tag, "ADDRESSES") with DbConfig {
def address = column[String]("ADDRESS", O.PrimaryKey)
def hash160 = column[String]("HASH160")
def n_tx = column[Long]("N_TX")
def total_received = column[Double]("TOTAL_RECEIVED")
def total_sent = column[Double]("TOTAL_SENT")
def final_balance = column[Double]("FINAL_BALANCE")
def * = (hash160, address, n_tx, total_received, total_sent, final_balance) <> (Address.tupled, Address.unapply)
}
What I want to do is expressed in the return type of the method getAddress
which is Future[Option[Address]]
. I want the first element that the database is finding. The type that is actually being returned is of type scala.slick.lifted.Query[com.core.address.AddressDAO,com.core.protocol.Address,Seq]
There does not seem to be any execute
method or anything to kick start the query. I suspect this can be done with for-comprehensions
but I cannot figure how to actually do it.
Thanks!
Upvotes: 0
Views: 166
Reputation: 30310
I am certainly no Slick expert, but after a quick perusal of the docs, I am wondering if maybe wrapping something like this in your Future
would work:
addresses.filter(_.address === "givenAddressString").firstOption
Upvotes: 1
Reputation: 12563
You have to actually run your query.
q.firstOption is what you probably want to use:
def getAddress(otherAddress: String): Future[Option[Address]] = {
future {
val q = for (addr <- addresses if (addr.address == otherAddress)) yield addr
q.firstOption
}
PS. Simply filtering addresses for the given value of address is indeed more concise. And of course the performance of this query depends on whether you have an index on that field and the size of your table :)
Upvotes: 1