Skip to content

Instantly share code, notes, and snippets.

@refset
Forked from comnik/relational-helpers.clj
Created January 2, 2023 16:35
Show Gist options
  • Save refset/a45ad60acd72aff6c45c9f8d65e1522a to your computer and use it in GitHub Desktop.
Save refset/a45ad60acd72aff6c45c9f8d65e1522a to your computer and use it in GitHub Desktop.
(defn relate [& pairs]
(assert (even? (count pairs)) "relate requires an even number of arguments")
(->> pairs
(partition 2)
(map (fn [[k vs]] (map #(hash-map k %) vs)))
(apply map merge)))
(defn matches-specmap? [specmap m]
(reduce-kv
(fn [_ k spec]
(if (s/valid? spec (get m k))
true
(reduced false)))
true
specmap))
(defn where
"Returns a set of the elements conforming to the given spec-map."
([specmap]
(filter (partial matches-specmap? specmap)))
([specmap xset]
(filter (partial matches-specmap? specmap) xset)))
(defn derive
"Maps a tuple operation over the relation, associng the result as a new attribute."
([dest-attr f]
(map (fn [tuple] (assoc tuple dest-attr (apply f [tuple])))))
([dest-attr f xrel & args]
(->> xrel
(map (fn [tuple] (assoc tuple dest-attr (apply f tuple args))))
(into #{}))))
(defn derive-k
"Corresponds to SELECT F(key, key2, ...)"
([dest-attr f ks]
(map (fn [tuple]
(let [param-fn (apply juxt ks)
;; @TODO combine juxt with flatten? then a single key-fn may return more than one paramater
params (param-fn tuple)]
(assoc tuple dest-attr (apply f params))))))
([dest-attr f ks xrel]
(into #{} (derive-k dest-attr f ks) xrel)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment