Reputation: 175
All. Here is my code -
def searchGames(location: Location, results: List[TournamentResult], roles:
List[Role], player: String, players: List[String], startPl: Int = 6,
endPl:Int = 30, startR: Int = 1, endR: Int = 1000, sy: Int = 2012, ey:
Int = 2017, sm: Int = 0, em: Int = 12, sd: Int = 0, ed: Int = 32) = {
val filtered2 = if (location != Location.SUMRAK) games.filter(_.location === location.name) else games
val filtered3 = if (startPl > 0) filtered2.filter(_.playersSize >= startPl) else filtered2
val filtered4 = if (endPl > 0) filtered3.filter(_.playersSize <= endPl) else filtered3
val filtered5 = if (startR > 0) filtered4.filter(_.rounds >= startR) else filtered4
val filtered6 = if (endR > 0) filtered5.filter(_.rounds <= endR) else filtered5
val filtered7 = if (results != Nil) {
filtered6.filter(a => a.tournamentResult.inSet(results.map(r => r.descr)))
} else filtered6
val filtered8 = filtered7.filter(a => (a.year === sy && a.month >= sm && a.day >= sd) || (a.year === ey && a.month <= em && a.day <= ed) || (a.year > sy && a.year < ey))
val filtered9 = if (player != null && !player.isEmpty) filtered8.filter(_.players like s"%$player%") else filtered8
val filtered14 = filtered9.map(a => (a.gameId, a.location, a.tournamentResult, a.players, a.playersSize, a.rounds, a.year, a.month, a.day))
filtered14.result
}
It looks nor functional nor pretty. I am relatively newbie to Slick, can you suggest how to refactor it? Slick version is 3.0. I think there should be some "pattern" to extract and simplify the code, but I can't figure out it.
Upvotes: 0
Views: 120
Reputation: 111
The documentation for queries in slick provides a good example: Queries - Slick 3.0.0 documentation - Sorting and Filtering
In short, create a list of Option[criteria] (actually Rep[Boolean]), collect the ones that are valid and && them together.
Something like this:
val filters = (x:GamesTable) => List(
if (startPl > 0) Some(x.playersSize >= startPl) else None,
if (endPl > 0) Some(x.playersSize <= endPl) else None,
if (startR > 0) Some(x.rounds >= startR) else None,
if (endR > 0) Some(x.rounds <= endR) else None
).collect{case Some(criteria) => criteria}.reduceLeft(_ && _)
games.filter( filters )
Makes a nice clean dynamic query.
Upvotes: 2