Skip to content

Commit 185fea5

Browse files
authored
Merge branch 'master' into lateral-case
2 parents 6d282d4 + b25aed7 commit 185fea5

File tree

4 files changed

+90
-5
lines changed

4 files changed

+90
-5
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ The following are the SQL functions added in `honeysql-postgres`
314314

315315
(sql/format (sql/call :primary-key :arg1 :arg2))
316316
=> ["PRIMARY KEY(arg1, arg2)"]
317+
318+
(-> (psqlh/create-table :table)
319+
(psqlh/with-columns [[:column_1 :integer]
320+
[:column_2 :text]])
321+
(psqlh/constraints [[:primary-key [:column_1]]])
322+
sql/format)
323+
=> ["CREATE TABLE table (column_1 integer, column_2 text, PRIMARY KEY(column_1))"]
317324
```
318325
- `unique`
319326
```clojure
@@ -322,6 +329,13 @@ The following are the SQL functions added in `honeysql-postgres`
322329

323330
(sql/format (sql/call :unique :arg1 :arg2))
324331
=> ["UNIQUE(arg1, arg2)"]
332+
333+
(-> (psqlh/create-table :table)
334+
(psqlh/with-columns [[:column_1 :integer]
335+
[:column_2 :text]])
336+
(psqlh/constraints [[:unique [:column_2]]])
337+
sql/format)
338+
=> ["CREATE TABLE table (column_1 integer, column_2 text, UNIQUE(column_2))"]
325339
```
326340
- `foreign-key`
327341
```clojure

src/honeysql_postgres/format.cljc

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
:within-group 55
1818
:over 55
1919
:insert-into-as 60
20+
:with-columns 70
21+
:constraints 75
2022
:join-lateral 153
2123
:left-join-lateral 154
2224
:partition-by 165
@@ -163,11 +165,39 @@
163165
util/get-first
164166
sqlf/to-sql)))
165167

166-
(defmethod format-clause :with-columns [[_ columns] _]
167-
(sqlf/paren-wrap (->> columns
168-
util/get-first
169-
(map #(sqlf/space-join (map sqlf/to-sql %)))
170-
sqlf/comma-join)))
168+
(def ^:private constraints-format-map
169+
{:primary-key "PRIMARY KEY"
170+
:unique "UNIQUE"})
171+
172+
(defn- format-constraint-clause
173+
[[constraint-type constraint-args]]
174+
(when (contains? constraints-format-map constraint-type)
175+
(str (get constraints-format-map constraint-type)
176+
(sqlf/paren-wrap (->> constraint-args
177+
(map sqlf/to-sql)
178+
sqlf/comma-join)))))
179+
180+
(defn- format-columns-clause
181+
[columns]
182+
(->> columns
183+
util/get-first
184+
(map #(sqlf/space-join (map sqlf/to-sql %)))
185+
sqlf/comma-join))
186+
187+
(defmethod format-clause :with-columns [[_ columns] complete-sql-map]
188+
(when-not (seq (:constraints complete-sql-map))
189+
(sqlf/paren-wrap (format-columns-clause columns))))
190+
191+
(defmethod format-clause :constraints [[_ [constraints]] complete-sql-map]
192+
(let [columns (:with-columns complete-sql-map)
193+
constraints (filter (fn [[constraint-type _]]
194+
(contains? constraints-format-map constraint-type)) constraints)]
195+
(sqlf/paren-wrap
196+
(str (when (seq columns)
197+
(format-columns-clause columns))
198+
(when (seq constraints)
199+
(str ", "
200+
(sqlf/comma-join (map format-constraint-clause constraints))))))))
171201

172202
(defmethod format-clause :drop-table [[_ params] _]
173203
(let [[if-exists & others] params

src/honeysql_postgres/helpers.cljc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
(defhelper with-columns [m args]
4343
(assoc m :with-columns args))
4444

45+
(defhelper constraints [m args]
46+
(assoc m :constraints args))
47+
4548
(defhelper drop-table [m tablenames]
4649
(assoc m :drop-table (sqlh/collify tablenames)))
4750

test/honeysql_postgres/postgres_test.cljc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
alter-table
1111
case-when
1212
case-when-else
13+
constraints
1314
create-extension
1415
create-table
1516
create-view
@@ -197,6 +198,43 @@
197198
[(sql/call :check [:> :discounted_price 0] [:> :price :discounted_price])]])
198199
sql/format)))))
199200

201+
(deftest constraints-test
202+
(testing "creating table with unique constraint on multiple columns"
203+
(is (= ["CREATE TABLE products (product_no integer, name text, product_sku integer, UNIQUE(product_no, product_sku))"]
204+
(-> (create-table :products)
205+
(with-columns [[:product_no :integer]
206+
[:name :text]
207+
[:product_sku :integer]])
208+
(constraints [[:unique [:product_no :product_sku]]])
209+
sql/format))))
210+
(testing "creating table with primary key constraint on single column"
211+
(is (= ["CREATE TABLE products (product_no integer, name text, product_sku integer, PRIMARY KEY(product_no))"]
212+
(-> (create-table :products)
213+
(with-columns [[:product_no :integer]
214+
[:name :text]
215+
[:product_sku :integer]])
216+
(constraints [[:primary-key [:product_no]]])
217+
sql/format))))
218+
(testing "creating table with primary key and unique constraints"
219+
(is (= ["CREATE TABLE products (product_no integer, name text, product_sku integer, UNIQUE(product_no, product_sku), PRIMARY KEY(product_no))"]
220+
(-> (create-table :products)
221+
(with-columns [[:product_no :integer]
222+
[:name :text]
223+
[:product_sku :integer]])
224+
(constraints [[:unique [:product_no :product_sku]]
225+
[:primary-key [:product_no]]])
226+
sql/format))))
227+
(testing "creating table with invalid/unsupported constraints does not produce incorrect SQL statement"
228+
(is (= ["CREATE TABLE products (product_no integer, name text, product_sku integer, PRIMARY KEY(product_no))"]
229+
(-> (create-table :products)
230+
(with-columns [[:product_no :integer]
231+
[:name :text]
232+
[:product_sku :integer]])
233+
(constraints [[:unique-constraint [:product_no]] ;; incorrect constraint-type
234+
[:primary-key [:product_no]]
235+
[:not-null [:name]]]) ;; unsupported constraint-type
236+
sql/format)))))
237+
200238
(deftest over-test
201239
(testing "window function over on select statemt"
202240
(is (= ["SELECT id , avg(salary) OVER (PARTITION BY department ORDER BY designation) AS Average, max(salary) OVER w AS MaxSalary FROM employee WINDOW w AS (PARTITION BY department)"]

0 commit comments

Comments
 (0)