diff --git a/README.md b/README.md index f10de34..106f0cc 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,22 @@ Deletes look as you would expect: => ["DELETE FROM films WHERE kind <> ?" "musical"] ``` +If your database supports it, you can also delete from multiple tables: + +```clojure +(-> (delete [:films :directors]) + (from :films) + (join :directors [:= :films.director_id :directors.id]) + (where [:<> :kind "musical"]) + sql/format) +=> [#sql/regularize + "DELETE films, directors + FROM films + INNER JOIN directors ON films.director_id = directors.id + WHERE kind <> ?" + "musical"] +``` + Queries can be nested: ```clojure diff --git a/src/honeysql/format.cljc b/src/honeysql/format.cljc index 12d201b..6da4730 100644 --- a/src/honeysql/format.cljc +++ b/src/honeysql/format.cljc @@ -205,6 +205,7 @@ :select 50 :insert-into 60 :update 70 + :delete 75 :delete-from 80 :columns 90 :from 110 @@ -588,6 +589,9 @@ (defmethod format-clause :delete-from [[_ table] _] (str "DELETE FROM " (to-sql table))) +(defmethod format-clause :delete [[_ tables] _] + (str "DELETE " (comma-join (map to-sql tables)))) + (defn cte->sql [[cte-name query]] (str (binding [*subquery?* false] diff --git a/src/honeysql/helpers.cljc b/src/honeysql/helpers.cljc index a0a0341..a2fff11 100644 --- a/src/honeysql/helpers.cljc +++ b/src/honeysql/helpers.cljc @@ -271,6 +271,13 @@ ([table] (delete-from nil table)) ([m table] (build-clause :delete-from m table))) +(defmethod build-clause :delete [_ m tables] + (assoc m :delete tables)) + +(defn delete + ([tables] (delete nil tables)) + ([m tables] (build-clause :delete m tables))) + (macros/usetime (defhelper with [m ctes] (assoc m :with ctes))) diff --git a/test/honeysql/format_test.cljc b/test/honeysql/format_test.cljc index 1dce993..38b5a7f 100644 --- a/test/honeysql/format_test.cljc +++ b/test/honeysql/format_test.cljc @@ -200,3 +200,17 @@ :set {:a 1} :where [:= :bar.b 42]} (format :quoting :mysql))))) + +(deftest delete-from-test + (is (= ["DELETE FROM `foo` WHERE `foo`.`id` = ?" 42] + (-> {:delete-from :foo + :where [:= :foo.id 42]} + (format :quoting :mysql))))) + +(deftest delete-test + (is (= ["DELETE `t1`, `t2` FROM `table1` `t1` INNER JOIN `table2` `t2` ON `t1`.`fk` = `t2`.`id` WHERE `t1`.`bar` = ?" 42] + (-> {:delete [:t1 :t2] + :from [[:table1 :t1]] + :join [[:table2 :t2] [:= :t1.fk :t2.id]] + :where [:= :t1.bar 42]} + (format :quoting :mysql)))))