Skip to content

Instantly share code, notes, and snippets.

@vaughnd
Created September 12, 2012 10:40
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save vaughnd/3705861 to your computer and use it in GitHub Desktop.
Save vaughnd/3705861 to your computer and use it in GitHub Desktop.
Datomic user -> group memberships with extra data using many-to-many
(use '[datomic.api :only (q db) :as d])
(def uri "datomic:mem://user-groups3")
(d/create-database uri)
(def conn (d/connect uri))
(d/transact
conn
[{:db.install/_attribute :db.part/db
:db/id #db/id[:db.part/db]
:db/ident :user/name
:db/unique :db.unique/value
:db/index true
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db.install/_attribute :db.part/db
:db/id #db/id[:db.part/db]
:db/ident :group/name
:db/unique :db.unique/value
:db/index true
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db.install/_attribute :db.part/db
:db/id #db/id[:db.part/db]
:db/ident :user/memberships
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}
{:db.install/_attribute :db.part/db
:db/id #db/id[:db.part/db]
:db/ident :membership/group
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one}
{:db.install/_attribute :db.part/db
:db/id #db/id[:db.part/db]
:db/ident :membership/join-date
:db/valueType :db.type/instant
:db/cardinality :db.cardinality/one}
{:db.install/_attribute :db.part/db
:db/id #db/id[:db.part/db]
:db/ident :membership/league
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
])
(let [[chess-club tennis-club sally bob chris sally--chess-club bob--chess-club bob--tennis-club chris--tennis-club] (repeatedly #(d/tempid :db.part/user))]
(d/transact conn
[{:db/id chess-club :group/name "chess club"}
{:db/id tennis-club :group/name "tennis club"}
{:db/id sally :user/name "sally"}
{:db/id bob :user/name "bob"}
{:db/id chris :user/name "chris"}
{:db/id sally--chess-club :membership/group chess-club}
{:db/id bob--chess-club :membership/group chess-club}
{:db/id bob--tennis-club :membership/group tennis-club}
{:db/id chris--tennis-club :membership/group tennis-club}
{:db/id sally--chess-club :membership/join-date #inst "2012-10-01"}
{:db/id bob--chess-club :membership/join-date #inst "2011-10-01"}
{:db/id bob--tennis-club :membership/join-date #inst "2010-10-01"}
{:db/id chris--tennis-club :membership/join-date #inst "2009-10-01"}
{:db/id sally--chess-club :membership/league "junior"}
{:db/id bob--chess-club :membership/league "senior"}
{:db/id bob--tennis-club :membership/league "of awesome"}
{:db/id chris--tennis-club :membership/league "of extraordinary gentlemen"}
{:db/id sally :user/memberships [sally--chess-club]}
{:db/id bob :user/memberships [bob--chess-club bob--tennis-club]}
{:db/id chris :user/memberships [chris--tennis-club]}])
)
(q '[:find ?m :where [?m :user/name "sally"]] (db conn))
(q '[:find ?ml :where [?g :group/name "chess club"] [?mg :membership/group ?g] [?mg :membership/league ?ml]] (db conn))
;; get all usernames in chess club
(q '[:find ?un :where
[?g :group/name "chess club"]
[?mg :membership/group ?g]
[?u :user/memberships ?mg]
[?u :user/name ?un]] (db conn))
;; get all usernames and leagues in tennis club
(q '[:find ?un ?l :where
[?g :group/name "tennis club"]
[?mg :membership/group ?g]
[?u :user/memberships ?mg]
[?mg :membership/league ?l]
[?u :user/name ?un]] (db conn))
;; get all membership data for tennis club
(sort (q '[:find ?un ?ident ?v :where
[?g :group/name "tennis club"]
[?mg :membership/group ?g]
[?mg ?a ?v]
[?a :db/ident ?ident]
[(not= ?ident :membership/group)]
[?u :user/memberships ?mg]
[?u :user/name ?un]
] (db conn)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment