Skip to content

Instantly share code, notes, and snippets.

@pjb3
Created February 22, 2012 14:48
Show Gist options
  • Select an option

  • Save pjb3/1885401 to your computer and use it in GitHub Desktop.

Select an option

Save pjb3/1885401 to your computer and use it in GitHub Desktop.
I'm running into an issue which appears to a leaky abstraction in the way macros are defined, specifically the with-query-results macro in clojure.java.jdbc.
(require '[clojure.java.jdbc :as sql])
(def mysql-db {:subprotocol "mysql"
:subname "//127.0.0.1:3306/mydb"
:user "root"}
(defn select-rows [query]
(sql/with-query-results rs query
(into [] rs)))
(defn find-each [fn query]
(sql/with-connection mysql-db
(let [batch-size 1000]
(loop [id 0]
(println "\n\n\n\n\n *********** Batch for id " id " ************ \n\n\n\n\n")
(let [paginated-query (str query " WHERE id > ? ORDER by id ASC LIMIT ?")
rows (select-rows [paginated-query id batch-size])]
(if rows
(do
(doseq [row rows] (fn row))
(recur (+ batch-size (:id (last rows)))))))))))
(find-each prn "SELECT * FROM people")
; This works fine, but it seems odd that I have to "escape" out of the macro with the select-rows function
; There also doesn't appear to be a non-macro function in clojure.java.jdbc that does what select-rows does :(
(require '[clojure.java.jdbc :as sql])
(def mysql-db {:subprotocol "mysql"
:subname "//127.0.0.1:3306/mydb"
:user "root"})
(defn find-each [fn query]
(sql/with-connection mysql-db
(let [batch-size 1000]
(loop [id 0]
(println "\n\n\n\n\n *********** Batch for id " id " ************ \n\n\n\n\n")
(let [paginated-query (str query " WHERE id > ? ORDER by id ASC LIMIT ?")
sql-params [paginated-query id batch-size]]
(sql/with-query-results rows sql-params
(if rows
(do
(doseq [row rows] (fn row))
(recur (+ batch-size (:id (last rows))))))))))))
(find-each prn "SELECT * FROM people")
; When I run this, I get this exception after it prints the first batch of results
;
; Exception in thread "main" java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long
;
; I think this is because recur is returning to the with-query-results call because with-query-results is a macro,
; and somewhere inside the definition of that macro is must use loop?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment