Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9cecfdc
Add filter clause:
scimetfoo Jun 22, 2020
0d707a6
Rename the filter-clause fn to format-filter-clause
scimetfoo Jun 24, 2020
f249afd
Add an example for filter to the usage section of the readme
scimetfoo Nov 12, 2020
110d6fc
Reformat the filter formatter: rename the format function, remove a
scimetfoo Nov 13, 2020
82a085d
- Reformat the filter example in the readme
scimetfoo Nov 13, 2020
2a305c0
Fix formatting
scimetfoo Nov 13, 2020
f8956c9
Merge branch 'master' into filter-clause
scimetfoo Nov 13, 2020
fe3fa37
List filter in index
scimetfoo Nov 16, 2020
20abd52
Format WITHIN GROUP expressions
scimetfoo Nov 13, 2020
c36095c
WITHIN GROUP expression example
scimetfoo Nov 13, 2020
48adaa5
Add the output to the example
scimetfoo Nov 13, 2020
fae071e
Allow aliasing WIHTIN GROUP expressions
scimetfoo Nov 16, 2020
ecdf197
Merge branch 'master' into filter-clause
scimetfoo Feb 26, 2021
cca1ba5
Bump honeysql to 1.0.461
scimetfoo Feb 26, 2021
fa4d9b6
Exclude filter from clojure.core
scimetfoo Feb 26, 2021
cfbe3dc
Fix formatting of a filter test
scimetfoo Feb 26, 2021
5fe4f4d
Format the clause using threading macros
scimetfoo Mar 9, 2021
d8b1f75
Format the clause using threading macros
scimetfoo Mar 9, 2021
709c7fb
Merge branch 'master' into filter-clause
kitallis Mar 11, 2021
b6b1628
Merge branch 'master' into filter-clause
scimetfoo Mar 11, 2021
348acc8
Merge branch 'filter-clause' of https://github.com/nilenso/honeysql-p…
scimetfoo Mar 11, 2021
3a32fd4
Merge branch 'filter-clause' into within-group
scimetfoo Mar 11, 2021
a4f5d8c
Merge branch 'master' into within-group
kitallis Mar 11, 2021
2236b07
Match filter + within group + over priorities
kitallis Mar 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,22 @@ The query creation and usage is exactly the same as honeysql.
- [pattern matching](#pattern-matching)
- [except](#except)
- [filter](#filter)
- [within group](#within-group)
- [SQL functions](#sql-functions)
- [License](#license)

## Usage

### REPL

```clojure
(require '[honeysql.core :as sql]
'[honeysql.helpers :refer :all :as sqlh]
'[honeysql-postgres.helpers :as psqlh])
```

### distinct-on

`select` can be written with a `distinct on` clause
``` clojure
(-> (select :column-1 :column-2 :column-3)
Expand All @@ -47,6 +50,7 @@ The query creation and usage is exactly the same as honeysql.
```

### upsert

`upsert` can be written either way. You can make use of `do-update-set!` over `do-update-set`, if you want to modify the some column values in case of conflicts.
```clojure
(-> (insert-into :distributors)
Expand All @@ -69,6 +73,7 @@ The query creation and usage is exactly the same as honeysql.
```

### insert into with alias

`insert-into-as` can be used to write insert statements with table name aliased.
```clojure
(-> (psqlh/insert-into-as :distributors :d)
Expand All @@ -84,6 +89,7 @@ The query creation and usage is exactly the same as honeysql.
```

### over

You can make use of `over` to write window functions where it takes in vectors with aggregator functions and window functions along with optional alias like `(over [aggregator-function window-function alias])`, the can be coupled with the `window` clause to write window-function functions with alias that is later defines the window-function, like `(-> (over [aggregator-function :w]) (window :w window-function))`.
```clojure
(-> (select :id)
Expand All @@ -108,6 +114,7 @@ You can make use of `over` to write window functions where it takes in vectors w
```

### create table

`create-table` and `with-columns` can be used to create tables along with the SQL functions, where `create-table` takes a table name as argument and `with-columns` takes a vector of vectors as argument, where the vectors describe the column properties as `[:column-name :datatype :constraints ... ]`.
```clojure
(-> (psqlh/create-table :films)
Expand All @@ -122,13 +129,15 @@ You can make use of `over` to write window functions where it takes in vectors w
```

### drop table

`drop-table` is used to drop tables
```clojure
(sql/format (psqlh/drop-table :cities :towns :vilages))
=> ["DROP TABLE cities, towns, vilages"]
```

### alter table

use `alter-table` along with `add-column` & `drop-column` to modify table level details
```clojure
(-> (psqlh/alter-table :employees)
Expand All @@ -143,6 +152,7 @@ use `alter-table` along with `add-column` & `drop-column` to modify table level
```

### create-extension

`create-extension` can be used to create extensions with a given keyword.
```clojure
(-> (psqlh/create-extension :uuid-ossp :if-not-exists? true)
Expand All @@ -161,6 +171,7 @@ use `alter-table` along with `add-column` & `drop-column` to modify table level
```

### pattern matching

The `ilike` and `not-ilike` operators can be used to query data using a pattern matching technique.
- like
```clojure
Expand All @@ -180,6 +191,7 @@ The `ilike` and `not-ilike` operators can be used to query data using a pattern
```

### except

```clojure
(sql/format
{:except
Expand All @@ -200,7 +212,19 @@ The `ilike` and `not-ilike` operators can be used to query data using a pattern
=> ["SELECT count(*) , count(*) FILTER (WHERE i < ?) AS foo, count(*) FILTER (WHERE i BETWEEN ? AND ?) AS bar FROM generate_series(1,10) AS s(i)" 5 3 10]
```

### within group

``` clojure
(-> (select (sql/call :count :*))
(within-group [(sql/call :percentile_disc (hsql-types/array [0.25 0.5 0.75])) (order-by :s.i) :alias])
(from (sql/raw "generate_series(1,10) AS s(i)"))
(sql/format))
=> ["SELECT count(*) , percentile_disc(ARRAY[?, ?, ?]) WITHIN GROUP (ORDER BY s.i) AS alias FROM generate_series(1,10) AS s(i)"
0.25 0.50 0.75]
```

### SQL functions

The following are the SQL functions added in `honeysql-postgres`
- not
```clojure
Expand Down Expand Up @@ -257,7 +281,7 @@ The following are the SQL functions added in `honeysql-postgres`
=> ["CHECK(a = b)"]

(sql/format (sql/call :check [:= :a :b] [:= :c :d]))
["CHECK(a = b AND c = d)"]
=> ["CHECK(a = b AND c = d)"]
```

## License
Expand Down
16 changes: 15 additions & 1 deletion src/honeysql_postgres/format.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
:add-column 30
:drop-column 40
:create-view 40
:filter 54
:filter 55
:within-group 55
:over 55
:insert-into-as 60
:partition-by 165
Expand Down Expand Up @@ -236,6 +237,19 @@
(binding [sqlf/*subquery?* false]
(string/join " EXCEPT ALL " (map sqlf/to-sql maps))))

(defmethod format-clause :within-group [[_ expr] m]
(let [format (fn [expr]
(let [[expression clause alias] (map sqlf/to-sql expr)]
(->> alias
(str " AS ")
(when alias)
(str expression " WITHIN GROUP " clause))))]
(-> m
:select
seq
(when ", ")
(str (sqlf/comma-join (map format expr))))))

(override-default-clause-priority)

(defmethod format-modifiers :distinct-on [[_ & fields]]
Expand Down
3 changes: 3 additions & 0 deletions src/honeysql_postgres/helpers.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
(defhelper insert-into-as [m fields]
(assoc m :insert-into-as (sqlh/collify fields)))

(defhelper within-group [m args]
(assoc m :within-group (sqlh/collify args)))

(defhelper create-extension [m extension-name]
(assoc m :create-extension (sqlh/collify extension-name)))

Expand Down
68 changes: 56 additions & 12 deletions test/honeysql_postgres/postgres_test.cljc
Original file line number Diff line number Diff line change
@@ -1,18 +1,52 @@
(ns honeysql-postgres.postgres-test
(:refer-clojure :exclude [update partition-by filter])
(:require [honeysql-postgres.helpers :as sqlph :refer [upsert on-conflict do-nothing on-conflict-constraint
returning do-update-set do-update-set!
alter-table rename-column drop-column
add-column partition-by insert-into-as
create-table rename-table drop-table
window create-view over with-columns
create-extension drop-extension filter]]
[honeysql.helpers :as sqlh :refer [insert-into values where select columns
from order-by update sset query-values
modifiers]]
[honeysql.core :as sql]
(:require [clojure.string :as str]
[clojure.test :as test :refer [deftest is testing]]
[clojure.string :as str]))
[honeysql-postgres.helpers
:as
sqlph
:refer
[add-column
alter-table
create-extension
create-table
create-view
do-nothing
do-update-set
do-update-set!
drop-column
drop-extension
drop-table
filter
insert-into-as
on-conflict
on-conflict-constraint
over
partition-by
rename-column
rename-table
returning
upsert
window
with-columns
within-group]]
[honeysql.core :as sql]
[honeysql.helpers
:as
sqlh
:refer
[columns
from
insert-into
modifiers
order-by
query-values
select
sset
update
values
where]]
[honeysql.types :as hsql-types]))

(deftest upsert-test
(testing "upsert sql generation for postgresql"
Expand Down Expand Up @@ -272,6 +306,16 @@
(modifiers :distinct-on :a :b)
(sql/format :quoting :ansi))))))

(deftest within-group-test
(is (= ["rank() WITHIN GROUP (ORDER BY i)"]
(sql/format (within-group [(sql/call :rank) (order-by :i)]))))

(is (= ["SELECT count(*) , percentile_disc(ARRAY[?, ?, ?]) WITHIN GROUP (ORDER BY s.i) AS alias FROM generate_series(1,10) AS s(i)"
0.25 0.50 0.75]
(-> (select (sql/call :count :*))
(within-group [(sql/call :percentile_disc (hsql-types/array [0.25 0.5 0.75])) (order-by :s.i) :alias])
(from (sql/raw "generate_series(1,10) AS s(i)"))
(sql/format)))))
(deftest create-extension-test
(testing "create extension"
(is (= ["CREATE EXTENSION \"uuid-ossp\""]
Expand Down