This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-01-06
Channels
- # announcements (18)
- # asami (3)
- # aws (10)
- # babashka (47)
- # beginners (343)
- # calva (36)
- # cider (4)
- # clojure (66)
- # clojure-europe (9)
- # clojure-nl (3)
- # clojure-uk (23)
- # clojurescript (30)
- # community-development (69)
- # conjure (1)
- # eastwood (9)
- # events (7)
- # fulcro (81)
- # graalvm (1)
- # malli (5)
- # meander (1)
- # off-topic (41)
- # pathom (15)
- # rdf (1)
- # reitit (6)
- # sci (57)
- # shadow-cljs (18)
- # spacemacs (4)
- # startup-in-a-month (1)
- # testing (2)
- # vim (1)
As part of the fun, I'm trying to write something similar to pull-syntax
with a meander
Let's say I have db
in this form.
{:ivan {:db/id :ivan, :name "Ivan" :last-name "Ivanov" :friend :petr}
:petr {:db/id :petr, :name "Petr" :last-name "Petrov" :friend :smith}
...
?id {:db/id ?id
?k ?v}}
(pull db [:name {:friend [:name]}] :ivan)
could be presented in this way
(m/find db
{?id {:name ?name
:friend ?friend}
?friend {:name ?friend-name}}
{:name ?name
:friend {:name ?friend-name}})
But how to make a function that would translate pull-syntax
to a meander's query?
For now I have something like that, but I can't do it any simpler and more elegant.
(def eid? (some-fn string? keyword? int?))
(defn pull [db selector entity]
(m/match selector
{:as ?q}
(reduce-kv
(fn [acc k v]
(m/match v
(m/pred vector?)
(assoc acc k (pull db v (get entity k)))))
{}
?q)
[!ks ...]
(reduce
(fn [acc elem]
(m/match elem
(m/pred eid?)
(assoc acc elem (get-in db [entity elem]))
{}
(let [entity' (get-in db [entity])]
(merge acc (pull db elem entity')))))
{}
!ks)))