Skip to content

Instantly share code, notes, and snippets.

@teaforthecat
Created March 12, 2018 21:06
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 teaforthecat/915575aa08188ebb03bf446cc98e31d7 to your computer and use it in GitHub Desktop.
Save teaforthecat/915575aa08188ebb03bf446cc98e31d7 to your computer and use it in GitHub Desktop.
sql macro; finding a short path to named parameters
(ns sql)
(defn sub-qmark [i form]
(if (keyword? form)
['? form] ;;todo need a stateful transducer
form))
(defn params [body]
(map-indexed sub-qmark body))
(defn q-vec? [form]
(and (vector? form) (= '? (first form))))
(defn pop-qmark [form]
(if (q-vec? form)
'?
form))
(defn pop-indexes [body]
(->> body
(filter q-vec?)
(map second)))
(defn pop-qmarks [body]
(map pop-qmark body))
(defmacro sql [& body]
(let [param-indexes (params body)
just-sql (clojure.string/join " " (pop-qmarks param-indexes))
vars (pop-indexes param-indexes)]
`(fn [args#]
;; todo validate all vars are in args
(into [~just-sql] (map #(get args# %) '~vars)))))
(comment
(-> '(select * from :wat :who :wat)
(params)
(pop-indexes)
)
(def select-stuff (sql select * from :wat :who))
(select-stuff
{:wat "a"
:who "b"})
;;=> ["select * from ? ?" "a" "b"]
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment