I have a table:
trait Schema {
val db: Database
class CoffeeTable(tag: Tag) extends Table[Coffee](tag, "coffees") {
def from = column[String]("from")
def kind = column[String]("kind")
def sold = column[Boolean]("sold")
}
protected val coffees = TableQuery[Coffee]
}
I want to update records that are for sale. Here is my method:
def markAsSold(soldCoffees: Seq[Coffee]): Future[Int] = {
val cmd = coffees
.filter { coffee =>
soldCoffees
.map(sc => coffee.from === sc.from && coffee.kind === sc.kind)
.reduceLeftOption(_ || _)
.getOrElse(LiteralColumn(false))
}
.map(coffee => coffee.sold)
.update(true)
db.db.stream(cmd)
}
While it works for a small collection soldCoffee, it fails badly when entering hundreds of elements:
java.lang.StackOverflowError
at slick.ast.TypeUtil$$colon$at$.unapply(Type.scala:325)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:311)
at slick.jdbc.H2Profile$QueryBuilder.expr(H2Profile.scala:99)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8(JdbcStatementBuilderComponent.scala:381)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8$adapted(JdbcStatementBuilderComponent.scala:381)
at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:381)
at slick.jdbc.H2Profile$QueryBuilder.expr(H2Profile.scala:99)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8(JdbcStatementBuilderComponent.scala:381)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8$adapted(JdbcStatementBuilderComponent.scala:381)
at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
So the question is, is there any other way to do such an update?
What comes to my mind is to use easier SQL-code or the introduction of some artificial column that contains the concatenated values of columns fromand typeand filtering against him.
source
share