From 379d3d05c48f1b3d28d44065e40e22b965754813 Mon Sep 17 00:00:00 2001 From: Sean Corfield Date: Mon, 1 Feb 2021 13:10:57 -0800 Subject: [PATCH] Drop ? from all keyword options --- README.md | 19 +++++----- src/honey/sql.cljc | 80 ++++++++++++++++++++-------------------- test/honey/sql_test.cljc | 18 ++++----- 3 files changed, 58 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 873757c..dad105d 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,7 @@ This is the README for the upcoming 2.x version of HoneySQL which provides a str All sample code in this README is automatically run as a unit test using [seancorfield/readme](https://github.com/seancorfield/readme). -Note that while some of these samples show pretty-printed SQL, this is just for -README readability; honeysql does not generate pretty-printed SQL. +Some of these samples show pretty-printed SQL: HoneySQL 2.x supports `:pretty true` which inserts newlines between clauses in the generated SQL strings. ## Usage @@ -154,7 +153,7 @@ then provide a collection of rows, each a collection of column values: [["Jon" "Smith" 34] ["Andrew" "Cooper" 12] ["Jane" "Daniels" 56]]) - (sql/format {:pretty? true})) + (sql/format {:pretty true})) => [" INSERT INTO properties (name, surname, age) @@ -172,7 +171,7 @@ and the remaining maps *must* have the same set of keys and values: (values [{:name "John" :surname "Smith" :age 34} {:name "Andrew" :surname "Cooper" :age 12} {:name "Jane" :surname "Daniels" :age 56}]) - (sql/format {:pretty? true})) + (sql/format {:pretty true})) => [" INSERT INTO properties (name, surname, age) VALUES (?, ?, ?), (?, ?, ?), (?, ?, ?) @@ -194,7 +193,7 @@ The column values do not have to be literals, they can be nested queries: :role_id (-> (select :id) (from :role) (where [:= :name role-name]))}]) - (sql/format {:pretty? true}))) + (sql/format {:pretty true}))) => [" INSERT INTO user_profile_to_role @@ -222,7 +221,7 @@ Composite types are supported: (values [["small" (composite 1 "inch")] ["large" (composite 10 "feet")]]) - (sql/format {:pretty? true})) + (sql/format {:pretty true})) => [" INSERT INTO comp_table (name, comp_column) @@ -240,7 +239,7 @@ Updates are possible too: (set {:kind "dramatic" :watched [:+ :watched 1]}) (where [:= :kind "drama"]) - (sql/format {:pretty? true})) + (sql/format {:pretty true})) => [" UPDATE films SET kind = ?, watched = watched + ? @@ -276,7 +275,7 @@ If your database supports it, you can also delete from multiple tables: (from :films) (join :directors [:= :films.director_id :directors.id]) (where [:<> :kind "musical"]) - (sql/format {:pretty? true})) + (sql/format {:pretty true})) => [" DELETE films, directors FROM films @@ -363,7 +362,7 @@ have a lot of function calls needed in code: (values [{:location [:ST_SetSRID [:ST_MakePoint 0.291 32.621] [:cast 4325 :integer]]}]) - (sql/format {:pretty? true})) + (sql/format {:pretty true})) => [" INSERT INTO sample (location) VALUES (ST_SETSRID(ST_MAKEPOINT(?, ?), CAST(? AS integer))) @@ -523,7 +522,7 @@ big-complicated-map ```clojure (sql/format big-complicated-map {:params {:param1 "gabba" :param2 2} - :pretty? true}) + :pretty true}) => [" SELECT DISTINCT f.*, b.baz, c.quux, b.bla \"bla-bla\", NOW(), @x := 10 FROM foo AS f, baz AS b diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 0fac9e5..64de08b 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -115,13 +115,13 @@ (defn- namespace-_ [x] (some-> (namespace x) (str/replace "-" "_"))) (defn- name-_ [x] (str/replace (name x) "-" "_")) -(defn- format-entity [x & [{:keys [aliased? drop-ns?]}]] +(defn- format-entity [x & [{:keys [aliased drop-ns]}]] (let [nn (if (or *quoted* (string? x)) name name-_) q (if (or *quoted* (string? x)) (:quote *dialect*) identity) - [t c] (if-let [n (when-not (or drop-ns? (string? x)) + [t c] (if-let [n (when-not (or drop-ns (string? x)) (namespace-_ x))] [n (nn x)] - (if aliased? + (if aliased [nil (nn x)] (let [[t c] (str/split (nn x) #"\.")] (if c [t c] [nil t]))))] @@ -162,30 +162,30 @@ (cond-> (format-entity s) pair? (str (if (and (contains? *dialect* :as) (not (:as *dialect*))) " " " AS ") - (format-entity (second x) {:aliased? true})))) + (format-entity (second x) {:aliased true})))) :else (format-entity x))) -(defn- format-selectable-dsl [x & [{:keys [as? aliased?] :as opts}]] +(defn- format-selectable-dsl [x & [{:keys [as aliased] :as opts}]] (cond (map? x) - (format-dsl x {:nested? true}) + (format-dsl x {:nested true}) (sequential? x) (let [s (first x) pair? (< 1 (count x)) a (second x) [sql & params] (if (map? s) - (format-dsl s {:nested? true}) + (format-dsl s {:nested true}) (format-expr s)) [sql' & params'] (when pair? (if (sequential? a) - (let [[sql params] (format-expr-list a {:aliased? true})] + (let [[sql params] (format-expr-list a {:aliased true})] (into [(str/join " " sql)] params)) - (format-selectable-dsl a {:aliased? true})))] + (format-selectable-dsl a {:aliased true})))] (-> [(cond-> sql pair? - (str (if as? + (str (if as (if (and (contains? *dialect* :as) (not (:as *dialect*))) " " @@ -195,11 +195,11 @@ (into params'))) (or (keyword? x) (symbol? x)) - (if aliased? + (if aliased [(format-entity x opts)] (format-var x opts)) - (and aliased? (string? x)) + (and aliased (string? x)) [(format-entity x opts)] :else @@ -212,7 +212,7 @@ (reduce (fn [[sql params] [sql' & params']] [(conj sql sql') (if params' (into params params') params)]) [[] []] - (map #(format-dsl % {:nested? true}) xs))] + (map #(format-dsl % {:nested true}) xs))] (into [(str/join (str " " (sql-kw k) " ") sqls)] params))) (defn format-expr-list @@ -235,7 +235,7 @@ (map #(format-expr % opts) exprs))) (defn- format-columns [k xs] - (let [[sqls params] (format-expr-list xs {:drop-ns? (= :columns k)})] + (let [[sqls params] (format-expr-list xs {:drop-ns (= :columns k)})] (into [(str "(" (str/join ", " sqls) ")")] params))) (defn- format-selects [k xs] @@ -244,9 +244,9 @@ (reduce (fn [[sql params] [sql' & params']] [(conj sql sql') (if params' (into params params') params)]) [[] []] - (map #(format-selectable-dsl % {:as? (#{:select :from} k)}) xs))] + (map #(format-selectable-dsl % {:as (#{:select :from} k)}) xs))] (into [(str (sql-kw k) " " (str/join ", " sqls))] params)) - (let [[sql & params] (format-selectable-dsl xs {:as? (#{:select :from} k)})] + (let [[sql & params] (format-selectable-dsl xs {:as (#{:select :from} k)})] (into [(str (sql-kw k) " " sql)] params)))) (defn- format-with-part [x] @@ -386,7 +386,7 @@ xs))] (into [(str "(" (str/join ", " - (map #(format-entity % {:drop-ns? true}) cols)) + (map #(format-entity % {:drop-ns true}) cols)) ") " (sql-kw k) " " @@ -419,7 +419,7 @@ (defn- format-do-update-set [k x] (if (or (keyword? x) (symbol? x)) - (let [e (format-entity x {:drop-ns? true})] + (let [e (format-entity x {:drop-ns true})] [(str (sql-kw k) " " e " = EXCLUDED." e)]) (format-set-exprs k x))) @@ -489,7 +489,7 @@ This is intended to be used when writing your own formatters to extend the DSL supported by HoneySQL." - [statement-map & [{:keys [aliased? nested? pretty?]}]] + [statement-map & [{:keys [aliased nested pretty]}]] (let [[sqls params leftover] (reduce (fn [[sql params leftover] k] (if-let [xs (or (k statement-map) @@ -507,10 +507,10 @@ (throw (ex-info (str "Unknown SQL clauses: " (str/join ", " (keys leftover))) leftover)) - (into [(cond-> (str/join (if pretty? "\n" " ") (filter seq sqls)) - pretty? + (into [(cond-> (str/join (if pretty "\n" " ") (filter seq sqls)) + pretty (as-> s (str "\n" s "\n")) - (and nested? (not aliased?)) + (and nested (not aliased)) (as-> s (str "(" s ")")))] params)))) (def ^:private infix-aliases @@ -552,8 +552,8 @@ x)) (defn- format-in [in [x y]] - (let [[sql-x & params-x] (format-expr x {:nested? true}) - [sql-y & params-y] (format-expr y {:nested? true}) + (let [[sql-x & params-x] (format-expr x {:nested true}) + [sql-y & params-y] (format-expr y {:nested true}) values (unwrap (first params-y) {})] (if (and (= "?" sql-y) (= 1 (count params-y)) (coll? values)) (let [sql (str "(" (str/join ", " (repeat (count values) "?")) ")")] @@ -572,9 +572,9 @@ (into [(str "ARRAY[" (str/join ", " sqls) "]")] params))) :between (fn [_ [x a b]] - (let [[sql-x & params-x] (format-expr x {:nested? true}) - [sql-a & params-a] (format-expr a {:nested? true}) - [sql-b & params-b] (format-expr b {:nested? true})] + (let [[sql-x & params-x] (format-expr x {:nested true}) + [sql-a & params-a] (format-expr a {:nested true}) + [sql-b & params-b] (format-expr b {:nested true})] (-> [(str sql-x " BETWEEN " sql-a " AND " sql-b)] (into params-x) (into params-a) @@ -625,7 +625,7 @@ {::wrapper (fn [fx _] (fx))})]) :nest (fn [_ [x]] - (format-expr x {:nested? true})) + (format-expr x {:nested true})) :not (fn [_ [x]] (let [[sql & params] (format-expr x)] @@ -655,12 +655,12 @@ This is intended to be used when writing your own formatters to extend the DSL supported by HoneySQL." - [expr & [{:keys [nested?] :as opts}]] + [expr & [{:keys [nested] :as opts}]] (cond (or (keyword? expr) (symbol? expr)) (format-var expr opts) (map? expr) - (format-dsl expr (assoc opts :nested? true)) + (format-dsl expr (assoc opts :nested true)) (sequential? expr) (let [op (first expr) @@ -678,10 +678,10 @@ [(conj sql sql') (if params' (into params params') params)]) [[] []] - (map #(format-expr % {:nested? true}) + (map #(format-expr % {:nested true}) (rest x)))] (into [(cond-> (str/join (str " " (sql-kw op) " ") sqls) - nested? + nested (as-> s (str "(" s ")")))] params)) (let [[_ a b & y] expr @@ -690,26 +690,26 @@ op " is supported") {:expr expr}))) - [s1 & p1] (format-expr a {:nested? true}) - [s2 & p2] (format-expr b {:nested? true}) + [s1 & p1] (format-expr a {:nested true}) + [s2 & p2] (format-expr b {:nested true}) op (get infix-aliases op op)] (if (and (#{:= :<>} op) (or (nil? a) (nil? b))) (-> (str (if (nil? a) (if (nil? b) "NULL" s2) s1) (if (= := op) " IS NULL" " IS NOT NULL")) - (cond-> nested? + (cond-> nested (as-> s (str "(" s ")"))) (vector)) (-> (str s1 " " (sql-kw op) " " s2) - (cond-> nested? + (cond-> nested (as-> s (str "(" s ")"))) (vector) (into p1) (into p2))))) (contains? #{:in :not-in} op) (let [[sql & params] (format-in op (rest expr))] - (into [(if nested? (str "(" sql ")") sql)] params)) + (into [(if nested (str "(" sql ")") sql)] params)) (contains? @special-syntax op) (let [formatter (get @special-syntax op)] (formatter op (rest expr))) @@ -849,7 +849,7 @@ (format {:select [:*] :from [:table] :order-by [[[:date :expiry] :desc] :bar]} {}) (println (format {:select [:*] :from [:table] - :order-by [[[:date :expiry] :desc] :bar]} {:pretty? true})) + :order-by [[[:date :expiry] :desc] :bar]} {:pretty true})) (format {:select [:*] :from [:table] :where [:< [:date_add :expiry [:interval 30 :days]] [:now]]} {}) (format-expr [:interval 30 :days]) @@ -859,10 +859,10 @@ :where [:= :id (with-meta (constantly 42) {:foo true})]} {:dialect :mysql})) (println (format {:select [:*] :from [:table] - :where [:in :id [1 2 3 4]]} {:pretty? true})) + :where [:in :id [1 2 3 4]]} {:pretty true})) (println (format {:select [:*] :from [:table] :where [:and [:in :id [1 [:param :foo]]] [:= :bar [:param :quux]]]} {:params {:foo 42 :quux 13} - :pretty? true})) + :pretty true})) ,) diff --git a/test/honey/sql_test.cljc b/test/honey/sql_test.cljc index 8655bbd..56c4d45 100644 --- a/test/honey/sql_test.cljc +++ b/test/honey/sql_test.cljc @@ -477,14 +477,14 @@ VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes') :values [[[:inline "UA502"] [:inline "Bananas"] [:inline 105] [:inline "1971-07-13"] [:inline "Comedy"] [:inline "82 minutes"]]]} - {:pretty? true}))) + {:pretty true}))) (is (= [" INSERT INTO films VALUES (?, ?, ?, ?, ?, ?) " "UA502", "Bananas", 105, "1971-07-13", "Comedy", "82 minutes"] (format {:insert-into :films :values [["UA502" "Bananas" 105 "1971-07-13" "Comedy" "82 minutes"]]} - {:pretty? true}))) + {:pretty true}))) (is (= [" INSERT INTO films (code, title, did, date_prod, kind) @@ -493,14 +493,14 @@ VALUES (?, ?, ?, ?, ?) (format {:insert-into :films :columns [:code :title :did :date_prod :kind] :values [["T_601", "Yojimo", 106, "1961-06-16", "Drama"]]} - {:pretty? true}))) + {:pretty true}))) (is (= [" INSERT INTO films VALUES (?, ?, ?, DEFAULT, ?, ?) " "UA502", "Bananas", 105, "Comedy", "82 minutes"] (format {:insert-into :films :values [["UA502" "Bananas" 105 [:default] "Comedy" "82 minutes"]]} - {:pretty? true}))) + {:pretty true}))) (is (= [" INSERT INTO films (code, title, did, date_prod, kind) @@ -509,7 +509,7 @@ VALUES (?, ?, ?, DEFAULT, ?) (format {:insert-into :films :columns [:code :title :did :date_prod :kind] :values [["T_601", "Yojimo", 106, [:default], "Drama"]]} - {:pretty? true})))) + {:pretty true})))) (deftest on-conflict-tests ;; these examples are taken from https://www.postgresqltutorial.com/postgresql-upsert/ @@ -525,7 +525,7 @@ DO NOTHING :values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]] :on-conflict {:on-constraint :customers_name_key} :do-nothing true} - {:pretty? true}))) + {:pretty true}))) (is (= [" INSERT INTO customers (name, email) @@ -538,7 +538,7 @@ DO NOTHING :values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]] :on-conflict :name :do-nothing true} - {:pretty? true}))) + {:pretty true}))) (is (= [" INSERT INTO customers (name, email) @@ -551,7 +551,7 @@ DO UPDATE SET email = EXCLUDED.email || ';' || customers.email :values [[[:inline "Microsoft"], [:inline "hotline@microsoft.com"]]] :on-conflict :name :do-update-set {:email [:|| :EXCLUDED.email [:inline ";"] :customers.email]}} - {:pretty? true})))) + {:pretty true})))) (deftest issue-285 (is (= [" @@ -564,4 +564,4 @@ ORDER BY id = ? DESC (h/from :processes) (h/where [:= :state 42]) (h/order-by [[:= :id 123] :desc])) - {:pretty? true})))) + {:pretty true}))))