Merge pull request #130 from rnewman/rnewman/rebase
ClojureScript support (fixes #117)
This commit is contained in:
commit
f00855c30b
10 changed files with 239 additions and 157 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,3 +1,6 @@
|
||||||
|
*~
|
||||||
|
.sw*
|
||||||
|
*.swp
|
||||||
/target
|
/target
|
||||||
/lib
|
/lib
|
||||||
/classes
|
/classes
|
||||||
|
|
|
||||||
21
project.clj
21
project.clj
|
|
@ -5,4 +5,23 @@
|
||||||
:url "https://github.com/jkk/honeysql"
|
:url "https://github.com/jkk/honeysql"
|
||||||
:scm {:name "git"
|
:scm {:name "git"
|
||||||
:url "https://github.com/jkk/honeysql"}
|
:url "https://github.com/jkk/honeysql"}
|
||||||
:dependencies [[org.clojure/clojure "1.8.0"]])
|
:dependencies [[org.clojure/clojure "1.8.0"]]
|
||||||
|
:cljsbuild {:builds {:release {:source-paths ["src"]
|
||||||
|
:compiler {:output-to "dist/honeysql.js"
|
||||||
|
:optimizations :advanced
|
||||||
|
:output-wrapper false
|
||||||
|
:parallel-build true
|
||||||
|
:pretty-print false}}
|
||||||
|
:test {:source-paths ["src" "test"]
|
||||||
|
:compiler {:output-to "target/test/honeysql.js"
|
||||||
|
:output-dir "target/test"
|
||||||
|
:source-map true
|
||||||
|
:main honeysql.test
|
||||||
|
:parallel-build true
|
||||||
|
:target :nodejs}}}}
|
||||||
|
:doo {:build "test"}
|
||||||
|
:profiles {:dev {:dependencies [[org.clojure/clojure "1.8.0"]
|
||||||
|
[org.clojure/clojurescript "1.9.89"]
|
||||||
|
[cljsbuild "1.1.3"]]
|
||||||
|
:plugins [[lein-cljsbuild "1.1.3"]
|
||||||
|
[lein-doo "0.1.6"]]}})
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
(:require [honeysql.format :as format]
|
(:require [honeysql.format :as format]
|
||||||
[honeysql.types :as types]
|
[honeysql.types :as types]
|
||||||
[honeysql.helpers :refer [build-clause]]
|
[honeysql.helpers :refer [build-clause]]
|
||||||
[honeysql.util :refer [defalias]]
|
#?(:clj [honeysql.util :refer [defalias]])
|
||||||
[clojure.string :as string]))
|
[clojure.string :as string]))
|
||||||
|
|
||||||
(defalias call types/call)
|
(#?(:clj defalias :cljs def) call types/call)
|
||||||
(defalias raw types/raw)
|
(#?(:clj defalias :cljs def) raw types/raw)
|
||||||
(defalias param types/param)
|
(#?(:clj defalias :cljs def) param types/param)
|
||||||
(defalias format format/format)
|
(#?(:clj defalias :cljs def) format format/format)
|
||||||
(defalias format-predicate format/format-predicate)
|
(#?(:clj defalias :cljs def) format-predicate format/format-predicate)
|
||||||
(defalias quote-identifier format/quote-identifier)
|
(#?(:clj defalias :cljs def) quote-identifier format/quote-identifier)
|
||||||
|
|
||||||
(defn qualify
|
(defn qualify
|
||||||
"Takes one or more keyword or string qualifers and name. Returns
|
"Takes one or more keyword or string qualifers and name. Returns
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
(ns honeysql.format
|
(ns honeysql.format
|
||||||
(:refer-clojure :exclude [format])
|
(:refer-clojure :exclude [format])
|
||||||
(:require [honeysql.types :refer [call raw param param-name]]
|
(:require [honeysql.types :refer [call raw param param-name
|
||||||
|
#?@(:cljs [SqlCall SqlRaw SqlParam SqlArray])]]
|
||||||
[clojure.string :as string])
|
[clojure.string :as string])
|
||||||
(:import [honeysql.types SqlCall SqlRaw SqlParam SqlArray]))
|
#?(:clj (:import [honeysql.types SqlCall SqlRaw SqlParam SqlArray])))
|
||||||
|
|
||||||
;;(set! *warn-on-reflection* true)
|
;;(set! *warn-on-reflection* true)
|
||||||
|
|
||||||
|
|
@ -203,7 +204,10 @@
|
||||||
|
|
||||||
(defn sort-clauses [clauses]
|
(defn sort-clauses [clauses]
|
||||||
(let [m @clause-store]
|
(let [m @clause-store]
|
||||||
(sort-by #(m % Long/MAX_VALUE) clauses)))
|
(sort-by
|
||||||
|
(fn [c]
|
||||||
|
(m c #?(:clj Long/MAX_VALUE :cljs js/Number.MAX_VALUE)))
|
||||||
|
clauses)))
|
||||||
|
|
||||||
(defn format
|
(defn format
|
||||||
"Takes a SQL map and optional input parameters and returns a vector
|
"Takes a SQL map and optional input parameters and returns a vector
|
||||||
|
|
@ -243,11 +247,22 @@
|
||||||
(defprotocol Parameterizable
|
(defprotocol Parameterizable
|
||||||
(to-params [value pname]))
|
(to-params [value pname]))
|
||||||
|
|
||||||
|
(defn to-params-seq [s pname]
|
||||||
|
(paren-wrap (comma-join (mapv #(to-params % pname) s))))
|
||||||
|
|
||||||
|
(defn to-params-default [value pname]
|
||||||
|
(swap! *params* conj value)
|
||||||
|
(swap! *param-names* conj pname)
|
||||||
|
(*parameterizer*))
|
||||||
|
|
||||||
(extend-protocol Parameterizable
|
(extend-protocol Parameterizable
|
||||||
clojure.lang.Sequential
|
#?@(:clj
|
||||||
|
[clojure.lang.Sequential
|
||||||
|
|
||||||
(to-params [value pname]
|
(to-params [value pname]
|
||||||
(paren-wrap (comma-join (mapv #(to-params % pname) value))))
|
(to-params-seq value pname))])
|
||||||
clojure.lang.IPersistentSet
|
#?(:clj clojure.lang.IPersistentSet
|
||||||
|
:cljs cljs.core/PersistentHashSet)
|
||||||
(to-params [value pname]
|
(to-params [value pname]
|
||||||
(to-params (seq value) pname))
|
(to-params (seq value) pname))
|
||||||
nil
|
nil
|
||||||
|
|
@ -255,11 +270,14 @@
|
||||||
(swap! *params* conj value)
|
(swap! *params* conj value)
|
||||||
(swap! *param-names* conj pname)
|
(swap! *param-names* conj pname)
|
||||||
(*parameterizer*))
|
(*parameterizer*))
|
||||||
java.lang.Object
|
#?(:clj Object :cljs default)
|
||||||
(to-params [value pname]
|
(to-params [value pname]
|
||||||
(swap! *params* conj value)
|
#?(:clj
|
||||||
(swap! *param-names* conj pname)
|
(to-params-default value pname)
|
||||||
(*parameterizer*)))
|
:cljs
|
||||||
|
(if (sequential? value)
|
||||||
|
(to-params-seq value pname)
|
||||||
|
(to-params-default value pname)))))
|
||||||
|
|
||||||
(defn add-param [pname pval]
|
(defn add-param [pname pval]
|
||||||
(to-params pval pname))
|
(to-params pval pname))
|
||||||
|
|
@ -279,22 +297,18 @@
|
||||||
|
|
||||||
(declare -format-clause)
|
(declare -format-clause)
|
||||||
|
|
||||||
(extend-protocol ToSql
|
(defn map->sql [m]
|
||||||
clojure.lang.Keyword
|
(let [clause-ops (sort-clauses (keys m))
|
||||||
(to-sql [x]
|
sql-str (binding [*subquery?* true
|
||||||
(let [s (name x)]
|
*fn-context?* false]
|
||||||
(case (.charAt s 0)
|
(space-join
|
||||||
\% (let [call-args (string/split (subs s 1) #"\." 2)]
|
(map (comp #(-format-clause % m) #(find m %))
|
||||||
(to-sql (apply call (map keyword call-args))))
|
clause-ops)))]
|
||||||
\? (to-sql (param (keyword (subs s 1))))
|
(if *subquery?*
|
||||||
(quote-identifier x))))
|
(paren-wrap sql-str)
|
||||||
clojure.lang.Symbol
|
sql-str)))
|
||||||
(to-sql [x] (quote-identifier x))
|
|
||||||
java.lang.Boolean
|
(defn seq->sql [x]
|
||||||
(to-sql [x]
|
|
||||||
(if x "TRUE" "FALSE"))
|
|
||||||
clojure.lang.Sequential
|
|
||||||
(to-sql [x]
|
|
||||||
(if *fn-context?*
|
(if *fn-context?*
|
||||||
;; list argument in fn call
|
;; list argument in fn call
|
||||||
(paren-wrap (comma-join (map to-sql x)))
|
(paren-wrap (comma-join (map to-sql x)))
|
||||||
|
|
@ -307,6 +321,26 @@
|
||||||
(if (string? (second x))
|
(if (string? (second x))
|
||||||
(quote-identifier (second x))
|
(quote-identifier (second x))
|
||||||
(to-sql (second x))))))
|
(to-sql (second x))))))
|
||||||
|
|
||||||
|
(extend-protocol ToSql
|
||||||
|
#?(:clj clojure.lang.Keyword
|
||||||
|
:cljs cljs.core/Keyword)
|
||||||
|
(to-sql [x]
|
||||||
|
(let [s (name x)]
|
||||||
|
(case (.charAt s 0)
|
||||||
|
\% (let [call-args (string/split (subs s 1) #"\." 2)]
|
||||||
|
(to-sql (apply call (map keyword call-args))))
|
||||||
|
\? (to-sql (param (keyword (subs s 1))))
|
||||||
|
(quote-identifier x))))
|
||||||
|
#?(:clj clojure.lang.Symbol
|
||||||
|
:cljs cljs.core/Symbol)
|
||||||
|
(to-sql [x] (quote-identifier x))
|
||||||
|
#?(:clj java.lang.Boolean :cljs boolean)
|
||||||
|
(to-sql [x]
|
||||||
|
(if x "TRUE" "FALSE"))
|
||||||
|
#?@(:clj
|
||||||
|
[clojure.lang.Sequential
|
||||||
|
(to-sql [x] (seq->sql x))])
|
||||||
SqlCall
|
SqlCall
|
||||||
(to-sql [x]
|
(to-sql [x]
|
||||||
(binding [*fn-context?* true]
|
(binding [*fn-context?* true]
|
||||||
|
|
@ -315,18 +349,12 @@
|
||||||
(apply fn-handler fn-name (.-args x)))))
|
(apply fn-handler fn-name (.-args x)))))
|
||||||
SqlRaw
|
SqlRaw
|
||||||
(to-sql [x] (.-s x))
|
(to-sql [x] (.-s x))
|
||||||
clojure.lang.IPersistentMap
|
#?(:clj clojure.lang.IPersistentMap
|
||||||
|
:cljs cljs.core/PersistentArrayMap)
|
||||||
(to-sql [x]
|
(to-sql [x]
|
||||||
(let [clause-ops (sort-clauses (keys x))
|
(map->sql x))
|
||||||
sql-str (binding [*subquery?* true
|
#?(:clj clojure.lang.IPersistentSet
|
||||||
*fn-context?* false]
|
:cljs cljs.core/PersistentHashSet)
|
||||||
(space-join
|
|
||||||
(map (comp #(-format-clause % x) #(find x %))
|
|
||||||
clause-ops)))]
|
|
||||||
(if *subquery?*
|
|
||||||
(paren-wrap sql-str)
|
|
||||||
sql-str)))
|
|
||||||
clojure.lang.IPersistentSet
|
|
||||||
(to-sql [x]
|
(to-sql [x]
|
||||||
(to-sql (seq x)))
|
(to-sql (seq x)))
|
||||||
nil
|
nil
|
||||||
|
|
@ -342,9 +370,15 @@
|
||||||
SqlArray
|
SqlArray
|
||||||
(to-sql [x]
|
(to-sql [x]
|
||||||
(str "ARRAY[" (comma-join (map to-sql (.-values x))) "]"))
|
(str "ARRAY[" (comma-join (map to-sql (.-values x))) "]"))
|
||||||
Object
|
#?(:clj Object :cljs default)
|
||||||
(to-sql [x]
|
(to-sql [x]
|
||||||
(add-anon-param x)))
|
#?(:clj (add-anon-param x)
|
||||||
|
:cljs (if (sequential? x)
|
||||||
|
(seq->sql x)
|
||||||
|
(add-anon-param x))))
|
||||||
|
#?@(:cljs
|
||||||
|
[cljs.core/PersistentHashMap
|
||||||
|
(to-sql [x] (map->sql x))]))
|
||||||
|
|
||||||
(defn sqlable? [x]
|
(defn sqlable? [x]
|
||||||
(satisfies? ToSql x))
|
(satisfies? ToSql x))
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
(ns honeysql.helpers
|
(ns honeysql.helpers
|
||||||
(:refer-clojure :exclude [update]))
|
(:refer-clojure :exclude [update])
|
||||||
|
#?(:cljs (:require-macros [honeysql.helpers :refer [defhelper]])))
|
||||||
|
|
||||||
(defmulti build-clause (fn [name & args]
|
(defmulti build-clause (fn [name & args]
|
||||||
name))
|
name))
|
||||||
|
|
@ -10,20 +11,23 @@
|
||||||
(defn plain-map? [m]
|
(defn plain-map? [m]
|
||||||
(and
|
(and
|
||||||
(map? m)
|
(map? m)
|
||||||
(not (instance? clojure.lang.IRecord m))))
|
(not (record? m))))
|
||||||
|
|
||||||
(defmacro defhelper [helper arglist & more]
|
#?(:clj
|
||||||
|
(defmacro defhelper [helper arglist & more]
|
||||||
(let [kw (keyword (name helper))]
|
(let [kw (keyword (name helper))]
|
||||||
`(do
|
`(do
|
||||||
(defmethod build-clause ~kw ~(into ['_] arglist) ~@more)
|
(defmethod build-clause ~kw ~(into ['_] arglist) ~@more)
|
||||||
(doto (defn ~helper [& args#]
|
(defn ~helper [& args#]
|
||||||
(let [[m# args#] (if (plain-map? (first args#))
|
(let [[m# args#] (if (plain-map? (first args#))
|
||||||
[(first args#) (rest args#)]
|
[(first args#) (rest args#)]
|
||||||
[{} args#])]
|
[{} args#])]
|
||||||
(build-clause ~kw m# args#)))
|
(build-clause ~kw m# args#)))
|
||||||
|
|
||||||
;; maintain the original arglist instead of getting
|
;; maintain the original arglist instead of getting
|
||||||
;; ([& args__6880__auto__])
|
;; ([& args__6880__auto__])
|
||||||
(alter-meta!
|
(alter-meta!
|
||||||
|
(var ~helper)
|
||||||
assoc
|
assoc
|
||||||
:arglists
|
:arglists
|
||||||
'(~(into [] (rest arglist))
|
'(~(into [] (rest arglist))
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
(ns honeysql.types)
|
|
||||||
|
|
||||||
(defrecord SqlCall [name args])
|
|
||||||
|
|
||||||
(defn call
|
|
||||||
"Represents a SQL function call. Name should be a keyword."
|
|
||||||
[name & args]
|
|
||||||
(SqlCall. name args))
|
|
||||||
|
|
||||||
(defn read-sql-call [form]
|
|
||||||
;; late bind so that we get new class on REPL reset
|
|
||||||
(apply (resolve `call) form))
|
|
||||||
|
|
||||||
(defmethod print-method SqlCall [^SqlCall o ^java.io.Writer w]
|
|
||||||
(.write w (str "#sql/call " (pr-str (into [(.-name o)] (.-args o))))))
|
|
||||||
|
|
||||||
(defmethod print-dup SqlCall [o w]
|
|
||||||
(print-method o w))
|
|
||||||
|
|
||||||
;;;;
|
|
||||||
|
|
||||||
(defrecord SqlRaw [s])
|
|
||||||
|
|
||||||
(defn raw
|
|
||||||
"Represents a raw SQL string"
|
|
||||||
[s]
|
|
||||||
(SqlRaw. (str s)))
|
|
||||||
|
|
||||||
(defn read-sql-raw [form]
|
|
||||||
;; late bind, as above
|
|
||||||
((resolve `raw) form))
|
|
||||||
|
|
||||||
(defmethod print-method SqlRaw [^SqlRaw o ^java.io.Writer w]
|
|
||||||
(.write w (str "#sql/raw " (pr-str (.-s o)))))
|
|
||||||
|
|
||||||
(defmethod print-dup SqlRaw [o w]
|
|
||||||
(print-method o w))
|
|
||||||
|
|
||||||
;;;;
|
|
||||||
|
|
||||||
(defrecord SqlParam [name])
|
|
||||||
|
|
||||||
(defn param
|
|
||||||
"Represents a SQL parameter which can be filled in later"
|
|
||||||
[name]
|
|
||||||
(SqlParam. name))
|
|
||||||
|
|
||||||
(defn param-name [^SqlParam param]
|
|
||||||
(.-name param))
|
|
||||||
|
|
||||||
(defn read-sql-param [form]
|
|
||||||
;; late bind, as above
|
|
||||||
((resolve `param) form))
|
|
||||||
|
|
||||||
(defmethod print-method SqlParam [^SqlParam o ^java.io.Writer w]
|
|
||||||
(.write w (str "#sql/param " (pr-str (.-name o)))))
|
|
||||||
|
|
||||||
(defmethod print-dup SqlParam [o w]
|
|
||||||
(print-method o w))
|
|
||||||
|
|
||||||
;;;;
|
|
||||||
|
|
||||||
(defrecord SqlArray [values])
|
|
||||||
|
|
||||||
(defn array
|
|
||||||
"Represents a SQL array."
|
|
||||||
[values]
|
|
||||||
(SqlArray. values))
|
|
||||||
|
|
||||||
(defn array-vals [^SqlArray a]
|
|
||||||
(.-values a))
|
|
||||||
|
|
||||||
(defn read-sql-array [form]
|
|
||||||
;; late bind, as above
|
|
||||||
((resolve `array) form))
|
|
||||||
|
|
||||||
(defmethod print-method SqlArray [^SqlArray a ^java.io.Writer w]
|
|
||||||
(.write w (str "#sql/array " (pr-str (.-values a)))))
|
|
||||||
|
|
||||||
(defmethod print-dup SqlArray [a w]
|
|
||||||
(print-method a w))
|
|
||||||
84
src/honeysql/types.cljc
Normal file
84
src/honeysql/types.cljc
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
(ns honeysql.types
|
||||||
|
(:refer-clojure :exclude [array]))
|
||||||
|
|
||||||
|
(defrecord SqlCall [name args])
|
||||||
|
|
||||||
|
(defn call
|
||||||
|
"Represents a SQL function call. Name should be a keyword."
|
||||||
|
[name & args]
|
||||||
|
(SqlCall. name args))
|
||||||
|
|
||||||
|
(defn read-sql-call [form]
|
||||||
|
;; late bind so that we get new class on REPL reset
|
||||||
|
(apply #?(:clj (resolve `call) :cljs call) form))
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
|
||||||
|
(defrecord SqlRaw [s])
|
||||||
|
|
||||||
|
(defn raw
|
||||||
|
"Represents a raw SQL string"
|
||||||
|
[s]
|
||||||
|
(SqlRaw. (str s)))
|
||||||
|
|
||||||
|
(defn read-sql-raw [form]
|
||||||
|
;; late bind, as above
|
||||||
|
(#?(:clj (resolve `raw) :cljs raw) form))
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
|
||||||
|
(defrecord SqlParam [name])
|
||||||
|
|
||||||
|
(defn param
|
||||||
|
"Represents a SQL parameter which can be filled in later"
|
||||||
|
[name]
|
||||||
|
(SqlParam. name))
|
||||||
|
|
||||||
|
(defn param-name [^SqlParam param]
|
||||||
|
(.-name param))
|
||||||
|
|
||||||
|
(defn read-sql-param [form]
|
||||||
|
;; late bind, as above
|
||||||
|
(#?(:clj (resolve `param) :cljs param) form))
|
||||||
|
|
||||||
|
;;;;
|
||||||
|
|
||||||
|
(defrecord SqlArray [values])
|
||||||
|
|
||||||
|
(defn array
|
||||||
|
"Represents a SQL array."
|
||||||
|
[values]
|
||||||
|
(SqlArray. values))
|
||||||
|
|
||||||
|
(defn array-vals [^SqlArray a]
|
||||||
|
(.-values a))
|
||||||
|
|
||||||
|
(defn read-sql-array [form]
|
||||||
|
;; late bind, as above
|
||||||
|
(#?(:clj (resolve `array) :cljs array) form))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(do
|
||||||
|
(defmethod print-method SqlCall [^SqlCall o ^java.io.Writer w]
|
||||||
|
(.write w (str "#sql/call " (pr-str (into [(.-name o)] (.-args o))))))
|
||||||
|
|
||||||
|
(defmethod print-dup SqlCall [o w]
|
||||||
|
(print-method o w))
|
||||||
|
|
||||||
|
(defmethod print-method SqlRaw [^SqlRaw o ^java.io.Writer w]
|
||||||
|
(.write w (str "#sql/raw " (pr-str (.s o)))))
|
||||||
|
|
||||||
|
(defmethod print-dup SqlRaw [o w]
|
||||||
|
(print-method o w))
|
||||||
|
|
||||||
|
(defmethod print-method SqlParam [^SqlParam o ^java.io.Writer w]
|
||||||
|
(.write w (str "#sql/param " (pr-str (.name o)))))
|
||||||
|
|
||||||
|
(defmethod print-dup SqlParam [o w]
|
||||||
|
(print-method o w))
|
||||||
|
|
||||||
|
(defmethod print-method SqlArray [^SqlArray a ^java.io.Writer w]
|
||||||
|
(.write w (str "#sql/array " (pr-str (.values a)))))
|
||||||
|
|
||||||
|
(defmethod print-dup SqlArray [a w]
|
||||||
|
(print-method a w))))
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
(ns honeysql.core-test
|
(ns honeysql.core-test
|
||||||
(:refer-clojure :exclude [format update])
|
(:refer-clojure :exclude [format update])
|
||||||
(:require [clojure.test :refer [deftest testing is]]
|
(:require [#?@(:clj [clojure.test :refer]
|
||||||
|
:cljs [cljs.test :refer-macros]) [deftest testing is]]
|
||||||
[honeysql.core :as sql]
|
[honeysql.core :as sql]
|
||||||
[honeysql.helpers :refer :all]))
|
[honeysql.helpers :refer [select modifiers from join left-join
|
||||||
|
right-join full-join where group having
|
||||||
|
order-by limit offset values columns
|
||||||
|
insert-into]]
|
||||||
|
honeysql.format-test))
|
||||||
|
|
||||||
;; TODO: more tests
|
;; TODO: more tests
|
||||||
|
|
||||||
|
|
@ -55,8 +60,8 @@
|
||||||
(is (= ["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e FULL JOIN beck ON beck.x = c.y WHERE ((f.a = ? AND b.baz <> ?) OR (? < ? AND ? < ?) OR (f.e in (?, ?, ?)) OR f.e BETWEEN ? AND ?) GROUP BY f.a HAVING ? < f.e ORDER BY b.baz DESC, c.quux, f.a NULLS FIRST LIMIT ? OFFSET ? "
|
(is (= ["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e FULL JOIN beck ON beck.x = c.y WHERE ((f.a = ? AND b.baz <> ?) OR (? < ? AND ? < ?) OR (f.e in (?, ?, ?)) OR f.e BETWEEN ? AND ?) GROUP BY f.a HAVING ? < f.e ORDER BY b.baz DESC, c.quux, f.a NULLS FIRST LIMIT ? OFFSET ? "
|
||||||
"bort" "gabba" 1 2 2 3 1 2 3 10 20 0 50 10]
|
"bort" "gabba" 1 2 2 3 1 2 3 10 20 0 50 10]
|
||||||
(sql/format m1 {:param1 "gabba" :param2 2}))))
|
(sql/format m1 {:param1 "gabba" :param2 2}))))
|
||||||
(testing "SQL data prints and reads correctly"
|
#?(:clj (testing "SQL data prints and reads correctly"
|
||||||
(is (= m1 (read-string (pr-str m1)))))
|
(is (= m1 (read-string (pr-str m1))))))
|
||||||
(testing "SQL data formats correctly with alternate param naming"
|
(testing "SQL data formats correctly with alternate param naming"
|
||||||
(is (= (sql/format m1 :params {:param1 "gabba" :param2 2} :parameterizer :postgresql)
|
(is (= (sql/format m1 :params {:param1 "gabba" :param2 2} :parameterizer :postgresql)
|
||||||
["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e FULL JOIN beck ON beck.x = c.y WHERE ((f.a = $1 AND b.baz <> $2) OR ($3 < $4 AND $5 < $6) OR (f.e in ($7, $8, $9)) OR f.e BETWEEN $10 AND $11) GROUP BY f.a HAVING $12 < f.e ORDER BY b.baz DESC, c.quux, f.a NULLS FIRST LIMIT $13 OFFSET $14 "
|
["SELECT DISTINCT f.*, b.baz, c.quux, b.bla AS bla_bla, now(), @x := 10 FROM foo f, baz b INNER JOIN draq ON f.b = draq.x LEFT JOIN clod c ON f.a = c.d RIGHT JOIN bock ON bock.z = c.e FULL JOIN beck ON beck.x = c.y WHERE ((f.a = $1 AND b.baz <> $2) OR ($3 < $4 AND $5 < $6) OR (f.e in ($7, $8, $9)) OR f.e BETWEEN $10 AND $11) GROUP BY f.a HAVING $12 < f.e ORDER BY b.baz DESC, c.quux, f.a NULLS FIRST LIMIT $13 OFFSET $14 "
|
||||||
|
|
@ -174,3 +179,5 @@
|
||||||
(from :foo)
|
(from :foo)
|
||||||
(join :x [:= :foo.id :x.id] :y nil)
|
(join :x [:= :foo.id :x.id] :y nil)
|
||||||
sql/format)))))
|
sql/format)))))
|
||||||
|
|
||||||
|
#?(:cljs (cljs.test/run-all-tests))
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
(ns honeysql.format-test
|
(ns honeysql.format-test
|
||||||
(:refer-clojure :exclude [format])
|
(:refer-clojure :exclude [format])
|
||||||
(:require [clojure.test :refer [deftest testing is are]]
|
(:require [#?@(:clj [clojure.test :refer]
|
||||||
[honeysql.format :refer :all]))
|
:cljs [cljs.test :refer-macros]) [deftest testing is are]]
|
||||||
|
[honeysql.types :as sql]
|
||||||
|
[honeysql.format :refer
|
||||||
|
[*allow-dashed-names?* quote-identifier format-clause format]]))
|
||||||
|
|
||||||
(deftest test-quote
|
(deftest test-quote
|
||||||
(are
|
(are
|
||||||
|
|
@ -66,11 +69,11 @@
|
||||||
(deftest array-test
|
(deftest array-test
|
||||||
(is (= (format {:insert-into :foo
|
(is (= (format {:insert-into :foo
|
||||||
:columns [:baz]
|
:columns [:baz]
|
||||||
:values [[#sql/array [1 2 3 4]]]})
|
:values [[(sql/array [1 2 3 4])]]})
|
||||||
["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?, ?])" 1 2 3 4]))
|
["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?, ?])" 1 2 3 4]))
|
||||||
(is (= (format {:insert-into :foo
|
(is (= (format {:insert-into :foo
|
||||||
:columns [:baz]
|
:columns [:baz]
|
||||||
:values [[#sql/array ["one" "two" "three"]]]})
|
:values [[(sql/array ["one" "two" "three"])]]})
|
||||||
["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?])" "one" "two" "three"])))
|
["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?])" "one" "two" "three"])))
|
||||||
|
|
||||||
(deftest union-test
|
(deftest union-test
|
||||||
9
test/honeysql/test.cljs
Normal file
9
test/honeysql/test.cljs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
(ns honeysql.test
|
||||||
|
(:require
|
||||||
|
[doo.runner :refer-macros [doo-tests]]
|
||||||
|
[cljs.test :as t :refer-macros [is are deftest testing]]
|
||||||
|
honeysql.core-test
|
||||||
|
honeysql.format-test))
|
||||||
|
|
||||||
|
(doo-tests 'honeysql.core-test
|
||||||
|
'honeysql.format-test)
|
||||||
Loading…
Reference in a new issue