diff --git a/src/honeysql/core.clj b/src/honeysql/core.clj index d25415c..87994cb 100644 --- a/src/honeysql/core.clj +++ b/src/honeysql/core.clj @@ -37,6 +37,7 @@ :join, :merge-join :left-join, :merge-left-join :right-join, :merge-right-join + :full-join, :merge-full-join :where, :merge-where :group-by, :merge-group-by :having, :merge-having diff --git a/src/honeysql/format.clj b/src/honeysql/format.clj index 004a640..b5ad43f 100644 --- a/src/honeysql/format.clj +++ b/src/honeysql/format.clj @@ -157,7 +157,7 @@ (def clause-order "Determines the order that clauses will be placed within generated SQL" [:select :insert-into :update :delete-from :columns :set :from :join - :left-join :right-join :where :group-by :having :order-by :limit :offset + :left-join :right-join :full-join :where :group-by :having :order-by :limit :offset :values :query-values]) (def known-clauses (set clause-order)) @@ -338,6 +338,10 @@ (space-join (map #(apply format-join :right %) (partition 2 join-groups)))) +(defmethod format-clause :full-join [[_ join-groups] _] + (space-join (map #(apply format-join :full %) + (partition 2 join-groups)))) + (defmethod format-clause :group-by [[_ fields] _] (str "GROUP BY " (comma-join (map to-sql fields)))) diff --git a/src/honeysql/helpers.clj b/src/honeysql/helpers.clj index 0646928..7222bad 100644 --- a/src/honeysql/helpers.clj +++ b/src/honeysql/helpers.clj @@ -93,6 +93,12 @@ (defhelper merge-right-join [m clauses] (update-in m [:right-join] concat clauses)) +(defhelper full-join [m clauses] + (assoc m :full-join clauses)) + +(defhelper merge-full-join [m clauses] + (assoc m :merge-full-join clauses)) + (defmethod build-clause :group-by [_ m fields] (assoc m :group-by (collify fields))) diff --git a/test/honeysql/core_test.clj b/test/honeysql/core_test.clj index 161b52f..59d5d43 100644 --- a/test/honeysql/core_test.clj +++ b/test/honeysql/core_test.clj @@ -15,6 +15,7 @@ (join :draq [:= :f.b :draq.x]) (left-join [:clod :c] [:= :f.a :c.d]) (right-join :bock [:= :bock.z :c.e]) + (full-join :beck [:= :beck.x :c.y]) (where [:or [:and [:= :f.a "bort"] [:not= :b.baz :?param1]] [:< 1 2 3] @@ -34,6 +35,7 @@ :join [:draq [:= :f.b :draq.x]] :left-join [[:clod :c] [:= :f.a :c.d]] :right-join [:bock [:= :bock.z :c.e]] + :full-join [:beck [:= :beck.x :c.y]] :where [:or [:and [:= :f.a "bort"] [:not= :b.baz :?param1]] [:< 1 2 3] @@ -51,7 +53,7 @@ (is (= m1 m3))) (testing "SQL data formats correctly" (is (= (sql/format m1 {:param1 "gabba" :param2 2}) - ["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e WHERE ((f.a = ? AND b.baz <> ?) OR (1 < 2 AND 2 < 3) OR (f.e in (1, ?, 3)) OR f.e BETWEEN 10 AND 20) GROUP BY f.a HAVING 0 < f.e ORDER BY b.baz DESC, c.quux LIMIT 50 OFFSET 10 " + ["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e FULL JOIN beck ON beck.x = c.y WHERE ((f.a = ? AND b.baz <> ?) OR (1 < 2 AND 2 < 3) OR (f.e in (1, ?, 3)) OR f.e BETWEEN 10 AND 20) GROUP BY f.a HAVING 0 < f.e ORDER BY b.baz DESC, c.quux LIMIT 50 OFFSET 10 " "bort" "gabba" 2]))) (testing "SQL data prints and reads correctly" (is (= m1 (read-string (pr-str m1)))))))