I basically would like to replace the following code with something more "slicky":
final case class User(firstName: String, lastName: String)
def dbAction(lastNameParts: Seq[String]): SqlStreamingAction[Vector[User], User, Effect]
implicit val getUserResult =
GetResult((r: PositionedResult) => {
val resultSet: ResultSet = r.rs
User(
resultSet.getString(1),
resultSet.getString(2)
)
})
val pattern = orgIds.mkString("|")
sql"""SELECT u.first_name, u.last_name
FROM users u
WHERE last_name ~* $pattern""".as[User]
So the resulting SQL would be:
SELECT u.first_name, u.last_name
FROM users u
WHERE last_name ~* '%bar|baz%';
So this dbAction will return an action which I can use to Query for all users having some name parts included in a list.
So
dbAction(Seq("bar", "baz"))
will return an action querying for all last names containing the strings "bar" or "baz" (case insensitive). I found a way to query for a single pattern
val query = for {
user <- users if user.lastName like "%bar%"
} yield (user.firstName, user.lastName)
and I found a way to query for list inclusion
u <- users if u.lastName.inSet(Seq("bar", "baz"))
but could not find a way to combine that
EDIT: Another way to possibly solve that would be via a regular expression. Is there a way to achieve something like the following SQL statement:
select * from users where last_name ~ '[\w]*bar[\w]*|[\w]*baz[\w]*';
Since this is somehow a different question how to use a regex I created a different question for this: Slick: Is there a way to create a WHERE clause with a regex?
Looking at the code you've posted, I didn't think you needed to literaly combine an
IN
with aLIKE
. I read the question as wanting to do a regular expression query. Although Slick doesn't support the~*
operator out of the box, you can add it yourself. That would give you a way to execute the query using the lifted embedded style of Slick query.To do that, you can use the
SimpleExpression
builder. There's not much documentation on it, but the jumping off point would be the Scalar Database Functions page of the reference manual.What we want to do is write a method along these lines:
To get
regexLike
we can enrich (enhance, "pimp") a string column to have theregexLike
method:The
implicit class
part is allow the compiler to construct theRegexLikeOps
class anytime it has aRep[String]
that calls a method thatRep[String]
doesn't already have (i.e., whenregexLike
is asked for).Our
regexLike
method takes anotherRep[String]
argument as the pattern, and then usesSimpleExpression
builder to safely construct the SQL we want to use.Putting it all together we can write:
The SQL generated (in my test with H2) is:
The full code is: https://github.com/d6y/so46199828