-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support #$ interpolation for dynamic sql such as table names, order clause, etc #20
Comments
I did a simple Helper to solve it package com.lucidchart.open.relate.interp
object Helper {
implicit def fromInterpolatedQuery(value: InterpolatedQuery): InterpolatedQueryParameter = new InterpolatedQueryParameter(value)
class InterpolatedQuery(value: InterpolatedQuery) extends Parameter {
def appendPlaceholders(stringBuilder: StringBuilder): Unit = stringBuilder ++= value.parsedQuery
def parameterize(statement: PreparedStatement, i: Int): Int = value.parameterize(statement, i)
}
} And you can use InterpolatedQuery as Parameter for other InterpolatedQuery import com.lucidchart.open.relate.interp.Helper._
val accountId = 2
val whereQuery = sql"where id = ${accountId}"
val query = sql"select * from users ${whereQuery}" I hope it help you |
@rfranco, that is actually already implemented ;) @rbanikaz, see https://github.com/lucidsoftware/relate/wiki/Query-Interpolation#query-composition. // interpolate (my preference)
val sql1 = sql"SELECT * FROM users"
val sql2 = sql"$sql1 LIMIT 5"
// concatenate
val sql3 = sql"SELECT * FROM users"
val sql4 = sql" LIMIT 5"
val sql5 = sql3 + sql4 (FYI, if for some reason you aren't constructing your queries with literal strings, an arbitrary string can be converted to a query by calling I like this approach to interpolation, as it encodes the semantics of the data -- text data, or SQL query -- in the type. It avoids the "String as universal data type" smell, and it makes accidental SQL injection more difficult. Let me know if you find this reasonable. |
@pauldraper Unfortunately, it doesnt work for dynamic table names or order by clauses.
Will return a InterpolatedQuery which looks like this:
which is not right. Thats why anorm/slick support #$ interpolation. Another example is table names, suppose I have time series tables which are formatted like follows: tablename_YYYYMMDD I will need to construct the table name as a string and pass it literally to the query but not as a parameter. Please let me know if I missed something and above 2 use cases are supported? |
For dynamic (rather than literal) strings, there is sql"""
select name, sum(foo) as foo, sum(bar) as bar
from table where account_id = $account_id
group by name
order by ${orderCol.toSql} ${orderDir.toSql}""" Similarly, sql"select * from tablename_${format.format(date).toSql}" If these are done frequently, you can define helpers. val tablename = s"tablename_${format.format(date)}".toSql
sql"select * from $tablename" This latter form results in less verbose queries, and the interpolation behavior is based off of type, just as it is for everything else: But I agree that in some cases, depending on the particular use, #$ may be simpler. If you like the #$, make a pull request. |
Cool thanks! I didn't know about the toSql, that's helpful at least it covers the use case. I do think the #$ is nice, I didn't spend much time going through your codebase, but I will go ahead and submit the PR, it will be great if you take a look I will be happy to respond to comments... Cheers! |
Love relate and the SqlResult parsing is much cleaner than anorm. One thing missing is #$ interpolation which is supported by anorm and slick. Its helpful for use cases like dynamic table names, order clauses, etc:
I have a quick and dirty commit which unblocks me for now, would remove this for official version if/when supported:
xadrnd@40e1766
Thanks!
The text was updated successfully, but these errors were encountered: