[How-To] Using UUIDs in XTDB Transactions

I needed to be able to submit documents to XTDB with UUIDs and have a guarantee that they wouldn’t collide so I came up with the following macro:

(defmacro submit-tx-with-uuid
  "Adds a uuid as :xt/id to the `tx-map` and submits it to `node`.

  Will check wether the uuid is already in use with ::xt/match and return the new entity if successful."
  {:style/indent 1}
  [node tx-map]
  `(loop []
     (let [uuid# (random-uuid)
           entity# (xt/entity (xt/db ~node) uuid#)]
       (if (and (empty? entity#)
                (xt/tx-committed?
                 ~node
                 (xt/await-tx
                  ~node
                  (xt/submit-tx
                   ~node
                   [[::xt/match
                     uuid# nil]
                    [::xt/put
                     (assoc ~tx-map :xt/id uuid#)]]))))
         (xt/entity (xt/db ~node) uuid#)
         (recur)))))

;; Usage Example
(comment
  (submit-tx-with-uuid <your node here>
    {:test/a 3
     :type :test})
  *e)

Hope somebody finds it useful :slight_smile:

Edit:
If you’re not on Clojure 1.11 yet, you’ll need to replace (random-uuid) with (java.util.UUID/randomUUID).

1 Like