Fork me on GitHub
#datomic
<
2019-12-25
>
Chris O’Donnell04:12:28

Is it possible to host multiple ion applications in the same (solo) topology? Use case: I have a tiny personal project where I'd like to have staging and production applications with distinct configuration, and I don't anticipate there will be sufficient traffic to put any kind of tax on a single solo topology setup. Paying for another stack would be cost-prohibitive in this case. I'm open to other ways of accomplishing this, as well.

steveb8n04:12:03

it would be tricky. you can create >1 databases with solo so you could keep data separate. the problem is code, I can’t think of a way to have > 1 version of code running in solo unless you do some crazy namespace duplication tricks.

steveb8n04:12:59

best bet is run 2 solo stacks and shut them down when you aren’t using them to save $. shutdown is simple, just set the ALB to zero instances and then 1 when you want to bring it back up

Chris O’Donnell04:12:59

Good point; I had not thought this all the way through. I may just not have a staging environment at all, since a bit of downtime won't be the end of the world in this case and rollback is not hard.

Chris O’Donnell18:12:07

I'd love some help building a query in the right way. I'm trying to add some authorization logic into my datomic queries. A slightly simplified example of what I'm trying to do is to allow a user to view their own attributes and also to view the attributes of other users which have granted them access. My initial attempt looks like this:

(d/q '{:find [(pull ?u [::user/name])]
       :in [$ ?requester-id ?id]
       :where [(or
                 (and
                   [?u ::user/id ?id]
                   [?u ::user/id ?requester-id])
                 (and
                   [?u ::user/id ?id]
                   [?requester ::user/id ?requester-id]
                   [?grant :view-grant/grantor ?u]
                   [?grant :view-grant/grantee ?requester]))]}
  (get-db) (java.util.UUID/randomUUID) (java.util.UUID/randomUUID))
However, this doesn't work because each clause in an or expression is required to bind the same set of variables. I can get around this by making two separate queries and combining their results, but the code is more complicated. Is there a reasonable way to do this in one query?

timcreasy18:12:20

Have you ever looked at Datomic Rules? Can use multiple rule heads for logical OR and have different bindings in each head. Can’t link to section on Rules on mobile, but it can be found here: https://docs.datomic.com/cloud/query/query-data-reference.html

Chris O’Donnell18:12:01

I will probably end up writing a rule for this later, thanks! For now I will use or-join until I know enough to build the right abstraction.

Chris O’Donnell18:12:06

Figured it out. 🙂 I needed to use or-join to specify which variables should be unified outside of the or. Corrected query in thread.

Chris O’Donnell18:12:46

The corrected query for the benefit of anyone else who has the same question and sees this:

(d/q '{:find [(pull ?u [::user/id])]
       :in [$ ?requester-id ?id]
       :where [(or-join [?u ?requester-id ?id]
                 (and
                   [?u ::user/id ?id]
                   [?u ::user/id ?requester-id])
                 (and
                   [?u ::user/id ?id]
                   [?requester ::user/id ?requester-id]
                   [?grant :view-grant/grantor ?u]
                   [?grant :view-grant/grantee ?requester]))]}
  (get-db) (java.util.UUID/randomUUID) (java.util.UUID/randomUUID))