Closed chshersh closed 5 years ago
Yes, I've been wanting to do something along these lines. However, you can't implement your idea exactly as written, rather it would need to be something closer to:
[sql|
SELECT col1, col2
FROM my_table
WHERE user_id = ?
AND (?after IS NULL OR id > ?after)
|] (Only userId)
This is because we don't have programmatic access to the variable name without wrapping a larger expression in template haskell. However, we don't need that in this case.
sqlite-simple
has very nice support for named arguments. Queries looks like this:
executeNamed_ [sql|
INSERT INTO file_upload_history
(file_name, uploader_id, timestamp, data_type, remarks)
VALUES
(:file, :uploader, :time, :type, :remarks)
|] [ ":file" := duFileName
, ":uploader" := adminId
, ":time" := curTime
, ":type" := duDataType
, ":remarks" := duRemarks
]
You can't mix named and non-named parameters in single query. But that's even better.
I'd like to implement a named-parameter quasiquoter along these lines. I don't think I can make it work for either of the syntaxes above, because a QuasiQuoter can only emit a single Expression, and cannot modify the parameters tuple. @lpsmith do you have some clever way to support named params and backwards compatibility with the sql
QQ, or do you agree with the below?
If the QQ emits a pair, call sites can look like:
uncurry (query conn) [sqlNamed|SELECT * FROM table WHERE column = ?foo|]
We can still mix positional and named, if people really want that, like:
uncurry (query conn)
([sqlNamed|SELECT * FROM table WHERE column = ?foo AND c2 = ? |] (Only bar))
-- desugars to
uncurry (query conn) ((\(Only a) ->
("SELECT * FROM table WHERE column = ? AND c2 = ?", (foo, a))) (Only bar))
Is this what folks want? Any better ideas for making usage more like the current library?
Looks like the library is maintained under the following fork:
I can't transfer the issue there, so closing it here.
Just in case somebody is looking for named parameters in postgresql-simple
and found this issue. We've created the postgresql-simple-named
library which adds support for named parameters on top of postgresql-simple
:
I'm trying to support classical usage of
after :: Maybe Id
parameter. Instead of having two queries forNothing
andJust
I want to write only single query like this:Unfortunately, this doesn't work with quasiquoter because if I use
?
twice I need to supply more than argument.Workaround: just duplicate query parameter. But it would be better to have named parameters inside quasi-quoter, like this: