Skip to content

Instantly share code, notes, and snippets.

@kommen
Last active September 8, 2017 09:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kommen/a902e4c5bfef1395e69a617d1cb427ac to your computer and use it in GitHub Desktop.
Save kommen/a902e4c5bfef1395e69a617d1cb427ac to your computer and use it in GitHub Desktop.
Datomic schema
A profile handle needs to be unique, but the profile can be "owned" by either a person or a group.
schema1 makes it hard (impossible?) to validate with clojure.spec.
schema2 it would be possible to validate with a or in clojure.spec, but would have the drawback of not knowing by just looking at the profile` if it is owned by a group or a person.
Questions:
1) Which one is more idiomatic?
2) Is "this would be easier to validated with clojure.spec" a valid argument for datomic schema design
3) What to we gain though the profile entity indirection? :profile/handle could be an attribute on the person or group entity directly
4) When using the second approach, should we add an :profile/owner-type attribute which defines what :profile/owner references?
5) Should we consider isComponent for this?
;;
(def profile
[{:db/ident :profile/handle
:db/unique :db.unique/value
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :profile/website
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}])
(def person
[{:db/ident :person/email
:db/unique :db.unique/value
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :person/password-digest
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "bcrypt encoded"}
{:db/ident :person/profile
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one}])
(def group
[{:db/ident :group/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :group/profile
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one}
{:db/ident :group/member
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}])
(def profile
[{:db/ident :profile/handle
:db/unique :db.unique/value
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :profile/website
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :profile/owner
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one}])
(def person
[{:db/ident :person/email
:db/unique :db.unique/value
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :person/password-digest
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "bcrypt encoded"}])
(def group
[{:db/ident :group/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :group/member
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment