This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-04
Channels
- # announcements (10)
- # babashka (16)
- # beginners (3)
- # calva (14)
- # clj-kondo (119)
- # clojure (15)
- # clojure-nl (2)
- # clojure-uk (2)
- # clojurescript (15)
- # conjure (1)
- # datascript (1)
- # duct (1)
- # fulcro (2)
- # lsp (6)
- # malli (1)
- # off-topic (9)
- # polylith (3)
- # re-frame (9)
- # reagent (12)
- # reitit (6)
- # shadow-cljs (27)
- # sql (14)
- # vim (5)
Hi, is there a way to parametrize a request with keywords rather than ?
? Because right now I am building a rather complicated request, and it would be much simpler if I could do WHERE foo = :foo
+ {:foo "bar"}
as parameter
HugSQL provides this functionality: https://hugsql.org
@archibald.pontier_clo I have a helper fn for that if you want it
;; ------------------------------------------------------------------------
(defn expand-named-parameters
"Given a sql query like \"SELECT name FROM TABLE WHERE id = :id\"
and a map of the form {:id ..., :other ...}, this will return
a sqlvec representation of that query with the named parameters in
the correct position"
[sql-str params]
(let [^Pattern replace-pattern #":([a-zA-Z]|\-|[0-9])+"
params-in-order (map first (re-seq replace-pattern sql-str))
with-placeholders (string/replace sql-str replace-pattern "?")
extract-param-value (fn [param]
(->> (keyword (.substring param 1 (count param)))
(get params)))]
(vec (cons with-placeholders
(map extract-param-value params-in-order)))))
;; ------------------------------------------------------------------------
(defmacro expand-named-parameters-compile-time
"Does the same work as [[expand-named-parameters]], but requires a
string literal and a map literal in exchange for doing the parsing
work at compile time."
[sql-str params]
(let [param-syms (map (fn [[name value]]
{:name name
:value value
:symbol (gensym)})
(seq params))
param-map (into {} (map (juxt :name :symbol) param-syms))
let-clause `(let ~(vec (mapcat (juxt :symbol :value) param-syms))
~(expand-named-parameters sql-str param-map))]
let-clause))
If i were to package that into a library I would probably make the macro version be the less verbose one
@emccue thank you, I'll check that out after I fix the massive security issue in my sql requests 😅
@archibald.pontier_clo lmk if you would want it as a library - I could stand to learn how to do that finally