change :' to use format-entity #352
This commit is contained in:
parent
b7b1ebafb9
commit
c7c634d694
4 changed files with 54 additions and 41 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Changes
|
||||
|
||||
* 2.2.next in progress
|
||||
* Address [#352](https://github.com/seancorfield/honeysql/issues/352) by treating `:'` as introducing a function name that should be transcribed exactly as-is into the generated SQL.
|
||||
* Address [#352](https://github.com/seancorfield/honeysql/issues/352) by treating `:'` as introducing a function name that should be formatted as a SQL entity (respects quoting, dot-splitting, etc).
|
||||
|
||||
* 2.2.861 -- 2022-01-30
|
||||
* Address [#382](https://github.com/seancorfield/honeysql/issues/382) by adding `:case-expr` for BigQuery support.
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -574,15 +574,24 @@ regular function calls in a select:
|
|||
=> ["SELECT MAX(id) FROM foo"]
|
||||
```
|
||||
|
||||
If a keyword begins with `'`, the function name is treated literally
|
||||
without being converted to uppercase (and without hyphens `-` becoming
|
||||
spaces):
|
||||
If a keyword begins with `'`, the function name is formatted as a SQL
|
||||
entity rather than being converted to uppercase and having hyphens `-`
|
||||
converted to spaces). That means that hyphens `-` will become underscores `_`
|
||||
unless you have quoting enabled:
|
||||
|
||||
```clojure
|
||||
(-> (select :*) (from :foo)
|
||||
(where [:'my-schema.SomeFunction :bar 0])
|
||||
(sql/format))
|
||||
=> ["SELECT * FROM foo WHERE my-schema.SomeFunction(bar, ?)" 0]
|
||||
=> ["SELECT * FROM foo WHERE my_schema.SomeFunction(bar, ?)" 0]
|
||||
(-> (select :*) (from :foo)
|
||||
(where [:'my-schema.SomeFunction :bar 0])
|
||||
(sql/format :quoted true))
|
||||
=> ["SELECT * FROM \"foo\" WHERE \"my-schema\".\"SomeFunction\"(\"bar\", ?)" 0]
|
||||
(-> (select :*) (from :foo)
|
||||
(where [:'my-schema.SomeFunction :bar 0])
|
||||
(sql/format :dialect :mysql))
|
||||
=> ["SELECT * FROM `foo` WHERE `my-schema`.`SomeFunction`(`bar`, ?)" 0]
|
||||
```
|
||||
|
||||
### Bindable parameters
|
||||
|
|
|
|||
|
|
@ -164,31 +164,6 @@
|
|||
s
|
||||
(recur (str/replace s #"(\w)-(\w)" "$1 $2") s))))
|
||||
|
||||
(defn sql-kw
|
||||
"Given a keyword, return a SQL representation of it as a string.
|
||||
|
||||
A keyword whose name begins with a single quote is left exactly as-is
|
||||
(with the `:` and `'` removed), otherwise a `:kebab-case` keyword
|
||||
becomes a `KEBAB CASE` (uppercase) string with hyphens replaced
|
||||
by spaces, e.g., `:insert-into` => `INSERT INTO`.
|
||||
|
||||
Any namespace qualifier is ignored."
|
||||
[k]
|
||||
(let [n (name k)]
|
||||
(if (= \' (first n))
|
||||
(subs n 1 (count n))
|
||||
(-> n (dehyphen) (upper-case)))))
|
||||
|
||||
(defn- sym->kw
|
||||
"Given a symbol, produce a keyword, retaining the namespace
|
||||
qualifier, if any."
|
||||
[s]
|
||||
(if (symbol? s)
|
||||
(if-let [n (namespace s)]
|
||||
(keyword n (name s))
|
||||
(keyword (name s)))
|
||||
s))
|
||||
|
||||
(defn- namespace-_
|
||||
"Return the namespace portion of a symbol, with dashes converted."
|
||||
[x]
|
||||
|
|
@ -211,14 +186,6 @@
|
|||
{:symbol x
|
||||
:failure (str t)})))))
|
||||
|
||||
(defn- sqlize-value [x]
|
||||
(cond
|
||||
(nil? x) "NULL"
|
||||
(string? x) (str \' (str/replace x "'" "''") \')
|
||||
(ident? x) (sql-kw x)
|
||||
(vector? x) (str "[" (str/join ", " (map #'sqlize-value x)) "]")
|
||||
:else (str x)))
|
||||
|
||||
(defn format-entity
|
||||
"Given a simple SQL entity (a keyword or symbol -- or string),
|
||||
return the equivalent SQL fragment (as a string -- no parameters).
|
||||
|
|
@ -255,6 +222,39 @@
|
|||
[v a d (format-entity v {:aliased a :drop-ns d})])))
|
||||
.)
|
||||
|
||||
(defn sql-kw
|
||||
"Given a keyword, return a SQL representation of it as a string.
|
||||
|
||||
A keyword whose name begins with a single quote is left exactly as-is
|
||||
(with the `:` and `'` removed), otherwise a `:kebab-case` keyword
|
||||
becomes a `KEBAB CASE` (uppercase) string with hyphens replaced
|
||||
by spaces, e.g., `:insert-into` => `INSERT INTO`.
|
||||
|
||||
Any namespace qualifier is ignored."
|
||||
[k]
|
||||
(let [n (name k)]
|
||||
(if (= \' (first n))
|
||||
(format-entity (keyword (subs n 1 (count n))))
|
||||
(-> n (dehyphen) (upper-case)))))
|
||||
|
||||
(defn- sym->kw
|
||||
"Given a symbol, produce a keyword, retaining the namespace
|
||||
qualifier, if any."
|
||||
[s]
|
||||
(if (symbol? s)
|
||||
(if-let [n (namespace s)]
|
||||
(keyword n (name s))
|
||||
(keyword (name s)))
|
||||
s))
|
||||
|
||||
(defn- sqlize-value [x]
|
||||
(cond
|
||||
(nil? x) "NULL"
|
||||
(string? x) (str \' (str/replace x "'" "''") \')
|
||||
(ident? x) (sql-kw x)
|
||||
(vector? x) (str "[" (str/join ", " (map #'sqlize-value x)) "]")
|
||||
:else (str x)))
|
||||
|
||||
(defn- param-value [k]
|
||||
(if (contains? *params* k)
|
||||
(get *params* k)
|
||||
|
|
|
|||
|
|
@ -800,10 +800,14 @@ ORDER BY id = ? DESC
|
|||
(format {:select [[[:'sysdate]]]})))
|
||||
(is (= ["SELECT count(*)"]
|
||||
(format {:select [[[:'count :*]]]})))
|
||||
(is (= ["SELECT Mixed-Kebab(`yum-yum`)"]
|
||||
(is (= ["SELECT Mixed_Kebab(yum_yum)"]
|
||||
(format {:select [[[:'Mixed-Kebab :yum-yum]]]})))
|
||||
(is (= ["SELECT `Mixed-Kebab`(`yum-yum`)"]
|
||||
(format {:select [[[:'Mixed-Kebab :yum-yum]]]} :dialect :mysql)))
|
||||
(is (= ["SELECT other-project.other_dataset.other_function(?, ?)" 1 2]
|
||||
(format {:select [[[:'other-project.other_dataset.other_function 1 2]]]})))))
|
||||
(is (= ["SELECT other_project.other_dataset.other_function(?, ?)" 1 2]
|
||||
(format {:select [[[:'other-project.other_dataset.other_function 1 2]]]})))
|
||||
(is (= ["SELECT \"other-project\".\"other_dataset\".\"other_function\"(?, ?)" 1 2]
|
||||
(format {:select [[[:'other-project.other_dataset.other_function 1 2]]]} :dialect :ansi)))))
|
||||
|
||||
(deftest join-without-on-using
|
||||
;; essentially issue 326
|
||||
|
|
|
|||
Loading…
Reference in a new issue