-
Notifications
You must be signed in to change notification settings - Fork 51
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
Tool for capturing query parameters as if they were string interpolations #213
Comments
Okay this is pretty great! And best of all it's optional so if someone's using a database which uses the PostgreSQL wire protocol but not the parameter syntax (i.e., I'm presuming this functions something like this: julia> @query "insert into foo values ($(email_and_id...))"
Query("insert into foo values (\$1, \$2)", ("[email protected]", 3)) Would this make sense as a string macro? |
Very similar (though the interpolation syntax is constructed lazily — this allows multiple such strings to be pasted together dynamically, as in the "Buliding up a query from fragments" section. (It would also allow non-PostgreSQL parameter syntax to be supported for other connection types.) julia> email_and_id = ("[email protected]", 3)
("[email protected]", 3)
julia> @query "insert into foo values ($(email_and_id...))"
insert into foo values ($1,$2)
$1 = "[email protected]"
$2 = 3
julia> dump(@query "insert into foo values ($(email_and_id...))")
JHubDbUtils.SafeQuery
args: Array{Any}((5,))
1: QueryFragment
fragment: String "insert into foo values ("
2: String "[email protected]"
3: QueryFragment
fragment: String ","
4: Int64 3
5: QueryFragment
fragment: String ")"
Yes I tried this, but I found it has a big downside: interpolations aren't syntax-highlighted. In practice I felt this quite outweighed the benefits of a string macro for visually parsing complex queries. (The benefits of a string macro being a separate namespace and no need for parentheses in larger expressions with trailing parts.) |
By the way, I found it helpful to add a By the way, regarding naming I'm not married to using In the end, |
If it was a string macro you could choose to use the The laziness actually presents a nice argument for this being a generic separate package, since the same syntax could be used for many different database systems. |
Yes that's a good point. I've taken a stab at refactoring this a bit and put the code into a new package SqlStrings.jl. I'll probably register a first version of this shortly: https://github.com/JuliaComputing/SQLStrings.jl
In SqlStrings, I've made it
At the moment it requires a small amount of glue code to integrate with I'm not 100% sure of the best way forward for integration. We could make SqlStrings a dependency of LibPQ and make A longer term goal might be to make the publicly exported |
I've recently written a macro tool for conveniently capturing query parameters as part of a private project. I've found it handy, so I wondered whether people would be interested in having this as part of LibPQ. Or if not, whether you have suggestions for a better home for it.
The general idea is that we should be able to build up queries by pasting together fragments of SQL and interpolated parameters like one might do with strings or
Cmd
backtick interpolation. But with all interpolations turned into SQL parameters for safety and consistency in converting those to SQL types.To just paste the readme in here:
The readme
The main thing provided here is the
@query
macro to allow queries to beconstructed by normal-looking string interpolation but without danger of SQL
injection attacks.
Note that
@query
does not parse or understand the SQL source text as thiswould be a lot of work. Instead, it keeps any literal SQL text you write as-is
and only treats the Julia-level string interpolations specially.
Use
runquery
to execute queries generated by@query
.Simple usage
Creating a table and inserting some values
Thence:
Howto: Inserting values from a Julia array into a row
In some circumstances it can be useful to use splatting syntax to interpolate a
Julia collection into a comma-separated list of values. Generally simple scalar
parameters should be preferred for simplicity, but splatting can be useful on
occasion:
Howto: Using the
in
operator with a Julia collectionThere's two ways to do this. First, using
in
and splatting syntaxSecond, using the SQL
any
operator and simply passing a single SQL array parameter:Howto: Building up a query from fragments
The text was updated successfully, but these errors were encountered: