Skip to content

Instantly share code, notes, and snippets.

@trinityXmontoya
Created April 23, 2016 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trinityXmontoya/0ca546af48ff315ebacef9306a230435 to your computer and use it in GitHub Desktop.
Save trinityXmontoya/0ca546af48ff315ebacef9306a230435 to your computer and use it in GitHub Desktop.
dynamic sql generation in clojure
(require '[cheshire.core :as json]
'[clojure.string :as string]
'[yesql.core :as yesql])
(defmulti ->sql "converts a given val to Postgres-compatible SQL" class)
(defmethod to->sql :default ([f] f))
(defmethod to->sql String (str "'" f "'"))
(defmethod to->sql org.joda.time.DateTime ([f] ((str "CAST('" f "' AS TIMESTAMP)")))
(defmethod to->sql clojure.lang.PersistentVector ([f] (str "ARRAY[" (string/join ", " f) "]")))
(defmethod to->sql clojure.lang.PersistentArrayMap ([f] (str "'" (json/encode f) "'")))
(defn build-create-query
[tablename params]
"ex: users, {:first_name 'Nancy' :last_name 'Drew'}
-> 'INSERT INTO users (first_name, last_name)
VALUES ('Nancy', 'Drew')'"
(let [attrs (string/join ", " (map (comp name first) params))
values (string/join ", " (map (comp ->sql second) params))]
(str "INSERT INTO " tablename " (" attrs ") "
"VALUES (" values ") "
"RETURNING *;")))
(defn build-update-query
[tablename params id]
"ex: users, {:first_name 'George' :last_name 'Fayne' :id 7}, :id
-> 'UPDATE users
SET first_name = 'George',
last_name = 'Fayne'
WHERE id = 7
RETURNING *;"
(let [id-val (get params id)
params (dissoc params id)
val-pairs (string/join
", "
(map
#(str (name (first %)) " = " (->sql (second %)))
params))]
(str "UPDATE " tablename
" SET " val-pairs
" WHERE " (name id) " = " (->sql id-val)
" RETURNING *;")))
(defn db-create!
[tablename params]
(let [query (build-create-query tablename params)]
(first (yesql.generate/query-handler @pg-conn query {}))))
(defn db-update!
[tablename params id]
(let [query (build-update-query tablename params id)]
(first (yesql.generate/query-handler @pg-conn query {}))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment