diff --git a/CHANGES.md b/CHANGES.md index 74aa2fa..593e047 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ ## 0.6.0 In development +* Convert seq param values to literal sql param lists (@dball) +* Apply seq to sets when converting to sql (@dball) + ## 0.5.3 * Support exists syntax (@cddr) diff --git a/src/honeysql/format.clj b/src/honeysql/format.clj index 8031484..fcdcf63 100644 --- a/src/honeysql/format.clj +++ b/src/honeysql/format.clj @@ -248,10 +248,24 @@ (into [sql-str] @*params*) [sql-str])))) +(defprotocol Parameterizable + (to-params [value pname])) + +(extend-protocol Parameterizable + clojure.lang.Sequential + (to-params [value pname] + (paren-wrap (comma-join (mapv #(to-params % pname) value)))) + clojure.lang.IPersistentSet + (to-params [value pname] + (to-params (seq value) pname)) + java.lang.Object + (to-params [value pname] + (swap! *params* conj value) + (swap! *param-names* conj pname) + (*parameterizer*))) + (defn add-param [pname pval] - (swap! *param-names* conj pname) - (swap! *params* conj pval) - (*parameterizer*)) + (to-params pval pname)) ;; Anonymous param name -- :_1, :_2, etc. (defn add-anon-param [pval] @@ -320,6 +334,9 @@ (if *subquery?* (paren-wrap sql-str) sql-str))) + clojure.lang.IPersistentSet + (-to-sql [x] + (-to-sql (seq x))) nil (-to-sql [x] "NULL") SqlParam diff --git a/test/honeysql/core_test.clj b/test/honeysql/core_test.clj index b465411..9545bb7 100644 --- a/test/honeysql/core_test.clj +++ b/test/honeysql/core_test.clj @@ -80,3 +80,39 @@ (columns :bar) (values [[(honeysql.format/value {:baz "my-val"})]]) sql/format)))) + +(deftest test-operators + (testing "in" + (doseq [[cname coll] [[:vector []] [:set #{}] [:list '()]]] + (testing (str "with values from a " (name cname)) + (let [values (conj coll 1)] + (is (= ["SELECT * FROM customers WHERE (id in (1))"] + (sql/format {:select [:*] + :from [:customers] + :where [:in :id values]}))) + (is (= ["SELECT * FROM customers WHERE (id in (?))" 1] + (sql/format {:select [:*] + :from [:customers] + :where [:in :id :?ids]} + {:ids values})))))) + (testing "with more than one integer" + (let [values [1 2]] + (is (= ["SELECT * FROM customers WHERE (id in (1, 2))"] + (sql/format {:select [:*] + :from [:customers] + :where [:in :id values]}))) + (is (= ["SELECT * FROM customers WHERE (id in (?, ?))" 1 2] + (sql/format {:select [:*] + :from [:customers] + :where [:in :id :?ids]} + {:ids values}))))) + (testing "with more than one string" + (let [values ["1" "2"]] + (is (= ["SELECT * FROM customers WHERE (id in (?, ?))" "1" "2"] + (sql/format {:select [:*] + :from [:customers] + :where [:in :id values]}) + (sql/format {:select [:*] + :from [:customers] + :where [:in :id :?ids]} + {:ids values})))))))