Skip to content

Instantly share code, notes, and snippets.

@leandrob13
Last active July 14, 2022 21:09
Show Gist options
  • Save leandrob13/a50f61db5a81d36dd5d35820fd9ca67e to your computer and use it in GitHub Desktop.
Save leandrob13/a50f61db5a81d36dd5d35820fd9ca67e to your computer and use it in GitHub Desktop.
Trait that adds two functions to the slick Query type. I am using typelevel.cats as the functional library. Works for play-slick 3.1
trait SlickQueryOps {
databaseConfig: HasDatabaseConfig[ JdbcProfile ] =>
import cats.Apply
import cats.std.list._
import driver.api._
type BooleanOp = ( Rep[ Boolean ], Rep[ Boolean ] ) => Rep[ Boolean ]
implicit class OptionFilter[ X, Y ]( query: Query[ X, Y, Seq ] ) {
/*
Filters collection from an optional value. If it is None, returns the unfiltered collection.
It can be applied consecutively to the query.
Used for finding a collection of elements
*/
def filteredBy[ T ]( op: Option[ T ] )
( f: ( X, T ) => Rep[ Boolean ]) ): Query[ X, Y, Seq ] = {
op map { o => query.filter( f( _, o ) ) } getOrElse query
}
/*
Applies a list of functions that return predicates to the query filter method.
If the result of the functions is None, returns an empty collection.
Used for finding the first match.
*/
def foundBy[ T ]( ops: List[ ( X ) => Option[ Rep[ Boolean ] ] ] )
( f: BooleanOp ): Query[ X, Y, Seq ] =
query.filter { q =>
val res = Apply[ List ].ap( ops )( List( q ) ).collect {
case Some( y ) => y
} reduceLeftOption f
res.getOrElse( false: Rep[ Boolean ] )
} take 1
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment