Skip to content

Commit 2d1e6d1

Browse files
authored
Merge pull request #34 from varnion/master
Support for EXCEPT and EXCEPT ALL clauses
2 parents f49efa4 + b14a4f1 commit 2d1e6d1

File tree

4 files changed

+76
-17
lines changed

4 files changed

+76
-17
lines changed

README.md

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,26 @@ Currently honeysql-postgres supports the following postgres specific clauses:
2323
- rename column
2424
- insert-into-as
2525
- pattern matching (ILIKE and NOT ILIKE)
26+
- except (and except-all)
2627

2728
## Index
2829

29-
- [Usage](https://github.com/nilenso/honeysql-postgres#usage)
30-
- [Leiningen](https://github.com/nilenso/honeysql-postgres#leiningen)
31-
- [Maven](https://github.com/nilenso/honeysql-postgres#maven)
32-
- [repl](https://github.com/nilenso/honeysql-postgres#repl)
33-
- [Breaking Change](https://github.com/nilenso/honeysql-postgres#breaking-change)
34-
- [upsert](https://github.com/nilenso/honeysql-postgres#upsert)
35-
- [insert into with alias](https://github.com/nilenso/honeysql-postgres#insert-into-with-alias)
36-
- [over](https://github.com/nilenso/honeysql-postgres#over)
37-
- [create view](https://github.com/nilenso/honeysql-postgres#create-view)
38-
- [create table](https://github.com/nilenso/honeysql-postgres#create-table)
39-
- [drop table](https://github.com/nilenso/honeysql-postgres#drop-table)
40-
- [alter table](https://github.com/nilenso/honeysql-postgres#alter-table)
41-
- [pattern matching](https://github.com/nilenso/honeysql-postgres#pattern-matching)
42-
- [SQL functions](https://github.com/nilenso/honeysql-postgres#sql-functions)
43-
- [License](https://github.com/nilenso/honeysql-postgres#license)
30+
- [Usage](#usage)
31+
- [Leiningen](#leiningen)
32+
- [Maven](#maven)
33+
- [repl](#repl)
34+
- [Breaking Change](#breaking-change)
35+
- [upsert](#upsert)
36+
- [insert into with alias](#insert-into-with-alias)
37+
- [over](#over)
38+
- [create view](#create-view)
39+
- [create table](#create-table)
40+
- [drop table](#drop-table)
41+
- [alter table](#alter-table)
42+
- [pattern matching](#pattern-matching)
43+
- [except](#except)
44+
- [SQL functions](#sql-functions)
45+
- [License](#license)
4446

4547
## Usage
4648

@@ -181,6 +183,17 @@ The `ilike` and `not-ilike` operators can be used to query data using a pattern
181183
sql/format)
182184
=> ["SELECT * FROM products WHERE name NOT ILIKE ?" "%name%"]
183185
```
186+
### except
187+
188+
```clj
189+
190+
(sql/format
191+
{:except
192+
[{:select [:ip]}
193+
{:select [:ip] :from [:ip_location]}]})
194+
=> ["SELECT ip EXCEPT SELECT ip FROM ip_location"]
195+
```
196+
`except-all` works the same way as `except`.
184197

185198
### SQL functions
186199
The following are the SQL functions added in `honeysql-postgres`

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(defproject nilenso/honeysql-postgres "0.2.5"
1+
(defproject nilenso/honeysql-postgres "0.2.6"
22
:description "PostgreSQL extension for honeysql"
33
:url "https://github.com/nilenso/honeysql-postgres"
44
:license {:name "Eclipse Public License"

src/honeysql_postgres/format.cljc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
(ns ^{:doc "Extension of the honeysql format functions specifically for postgreSQL"}
22
honeysql-postgres.format
33
(:require [honeysql.format :as sqlf :refer [fn-handler format-clause]] ;; multi-methods
4-
[honeysql-postgres.util :as util]))
4+
[honeysql-postgres.util :as util]
5+
[clojure.string :as string]))
56

67
(def ^:private custom-additions
78
{:create-table 10
@@ -26,6 +27,8 @@
2627
"Determines the order that clauses will be placed within generated SQL"
2728
(merge {:with 30
2829
:with-recursive 40
30+
:except 45
31+
:except-all 45
2932
:select 50
3033
:insert-into 60
3134
:update 70
@@ -208,4 +211,12 @@
208211
(defmethod format-clause :insert-into-as [[_ [table-name table-alias]] _]
209212
(str "INSERT INTO " (sqlf/to-sql table-name) " AS " (sqlf/to-sql table-alias)))
210213

214+
(defmethod format-clause :except [[_ maps] _]
215+
(binding [sqlf/*subquery?* false]
216+
(string/join " EXCEPT " (map sqlf/to-sql maps))))
217+
218+
(defmethod format-clause :except-all [[_ maps] _]
219+
(binding [sqlf/*subquery?* false]
220+
(string/join " EXCEPT ALL " (map sqlf/to-sql maps))))
221+
211222
(override-default-clause-priority)

test/honeysql_postgres/postgres_test.cljc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,38 @@
219219
(from :products)
220220
(where [:not-ilike :name "%name%"])
221221
sql/format)))))
222+
223+
(deftest values-except-select
224+
(testing "select which values are not not present in a table"
225+
(is (= ["VALUES (?), (?), (?) EXCEPT SELECT id FROM images" 4 5 6]
226+
(sql/format
227+
{:except
228+
[{:values [[4] [5] [6]]}
229+
{:select [:id] :from [:images]}]})))))
230+
231+
232+
(deftest select-except-select
233+
(testing "select which rows are not present in another table"
234+
(is (= ["SELECT ip EXCEPT SELECT ip FROM ip_location"]
235+
(sql/format
236+
{:except
237+
[{:select [:ip]}
238+
{:select [:ip] :from [:ip_location]}]})))))
239+
240+
241+
(deftest values-except-all-select
242+
(testing "select which values are not not present in a table"
243+
(is (= ["VALUES (?), (?), (?) EXCEPT ALL SELECT id FROM images" 4 5 6]
244+
(sql/format
245+
{:except-all
246+
[{:values [[4] [5] [6]]}
247+
{:select [:id] :from [:images]}]})))))
248+
249+
250+
(deftest select-except-all-select
251+
(testing "select which rows are not present in another table"
252+
(is (= ["SELECT ip EXCEPT ALL SELECT ip FROM ip_location"]
253+
(sql/format
254+
{:except-all
255+
[{:select [:ip]}
256+
{:select [:ip] :from [:ip_location]}]})))))

0 commit comments

Comments
 (0)