Skip to content

Instantly share code, notes, and snippets.

@sc13-bioinf
Created March 22, 2017 07:39
Show Gist options
  • Save sc13-bioinf/415b5bfd36b27d3a19b7f0d2ca88acda to your computer and use it in GitHub Desktop.
Save sc13-bioinf/415b5bfd36b27d3a19b7f0d2ca88acda to your computer and use it in GitHub Desktop.
The aim is to be able to use om.next/set-query! with datascript. I store the query for each component as a new index ':tree-path->query'.
tree-path->query: {
"de$mpg$shh$lims$ui$components$dynamic_query_test$RootView_[]" {
:query [{:app/root [:db/id {:app.root/trunk "de$mpg$shh$lims$ui$components$dynamic_query_test$TrunkView_[]"} {:app.root/another "de$mpg$shh$lims$ui$components$dynamic_query_test$AnotherView_[]"}]}]},
"de$mpg$shh$lims$ui$components$dynamic_query_test$TrunkView_[]" {
:query [:db/id :app.root.trunk/text-one {:app.root.trunk/branches ["de$mpg$shh$lims$ui$components$dynamic_query_test$BranchView_[:app/root :app.root/trunk :app.root.trunk/branches 0]" "de$mpg$shh$lims$ui$components$dynamic_query_test$BranchView_[:app/root :app.root/trunk :app.root.trunk/branches 1]"]}]},
"de$mpg$shh$lims$ui$components$dynamic_query_test$AnotherView_[]" {
:query [:db/id :app.root.another/text]},
"de$mpg$shh$lims$ui$components$dynamic_query_test$BranchView_[:app/root :app.root/trunk :app.root.trunk/branches 0]" {
:query [:db/id :app.root.trunk.branch/text :app.root.trunk.branch/leaves {:autumn [*]}],
:parent "de$mpg$shh$lims$ui$components$dynamic_query_test$TrunkView_[]"},
"foobar" {
:query [:text],
:parent "de$mpg$shh$lims$ui$components$dynamic_query_test$BranchView_[:app/root :app.root/trunk :app.root.trunk/branches 0]"},
"de$mpg$shh$lims$ui$components$dynamic_query_test$BranchView_[:app/root :app.root/trunk :app.root.trunk/branches 1]" {
:query [:db/id :app.root.trunk.branch/text :app.root.trunk.branch/leaves],
:parent "de$mpg$shh$lims$ui$components$dynamic_query_test$TrunkView_[]"}}
This allows me to return a query like so:
read :app/root query: [:db/id {:app.root/trunk [:db/id :app.root.trunk/text-one {:app.root.trunk/branches [[:db/id :app.root.trunk.branch/text :app.root.trunk.branch/leaves {:autumn [*]}] [:db/id :app.root.trunk.branch/text :app.root.trunk.branch/leaves]]}]} {:app.root/another [:db/id :app.root.another/text]}]
Note that there are now two different queries for the attr :app.root.trunk/branches
[[:db/id :app.root.trunk.branch/text :app.root.trunk.branch/leaves {:autumn [*]}]
[:db/id :app.root.trunk.branch/text :app.root.trunk.branch/leaves]]
We need a custom resolver to walk the returned pull pattern as I cannot query datascript for more than one of the patterns above.
(defn attr-selector?
[attr selector]
(and (map? selector)
(= attr (ffirst selector))))
;; The selector may now contain sub-selectors
(defn super-resolve-query
[state e-id selector]
(let [level-selector (vec (for [attr selector]
(cond
(map? attr) {(ffirst attr) [:db/id]}
:else attr)))
level-data (d/pull (d/db state) level-selector e-id)]
(into {} (for [[attr v] level-data]
(let [attr-schema (get (:schema @state) attr)]
(cond
(and (= (:db/valueType attr-schema) :db.type/ref)
(= (:db/cardinality attr-schema) :db.cardinality/many))
(let [attr-selector (first (filter (partial attr-selector? attr) selector))]
[attr (vec (for [[sub-i sub-v] (map-indexed vector v)]
(if (every? vector? (get attr-selector attr))
(super-resolve-query state (:db/id sub-v) (get-in attr-selector [attr sub-i]))
(super-resolve-query state (:db/id sub-v) (get attr-selector attr)))))])
(= (:db/valueType attr-schema) :db.type/ref)
(let [attr-selector (first (filter (partial attr-selector? attr) selector))]
[attr (super-resolve-query state (:db/id v) (get attr-selector attr))])
:else [attr v]))))))
Issues:
How should this work with om.next/full-query work?
Is this the right approach?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment