Slick generic query with distinctOn - scala

I would want to make a generic slick query using distinctOn on table to count distinct elements in the column.
def countDistinct(table: TableQuery[_], column: Rep[_]): DBIO[Int] =
table.distinctOn(_ => column).length.result
This code above doesn't compile because:
No matching Shape found.
[error] Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection,
[error] you use an unsupported type in a Query (e.g. scala List),
[error] or you forgot to import a driver api into scope.
[error] Required level: slick.lifted.FlatShapeLevel
[error] Source type: slick.lifted.Rep[_]
[error] Unpacked type: T
[error] Packed type: Any
[error] table.distinctOn(_ => column).length.result
FlatShapeLevel instead of Rep[_] also doesn't work. I'm using slick 3.

distinctOn doesn't work properly in Slick due to incorrect projection to a particular field/column. The bug was raised 5 years ago, surprisingly still hasn't been resolved.

Related

How do I post a non-string value in a Scala Http request?

From a Scala program, I need to send values with different primitive types to a Node server.
Http("http://middleware-api:3000/createPromoCodeInCms?")
.postForm
.param("lifetime", 5)
.method("POST")
.asString
This does not compile:
[error] /Users/corbac/Desktop/spark-projects/App.scala:192:24: type mismatch;
[error] found : Int(5)
[error] required: String
[error] .param("lifetime", 5)
[error] ^
However it seems like only strings are accepted as body parameters. Is it possible to post non-string types such as a number or a boolean? If yes how do I do it?
I am using Scala 2.11.

ambigious implicits value - twirl form error

With playframework 2.6, I am getting following errors. I have read and found this error only on older versions, that too resolved easily.
[error] /Users/vishalupadhyay/Work/app/views/login_form.scala.html:12:22: ambiguous implicit values:
[error] both method implicitJavaMessages in object PlayMagicForJava of type => play.api.i18n.Messages
[error] and value request of type play.api.mvc.MessagesRequestHeader
[error] match expected type play.api.i18n.MessagesProvider
[error] #helper.inputText(loginForm("password"))
[error] ^
Could not find any answer which can help it. Please see complete code in this link.
Remove the implicit Lang and Messages arguments

Grouping in Slick

I am trying to get a group by result in from the slick table .
Sql : Select * from Jobs GROUP BY category ;
Class
case class JobEntity(id:Option[Long],category:String,properties:String)
My slick function
def getJobsByCategory() :(String,Future[Seq[JobsEntity]]) =
db.run(jobs.groupBy(_.category).map{ case(category,res) =>
(category,res)}.result)
Error:
No matching Shape found.
[ERROR] Slick does not know how to map the given types.
[ERROR] Possible causes: T in Table[T] does not match your * projection,
[ERROR] you use an unsupported type in a Query (e.g. scala List),
[ERROR] or you forgot to import a driver api into scope.
[ERROR] Required level: slick.lifted.FlatShapeLevel
[ERROR] Source type: (slick.lifted.Rep[String], slick.sql.FixedSqlStreamingAction[Seq[org.exadatum.xstream.persistence.models.SparkConfigEntity],org.exadatum.xstream.persistence.models.SparkConfigEntity,slick.dbio.Effect.Read])
[ERROR] Unpacked type: T
[ERROR] Packed type: G
[ERROR]
There is probably some issue with the return type but am not sure what
as the IDE generates error as
Expression of type Future[Seq[Nothing]] doesn't conform to expected type (String,Future[Seq[JobsEntity]])
Sql : Select * from Jobs GROUP BY category ;
This query would only work (even in SQL) if your table only consists of the category field.
With a group by statement every field in the select statement which is not in the group by statement (in your case everything (*) aside from category), needs to be aggregated in some way, since standard SQL only supports flat result tables.
Same stands for Slick. In the map call following the groupBy call, you'll have to define aggregation functions for everything aside your category. Otherwise Slick does not know how to map the result (as stated in the exception)
case class JobEntity(id:Option[Long],category:String,properties:String)
db.run(jobs.groupBy(_.category).map{ case(category,res) =>(category,res)}.result)
Does not work as it is.
Something like:
db.run(jobs.groupBy(_.category).map{ case(category,res) =>(category,res.map(_.1).sum)}.result)
Would work, since it results in a flat shape: Your category and the sum of the IDs with that category. I know this does not make sense for you as is, but hopefully illustrates the problem.
If really just want to group your jobs by the category, I would do it in Scala after fetching them from the database:
val groupedJobs: Future[Seq[String, JobEntity]] = db.run(jobs).map {
case jobs => jobs.groupBy(_.category)
}
If you tell me what you want to achieve exactly, I can propose another solution for you.

spark example wont compile

Trying to run one of apache sparks example codes (https://github.com/apache/spark/blob/master/examples/src/main/scala/org/apache/spark/examples/graphx/AggregateMessagesExample.scala) I get the following compile error
too many arguments for method sendToDst: (msg: (Int, Double))Unit
[error] Error occurred in an application involving default arguments.
[error] triplet.sendToDst(1, triplet.srcAttr)
[error] ^
[error] one error found
But looking at the mehtods it seems to be correct. Not sure what is wrong here.
It looks like the method you are calling expects a single argument (a Tuple2) and you are passing in 2 arguments.
Try
triplet.sendToDst((1, triplet.srcAttr))

Squeryl Many to Many: compositeKey(field1, field2) doesn't exist

I'm learning Scala (2.11) and the Play Framework, and i'm trying to implement a Many to Many relation between Person and Skill with Squeryl (0.9.5-7). Multiple Persons can share Skills, and a Person can have many Skills.
The Squeryl docs tell me to do this:
class PersonToSkill(val personId: Long, val skillId: Long) extends KeyedEntity[CompositeKey2[Long,Long]] {
def id = compositeKey(personId, skillId)
}
But the compiler tells me this:
not found: value compositeKey
[error] def id = compositeKey(personId, skillId)
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
Also, i cannot find compositeKey(fieldId, fieldId) in the docs. I have no idea where it it originates from..
I'm hoping someone can help me solve my problem, or at least explain me where to look for a solution. Thanks!
You can find compositeKey located within org.squery.dsl.QueryDsl
You'll want to make sure you import org.squeryl.PrimitiveTypeMode._ which extends QueryDsl. That should resolve the error you are receiving.