Fork me on GitHub
#datomic
<
2017-12-15
>
david_clojurian12:12:11

Hello, I'm looking for a way to query an entity that is tagged as :db.unique/value. This value exists only once in the database and I hope I can query it without knowing the attribute name. In this example I only like to query it by an UUID, but I don't know whether it is a :one/v1 or a :another/v2. I tried to lookup it by [#uuid "59bbb1bb-7827-41e2-b213-db1d58ed9661"], but this doesn't work. Is it possible to lookup by a db.unique/value without an attribute name?

souenzzo12:12:52

(d/q '[:find ?e :in $ ?v :where [?attr :db/ident] [?e ?attr ?v]] db my-uuid)

souenzzo12:12:44

You can do [?attr :db/unique :db.unique/value] or something like for optimal performance.

david_clojurian13:12:52

Thanks for the response. I will try it.

souenzzo14:12:07

sometimes skip full scan is tricky 😄

david_clojurian14:12:29

I changed it a little bit and now it works for me.

(query '[:find ?ident-key ?uuid
               :in $ ?uuid
               :where
               [?attr :db/unique :db.unique/value]
               [?e ?attr ?uuid]
               [?attr :db/ident ?ident-key]]
             [db uuid])

favila16:12:10

it does not

eraserhd16:12:03

Is there a way to get the tx from the db?

favila16:12:30

use a tx tempid

favila16:12:48

string "datomic.tx" or (d/tempid :db.part/tx)

favila16:12:20

there's no way to predict what it will be

favila16:12:32

its value depends on how many entities were "created" by the transaction you want

favila16:12:56

there is one autoincrement id for an entire datomic db

eraserhd16:12:36

My goal is to prevent the transaction of data which would violate some user-specified constraints.

favila16:12:39

you need to test your constraint and throw after the transaction is applied

eraserhd16:12:57

There's no way to back out a transaction, correct?

favila16:12:16

no foolproof way, no

favila16:12:48

you can do this in a locking manner or with optimistic concurrency

favila16:12:52

the locking is simpler

eraserhd16:12:01

How would one do locking?

favila16:12:35

make a transaction function which takes the entire transaction you want to run

favila16:12:28

the body of the transaction should apply the transaction with d/with to the supplied db, then run validation. if validation fails, it should throw; otherwise it should return the transaction unchanged

favila16:12:51

the optimistic version just does the same thing, but in the peer

favila16:12:30

and adds extra precondition checks to the submitted transaction to make sure nothing important changed by the time the transaction reached the transactor

favila16:12:48

presumably the peer would retry

eraserhd16:12:49

So the original TX becomes something like, [:db.fn/doAndCheck [[:db/add ...] [:db.fn/retractEntity ...]]]]

favila16:12:38

the transactor is the only writer, so you are essentially locking the db while doAndCheck runs

favila16:12:44

(write-locking)

favila16:12:21

so there's no possibility of funny business. the db your tx fn receives is absolutely the prior db, and the tx you return will absolutely be applied against that one

eraserhd16:12:32

Will d/with run functions like retractEntity?

favila16:12:33

if you do it in the peer, you don't have that guarantee

favila16:12:23

d/with is exactly the same

favila16:12:35

it does everything d/transact can do

favila16:12:49

except it doesn't write

eraserhd16:12:58

OK, cool. I think I have a solution, then.

lellis19:12:43

Hi guys! I know datomic has an Datom's max size, suppose i reach the maximum size. My question is: Excision datoms will make smaller the occuped size?