Created
May 3, 2012 23:42
-
-
Save RickMoynihan/2590472 to your computer and use it in GitHub Desktop.
Symbol abuse, to get escape free SQL strings in Clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (defn &&* [symbol-seq] | |
| "escape free strings" | |
| (apply str (interpose " " symbol-seq))) | |
| (&&* '(SELECT "users.*" FROM "users" WHERE ("users.username" = ?) ORDER BY "users.created" ASC)) | |
| ;; => "SELECT users.* FROM users WHERE (\"users.username\" = ?) ORDER BY users.created ASC" | |
| (defmacro && [& args] | |
| "Use the macro if you can't live with having to quote a list when using &&*" | |
| (&&* args)) | |
| (&& SELECT "users.*" FROM "users" WHERE ("users.username" = ?) ORDER BY "users.created" ASC) | |
| ;; => "SELECT users.* FROM users WHERE (\"users.username\" = ?) ORDER BY users.created ASC" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; now quotes strings... unfortunately this means you can't use strings for reader characters.... keywords maybe? :-) | |
| (defn &&* [symbol-seq] | |
| (apply str | |
| (interpose " " | |
| (map (fn [s] | |
| (if (string? s) | |
| (str \" s \") | |
| s)) | |
| symbol-seq)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is all good - I've learned a great deal about Clojure's Java innards and how the Reader works. I've also learned that I should have implemented a Dispatch Macro instead of a top level Reader Macro (although it's pretty much the same thing), which frees up more ASCII codes, so I've now done that. You get to choose the delimiter which follows the '#?'.
Output from my REPL:
user=> (println #?'abc def')
abc def
nil
user=> (println #?|abc"de "" e f|)
abc"de "" e f
nil
user=> (println #?:abc \n "d" e:)
abc \n "d" e
nil