threatgrid / asami

A graph store for Clojure and ClojureScript
Eclipse Public License 1.0
637 stars 29 forks source link

Add transact time support for schemas #223

Open quoll opened 3 years ago

quoll commented 3 years ago

Asami is schema-less, but during transactions it can be useful to incorporate schema information. For instance:

(transact conn {:tx-data [{:db/ident "first" :data 1}]})
(transact conn {:tx-data [{:db/ident "first" :data 42}]
                :schema {:db/ident :data
                :db/cardinality :db/cardinality/one})

By indicating a cardinality of one, this is equivalent to using an update annotation on the :data attribute.

(entity conn "first")

{:data 42} Without the schema, this would have resulted in: {:data #{1 42}}

Also, data integrity can be checked:

(transact conn {:tx-data [{:db/ident "first" :data "forty-two"}]
                :schema {:db/ident :data
                         :db/valueType :db.type/long})

This would throw an ExceptionInfo, with a message like: Attribute :data cannot accept data: "forty-two". Requires Long value.

These changes will occur in asami.entities

quoll commented 3 years ago

A more important feature is:

(transact conn {:tx-data [{:db/ident "first" :data "forty-two" :sub {:data "sub-entity"}}])
(entity conn "first")

Result: {:data "forty-two" :sub {:data "sub-entity"}} (This is the current behavior)

An important new database function will be :db/retractEntity, and this relies on schema:

(transact conn {:tx-data [[:db/retractEntity [:db/ident "first"]]]
                :schema {:db/ident :sub
                         :db/valueType :db.type/ref
                         :db/isComponent true}})
(entity conn "first")

Result: nil

(q '[:find [?e ...] :where [?e :data ?d]] conn)

Result: () (Currently, removing the top level object will still leave the "sub-entity" object alone)