Skip to content

Instantly share code, notes, and snippets.

@dustingetz
Last active December 12, 2018 08:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustingetz/cfd6882e2acae6e8b48759ec24c4de0a to your computer and use it in GitHub Desktop.
Save dustingetz/cfd6882e2acae6e8b48759ec24c4de0a to your computer and use it in GitHub Desktop.

This is a thought experiment, obviously this is not real datomic!

Why do this? I think it would cancel out data transformation boilerplate currently needed to do something like this.

(defn user-uuid-to-user [user-uuid]
  (d/q [:in $ ?user-uuid
        :find ?user .                          ; no pull here, bind it later
        :where [?user :user/uuid ?user-uuid]]
       *$* user-uuid))

(d/pull $ [:domain/ident
           {:hyperfiddle/owners                ; :many :uuid
            [{user-uuid-to-user                ; a fn that navs deeper, takes uuid as input
              [:user/name                      ; now we can pull deeper as if the relation was a ref
               :user/email]}]}]
        [:domain/ident "tank"])

Someone who understands rules can probably make this simpler.

@comnik
Copy link

comnik commented Dec 11, 2018

FWIW this is how you might express the uuid<->user relation with rules (but it doesn't add much in this case):

(def rules
  [[(uuid ?user ?uuid)] [?user :user/uuid ?uuid]])

(d/q
  '[:find ?user
    :in $ % ?user-uuid
    :where (uuid ?user ?user-uuid)] 
  *$* rules user-uuid)

But yeah so right now I think Datomic can't do any kind of filtering within pull. You'd have to re-write as something like:

(d/q
  '[:find (pull ?owner [:user/name :user/email])
     :in ...
     :where 
     [?domain :domain/ident "tank"]
     [?domain :hyperfiddle/owners ?user]
     (uuid ?user ?user-uuid)]
  *$* rules user-uuid)

etc...

In PullQL we'd write this as

[[:domain/ident "tank"]
  {:hyperfiddle/owners
   [[:user/uuid <target-uuid>]
     :user/name
     :user/email]}]

We don't do query caching / inputs yet, but that's the idea. But in any case I think it makes sense to have something like that, yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment