Fix query generation when user.language is Turkish
This commit is contained in:
parent
b68e3c3f20
commit
bd076b193a
2 changed files with 33 additions and 3 deletions
|
|
@ -71,6 +71,17 @@
|
||||||
(defn- undasherize [s]
|
(defn- undasherize [s]
|
||||||
(string/replace s "-" "_"))
|
(string/replace s "-" "_"))
|
||||||
|
|
||||||
|
;; String.toUpperCase() or `string/upper-case` for that matter converts the string to uppercase for the DEFAULT
|
||||||
|
;; LOCALE. Normally this does what you'd expect but things like `inner join` get converted to `İNNER JOIN` (dot over
|
||||||
|
;; the I) when user locale is Turkish. This predictably has bad consequences for people who like their SQL queries to
|
||||||
|
;; work. The fix here is to use String.toUpperCase(Locale/US) instead which always converts things the way we'd expect.
|
||||||
|
;;
|
||||||
|
;; Use this function instead of `string/upper-case` as it will always use Locale/US.
|
||||||
|
(def ^:private ^{:arglists '([s])} upper-case
|
||||||
|
;; TODO - not sure if there's a JavaScript equivalent here we should be using as well
|
||||||
|
#?(:clj (fn [s] (.. s toString (toUpperCase (java.util.Locale/US))))
|
||||||
|
:cljs string/upper-case))
|
||||||
|
|
||||||
(defn quote-identifier [x & {:keys [style split] :or {split true}}]
|
(defn quote-identifier [x & {:keys [style split] :or {split true}}]
|
||||||
(let [name-transform-fn (cond
|
(let [name-transform-fn (cond
|
||||||
*name-transform-fn* *name-transform-fn*
|
*name-transform-fn* *name-transform-fn*
|
||||||
|
|
@ -453,7 +464,7 @@
|
||||||
(->> args
|
(->> args
|
||||||
(remove nil?)
|
(remove nil?)
|
||||||
(map format-predicate*)
|
(map format-predicate*)
|
||||||
(string/join (str " " (string/upper-case op-name) " "))
|
(string/join (str " " (upper-case op-name) " "))
|
||||||
(paren-wrap))
|
(paren-wrap))
|
||||||
|
|
||||||
"exists"
|
"exists"
|
||||||
|
|
@ -494,7 +505,7 @@
|
||||||
(defmethod format-clause :select [[_ fields] sql-map]
|
(defmethod format-clause :select [[_ fields] sql-map]
|
||||||
(str "SELECT "
|
(str "SELECT "
|
||||||
(when (:modifiers sql-map)
|
(when (:modifiers sql-map)
|
||||||
(str (space-join (map (comp string/upper-case name)
|
(str (space-join (map (comp upper-case name)
|
||||||
(:modifiers sql-map)))
|
(:modifiers sql-map)))
|
||||||
" "))
|
" "))
|
||||||
(comma-join (map to-sql fields))))
|
(comma-join (map to-sql fields))))
|
||||||
|
|
@ -507,7 +518,7 @@
|
||||||
|
|
||||||
(defn format-join [type table pred]
|
(defn format-join [type table pred]
|
||||||
(str (when type
|
(str (when type
|
||||||
(str (string/upper-case (name type)) " "))
|
(str (upper-case (name type)) " "))
|
||||||
"JOIN " (to-sql table)
|
"JOIN " (to-sql table)
|
||||||
(when pred
|
(when pred
|
||||||
(if (= :using (first pred))
|
(if (= :using (first pred))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
(:refer-clojure :exclude [format])
|
(:refer-clojure :exclude [format])
|
||||||
(:require [#?@(:clj [clojure.test :refer]
|
(:require [#?@(:clj [clojure.test :refer]
|
||||||
:cljs [cljs.test :refer-macros]) [deftest testing is are]]
|
:cljs [cljs.test :refer-macros]) [deftest testing is are]]
|
||||||
|
honeysql.core
|
||||||
[honeysql.types :as sql]
|
[honeysql.types :as sql]
|
||||||
[honeysql.format :refer
|
[honeysql.format :refer
|
||||||
[*allow-dashed-names?* quote-identifier format-clause format
|
[*allow-dashed-names?* quote-identifier format-clause format
|
||||||
|
|
@ -228,3 +229,21 @@
|
||||||
(format {:select [(honeysql.core/inline "foo")
|
(format {:select [(honeysql.core/inline "foo")
|
||||||
(honeysql.core/inline :bar)
|
(honeysql.core/inline :bar)
|
||||||
(honeysql.core/inline nil)]}))))
|
(honeysql.core/inline nil)]}))))
|
||||||
|
|
||||||
|
;; Make sure if Locale is Turkish we're not generating queries like İNNER JOIN (dot over the I) because
|
||||||
|
;; `string/upper-case` is converting things to upper-case using the default Locale. Generated query should be the same
|
||||||
|
;; regardless of system Locale. See #236
|
||||||
|
#?(:clj
|
||||||
|
(deftest statements-generated-correctly-with-turkish-locale
|
||||||
|
(let [format-with-locale (fn [^String language-tag]
|
||||||
|
(let [original-locale (java.util.Locale/getDefault)]
|
||||||
|
(try
|
||||||
|
(java.util.Locale/setDefault (java.util.Locale/forLanguageTag language-tag))
|
||||||
|
(format {:select [:t2.name]
|
||||||
|
:from [[:table1 :t1]]
|
||||||
|
:join [[:table2 :t2] [:= :t1.fk :t2.id]]
|
||||||
|
:where [:= :t1.id 1]})
|
||||||
|
(finally
|
||||||
|
(java.util.Locale/setDefault original-locale)))))]
|
||||||
|
(is (= (format-with-locale "en")
|
||||||
|
(format-with-locale "tr"))))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue