Addresses #283 on the v1 branch
This commit is contained in:
parent
06d90c174e
commit
b600348808
3 changed files with 42 additions and 40 deletions
|
|
@ -1,5 +1,8 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
* 2.0.0-alpha3 in progress
|
||||||
|
* Reconcile `where` behavior with recent 1.0 changes.
|
||||||
|
|
||||||
* 2.0.0-alpha2 (for early testing)
|
* 2.0.0-alpha2 (for early testing)
|
||||||
* Since Alpha 1, a lot more documentation has been written and docstrings have been added to most functions in `honey.sql.helpers`.
|
* Since Alpha 1, a lot more documentation has been written and docstrings have been added to most functions in `honey.sql.helpers`.
|
||||||
* Numerous small improvements have been made to clauses and helpers around insert/upsert.
|
* Numerous small improvements have been made to clauses and helpers around insert/upsert.
|
||||||
|
|
|
||||||
|
|
@ -11,47 +11,50 @@
|
||||||
(into (vec current) args))
|
(into (vec current) args))
|
||||||
|
|
||||||
(defn- and-merge
|
(defn- and-merge
|
||||||
"Recursively merge args into the current expression."
|
[current arg]
|
||||||
|
(if-let [conj' (and (sequential? arg) (#{:and :or} (first arg)))]
|
||||||
|
(cond (= conj' (first current))
|
||||||
|
(into (vec current) (rest arg))
|
||||||
|
(seq current)
|
||||||
|
(into [conj' current] (rest arg))
|
||||||
|
:else
|
||||||
|
(into [conj'] (rest arg)))
|
||||||
|
(cond (= :and (first current))
|
||||||
|
(conj (vec current) arg)
|
||||||
|
(seq current)
|
||||||
|
(conj [:and current] arg)
|
||||||
|
:else
|
||||||
|
(conj [:and] arg))))
|
||||||
|
|
||||||
|
(defn- and-merges
|
||||||
[current args]
|
[current args]
|
||||||
(let [args (remove nil? args)]
|
(let [args (remove nil? args)
|
||||||
(cond (= :and (first args))
|
result
|
||||||
(recur current [args])
|
(cond (keyword? (first args))
|
||||||
(= :or (first args))
|
(and-merges current [args])
|
||||||
(recur [:or current] (rest args))
|
(seq args)
|
||||||
:else
|
(let [[arg & args] args]
|
||||||
(let [arg (first args)
|
(and-merges (and-merge current arg) args))
|
||||||
conj-1 (#{:and :or} (first current))
|
:else
|
||||||
conj-2 (#{:and :or} (and (sequential? arg) (first arg)))]
|
current)]
|
||||||
(cond (empty? args)
|
(case (count result)
|
||||||
;; nothing more to merge:
|
0 nil
|
||||||
(vec current)
|
1 (if (sequential? (first result))(first result) result)
|
||||||
(and conj-1 conj-2 (= conj-1 conj-2))
|
2 (if (#{:and :or} (first result))
|
||||||
;; both conjunctions and they match:
|
(second result)
|
||||||
(recur (default-merge current (rest arg)) (rest args))
|
result)
|
||||||
(and conj-1 conj-2)
|
result)))
|
||||||
;; both conjunctions but they don't match:
|
|
||||||
(if (= :and conj-1)
|
|
||||||
(recur (default-merge current [arg]) (rest args))
|
|
||||||
(recur (default-merge [:and current] (rest arg)) (rest args)))
|
|
||||||
conj-1
|
|
||||||
;; current is conjunction; arg is not
|
|
||||||
(recur (default-merge (if (= :and conj-1) current [:and current]) [arg]) (rest args))
|
|
||||||
(and conj-2 (seq current))
|
|
||||||
;; arg is conjunction; current is not
|
|
||||||
(recur (default-merge [conj-2 current] (rest arg)) (rest args))
|
|
||||||
(seq current)
|
|
||||||
;; current non-empty; neither is a conjunction
|
|
||||||
(recur (default-merge [:and current] [arg]) (rest args))
|
|
||||||
:else ; current is empty; use arg as current
|
|
||||||
(recur (if (sequential? arg) arg [arg]) (rest args)))))))
|
|
||||||
|
|
||||||
(def ^:private special-merges
|
(def ^:private special-merges
|
||||||
{:where #'and-merge
|
{:where #'and-merges
|
||||||
:having #'and-merge})
|
:having #'and-merges})
|
||||||
|
|
||||||
(defn- helper-merge [data k args]
|
(defn- helper-merge [data k args]
|
||||||
(let [merge-fn (special-merges k default-merge)]
|
(if-let [merge-fn (special-merges k)]
|
||||||
(clojure.core/update data k merge-fn args)))
|
(if-let [clause (merge-fn (get data k) args)]
|
||||||
|
(assoc data k clause)
|
||||||
|
data)
|
||||||
|
(clojure.core/update data k default-merge args)))
|
||||||
|
|
||||||
(defn- generic [k args]
|
(defn- generic [k args]
|
||||||
(if (map? (first args))
|
(if (map? (first args))
|
||||||
|
|
|
||||||
|
|
@ -563,7 +563,3 @@
|
||||||
(f {k [:and [:a] [:b]]}
|
(f {k [:and [:a] [:b]]}
|
||||||
:or
|
:or
|
||||||
[:x] [:y]))))))))
|
[:x] [:y]))))))))
|
||||||
|
|
||||||
(comment
|
|
||||||
(where {:where [:and [:a] [:b]]} [:and [:x] [:y]])
|
|
||||||
.)
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue