Fork me on GitHub
#datascript
<
2016-05-02
>
verma17:05:04

when transacting and entity which has a db.cardinality/many, it seems that the entities are only being added, and not removed, is that expected? example coming up

verma17:05:51

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

(def schema {:user/id {:db/unique :db.unique/identity}
             :user/name {}
             :user/buddies {:db/cardinality :db.cardinality/many}})

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

(d/transact! conn [{:user/id "1" :user/name "test"}
                   {:user/id "2" :user/name "what?"}
                   {:user/id "3" :user/name "hello"}
                   {:user/id "4" :user/name "when"}])

(:user/buddies (d/entity @conn [:user/id "1"])) ;; => nil

(d/transact! conn [{:user/id "1"
                    :user/buddies [[:user/id "2"]]}])

(:user/buddies (d/entity @conn [:user/id "1"])) ;; => #{[:user/id "2"]}

(d/transact! conn [{:user/id "1"
                    :user/buddies [[:user/id "3"]]}])

(:user/buddies (d/entity @conn [:user/id "1"])) ;; => #{[:user/id "3"] [:user/id "2"]}

verma17:05:11

the last statement, I am only expecting to see [:user/id 3]

verma17:05:15

I am not seeing any retracts for [:user/id "2"], is my expectation incorrect?

ckarlsen17:05:46

same behaviour as datomic

verma17:05:08

so I have to be more explicit about retracting

verma17:05:40

guess I could do something with db.fn

ckarlsen17:05:51

yes, could write your own tx function simple_smile

verma17:05:56

nice, thanks @ckarlsen , what are you expected to in such cases? .. other than writing your own tx, must be a general use case .. right?

verma17:05:20

diff the two sets and do :add/:retract ?

ckarlsen17:05:08

yeah thats usually what I have done (diff the sets)

verma17:05:22

ah ok simple_smile thanks :thumbsup:

verma17:05:48

I will try to write one and post here

verma18:05:53

@ckarlsen: this is what I came up with

(defn update-users [conn id new-users]
  (let [e (d/entity conn [:user/id id])

        new (set (map #(d/entity conn [:user/id %]) new-users))
        existing (:user/buddies e)

        joining (set/difference new existing)
        leaving (set/difference existing new)]

    (concat
     (map #(vector :db/add (:db/id e) :user/buddies (:db/id %)) joining)
     (map #(vector :db/retract (:db/id e) :user/buddies (:db/id %)) leaving))))

(defn set-users [id users]
  (d/transact! conn [[:db.fn/call update-users id users]]))

(set-users "1" ["3"])