Skip to content

Commit

Permalink
Add high-level helper for relaxing find
Browse files Browse the repository at this point in the history
  • Loading branch information
crisptrutski committed May 23, 2024
1 parent 5e7fe7b commit 99b50ab
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 27 deletions.
32 changes: 9 additions & 23 deletions src/macaw/rewrite.clj
Original file line number Diff line number Diff line change
Expand Up @@ -74,32 +74,18 @@

(defn- rename-table
[updated-nodes table-renames schema-renames known-tables ^Table t _ctx]
(let [table (-> (get known-tables t)
(select-keys [:table :schema]))]
(when-let [rename (or (find table-renames table)
(when (nil? (:schema table))
(u/seek #(= (:table table) (:table (key %))) table-renames)))]
(vswap! updated-nodes conj [t rename])
(.setName t (val rename)))
(when-let [schema-rename (find schema-renames (.getSchemaName t))]
(vswap! updated-nodes conj [(.getSchemaName t) schema-rename])
(.setSchemaName t (val schema-rename)))))
(when-let [rename (u/cascading-find table-renames (get known-tables t) [:table :schema])]
(vswap! updated-nodes conj [t rename])
(.setName t (val rename)))
(when-let [schema-rename (find schema-renames (.getSchemaName t))]
(vswap! updated-nodes conj [(.getSchemaName t) schema-rename])
(.setSchemaName t (val schema-rename))))

(defn- rename-column
[updated-nodes column-renames known-columns ^Column c _ctx]
(let [col (-> (get known-columns c)
(select-keys [:column :table :schema]))
rename (when col
(or (find column-renames col)
(when (nil? (:schema col))
(u/seek #(= (dissoc col :schema)
(dissoc (key %) :schema))
column-renames))
(when (nil? (:table col))
(u/seek #(= (:column col) (:column (key %))) column-renames))))]
(when rename
(vswap! updated-nodes conj [c rename])
(.setColumnName c (val rename)))))
(when-let [rename (u/cascading-find column-renames (get known-columns c) [:column :table :schema])]
(vswap! updated-nodes conj [c rename])
(.setColumnName c (val rename))))

(defn- alert-unused! [updated-nodes renames]
(let [known-rename? (set (map second updated-nodes))]
Expand Down
21 changes: 17 additions & 4 deletions src/macaw/util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,20 @@
"Like (first (filter ... )), but doesn't realize chunks of the sequence. Returns the first item in `coll` for which
`pred` returns a truthy value, or `nil` if no such item is found."
[pred coll]
(reduce
(fn [acc x] (if (pred x) (reduced x) acc))
nil
coll))
(some #(when (pred %) %) coll))

(defn cascading-find
"Search the given map for the entry corresponding to the given [[map-key]], considering only the given keys.
If no entry is found, recursively start ignoring the right-most key, until we're comparing only the first one."
[m map-key ks]
(when map-key
(if (every? map-key ks)
(find m (select-keys map-key ks))
;; Strip off keys from right-to-left where they are nil, and relax search to only consider these keys.
;; We need at least one non-generate key to remain for the search.
(when-let [ks-prefix (->> ks reverse (drop-while (comp nil? map-key)) reverse seq)]
(when (not= ks ks-prefix)
(seek (comp #{(select-keys map-key ks-prefix)}
#(select-keys % ks-prefix)
key)
m))))))
28 changes: 28 additions & 0 deletions test/macaw/util_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(ns macaw.util-test
(:require
[clojure.test :refer :all]
[macaw.util :as u]))

(def ^:private haystack
{{:a 3 :b 2 :c 1} 2
{:a 3 :b nil :c 1} 3
{:a 1 :b 2 :c 3} 1})

(deftest cascading-find-test
(testing "We ignore any suffix of degenerate keys"
(doseq [x [{:a 1}
{:a 1 :b 2}
{:a 1 :b 2 :c 3}
{:a 1 :b 2 :c 3 :d 4}]]
(is (= [{:a 1 :b 2 :c 3} 1]
(u/cascading-find haystack x [:a :b :c])))))

(testing "We need at least one non-degenerate key"
(is (nil? (u/cascading-find haystack {} [:a :b :c]))))

(testing "We don't ignore non-suffix degenerate keys"
(doseq [x [{:a nil :b 2}
{:a 1 :b nil :c 3}
{:a nil :b 2 :c 3}]]
(is (nil?
(u/cascading-find haystack x [:a :b :c]))))))

0 comments on commit 99b50ab

Please sign in to comment.