datascript icon indicating copy to clipboard operation
datascript copied to clipboard

Lookup ref in composite tuple during upsert

Open telekid opened this issue 2 years ago • 1 comments

Back with another weird one. In the following example, I'd like to upsert an entity via composite tuple. One element of the composite tuple is a ref. At insertion time, I only know the natural identity (:db/uuid) of said referent, not its datascript :db/id.

It occurred to me that I may be able to supply a lookup ref as an element within a composite tuple that is being used for upsert, but it appears that is not the case.

Does this seem like a useful feature? Any suggested workarounds for its absence (that don't require multiple transactions?)

(ns core
  (:require [datascript.core :as d]))

(def schema
  {:db/uuid {:db/unique    :db.unique/identity}
   :user/db {:db/valueType :db.type/ref}
   :user/dbid {}
   :user/db+dbid {:db/valueType :db.type/tuple
                  :db/unique :db.unique/identity
                  :db/tupleAttrs [:user/db :user/dbid]}})

(def db (d/create-conn schema))

(d/transact!
 db
 [{:db/uuid "A"}
  {:user/db [:db/uuid "A"]
   :user/dbid 1}])

;; This transaction will fail
(d/transact!
 db            ;; |    BELOW   |
 [{:user/db+dbid [[:db/uuid "A"] 1] ;; This will work if you change `[:db/uuid "A"]` to `1`
   :user/name "jake"}])

;; Execution error (ClassCastException) at datascript.db/value-compare (db.cljc:387).
;; class clojure.lang.PersistentVector cannot be cast to class java.lang.Number

telekid avatar Jul 24 '23 19:07 telekid

Yes, seems useful

tonsky avatar Jul 30 '23 12:07 tonsky

Ran into this as well. Would fixing this require changing just validate-datom or is this more involved?

handerpeder avatar May 25 '24 20:05 handerpeder