In datomic, is there a way to enforce that a relation be one-to-many as opposed to many-to-many? For example, setting :folder/files
to have :db.cardinality/many
does not prohibit the co-existence of [x :folder/file k]
and [y :folder/file k]
.
if i'm reading that correctly, then file k
can only exist in one :folder/files
relationship, correct?
you could put a :db.unique/value
constraints on :folder/files
(d/transact (client/get-conn)
{:tx-data [#:db{:ident :some/id
:valueType :db.type/string
:cardinality :db.cardinality/one
:unique :db.unique/identity}
#:db{:ident :folder/files
:valueType :db.type/ref
:cardinality :db.cardinality/many
:unique :db.unique/value}]})
here is a folder with two files:
(d/transact (client/get-conn)
{:tx-data [{:db/id "file1"
:some/id "file1"}
{:db/id "file2"
:some/id "file2"}
; file1 and file2 are part of folder1
{:db/id "folder1"
:some/id "folder1"
:folder/files ["file1" "file2"]}]})
=> Success
then adding file1
, which is already claimed by folder1
, throws an exception when adding it to a new folder2
:
(d/transact (client/get-conn)
{:tx-data [{:db/id "folder2"
:some/id "folder2"
:folder/files [{:some/id "file1"}]}]})
Execution error (ExceptionInfo) at datomic.client.api.async/ares (async.clj:58).
Unique conflict: :folder/files, value: 30570821298684032 already held by: 44692948645838978 asserted for: 69889357107953795