diff --git a/CHANGELOG.md b/CHANGELOG.md index 351a4c2..1cff242 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changes * 2.6.next in progress + * Address [#567](https://github.com/seancorfield/honeysql/issues/567) by adding support for `ASSERT` clause. * Address [#566](https://github.com/seancorfield/honeysql/issues/566) by adding `IS [NOT] DISTINCT FROM` operators. * Add examples of `:alias` with `:group-by` (syntax is slightly different to existing examples for `:order-by`). diff --git a/doc/xtdb.md b/doc/xtdb.md index 3f11274..709ebee 100644 --- a/doc/xtdb.md +++ b/doc/xtdb.md @@ -207,3 +207,14 @@ user=> (sql/format {:patch-into :foo :records [{:_id 1 :status "active"}]}) ["PATCH INTO foo RECORDS ?" {:_id 1, :status "active"}] ``` + +## `assert` + +XTDB supports an `ASSERT` operation that will throw an exception if the +asserted predicate is not true: + +```clojure +user=> (sql/format '{assert (not-exists {select 1 from users where (= email "james @example.com")})} + :inline true) +["ASSERT NOT EXISTS (SELECT 1 FROM users WHERE email = 'james @example.com')"] +``` diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 642fdf7..174d379 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -59,7 +59,7 @@ ;; then SQL clauses in priority order: :setting :raw :nest :with :with-recursive :intersect :union :union-all :except :except-all - :table + :table :assert ; #567 XTDB :select :select-distinct :select-distinct-on :select-top :select-distinct-top :distinct :expr :exclude :rename :into :bulk-collect-into @@ -1654,6 +1654,9 @@ :except #'format-on-set-op :except-all #'format-on-set-op :table #'format-selector + :assert (fn [k xs] + (let [[sql & params] (format-expr xs)] + (into [(str (sql-kw k) " " sql)] params))) :select #'format-selects :select-distinct #'format-selects :select-distinct-on #'format-selects-on diff --git a/test/honey/sql/xtdb_test.cljc b/test/honey/sql/xtdb_test.cljc index d9a8c35..fb759db 100644 --- a/test/honey/sql/xtdb_test.cljc +++ b/test/honey/sql/xtdb_test.cljc @@ -1,4 +1,4 @@ -;; copyright (c) 2020-2024 sean corfield, all rights reserved +;; copyright (c) 2020-2025 sean corfield, all rights reserved (ns honey.sql.xtdb-test (:require [clojure.test :refer [deftest is testing]] @@ -129,3 +129,11 @@ (sql/format '{select (((get-in (. a b) c (lift 1) d)))}))) (is (= ["SELECT (OBJECT (_id: 1, b: 'thing').b).c[?].d" 1] (sql/format '{select (((get-in (. (object {_id 1 b "thing"}) b) c (lift 1) d)))})))) + +(deftest assert-statement + (is (= ["ASSERT NOT EXISTS (SELECT 1 FROM users WHERE email = 'james @example.com')"] + (sql/format '{assert (not-exists {select 1 from users where (= email "james @example.com")})} + :inline true))) + (is (= ["ASSERT TRUE"] + (sql/format '{assert true} + :inline true))))