Skip to content

Instantly share code, notes, and snippets.

@jonase
Created June 14, 2012 11:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jonase/2929737 to your computer and use it in GitHub Desktop.
Save jonase/2929737 to your computer and use it in GitHub Desktop.
(use '[datomic.api :only [db q] :as d])
;; DB setup
(def schema
[{:db/id #db/id[:db.part/db]
:db/ident :site/url
: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 :site/link
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}])
(def conn
(let [uri "datomic:mem://links"]
(d/delete-database uri)
(d/create-database uri)
(let [conn (d/connect uri)]
(d/transact conn schema)
conn)))
;; Generate data
(let [top-level-domains ["com" "org" "net"]
rand-char #(rand-nth (vec "abcdefghijklmnopqrstuvxyz"))
rand-string #(repeatedly (+ %1 (rand-int %2)) rand-char)
rand-url #(apply str (concat "http://"
(rand-string 5 8)
"."
(rand-nth top-level-domains)))
temp-ids (vec (repeatedly 10000 #(d/tempid :db.part/user)))
link-map (zipmap temp-ids
(repeatedly (fn []
(repeatedly (rand-int 10)
#(rand-nth temp-ids)))))
urls (zipmap temp-ids
(distinct
(concat ["http://datomic.com"
"http://clojure.org"]
(repeatedly rand-url))))
url-transactions (for [[eid url] urls]
[:db/add eid :site/url url])
link-transactions (for [[eid links] link-map]
(map #(vector :db/add eid :site/link %)
links))]
(d/transact conn (concat url-transactions
(apply concat link-transactions))))
;; Find sites that are linked from datomic.com
(q '[:find ?url
:where
[?from :site/url "http://datomic.com"]
[?from :site/link ?to]
[?to :site/url ?url]]
(db conn))
;; Find sites that link to clojure.org
(q '[:find ?url
:where
[?to :site/url "http://clojure.org"]
[?from :site/link ?to]
[?from :site/url ?url]]
(db conn))
;; The following four queries attempts to find sites that link to
;; themselves:
;; alt 1:
(q '[:find ?url
:where
[?from :site/link ?from]
[?from :site/url ?url]]
(db conn))
;; alt 2, Same as previous but the first constraint moved to a rule:
(q '[:find ?url
:in $ %
:where
[link ?link ?link]
[?link :site/url ?url]]
(db conn)
'[[(link ?from ?to)
[?from :site/link ?to]]])
;; alt 3:
(q '[:find ?url
:where
[?from :site/url ?url]
[?from :site/link ?to]
[?to :site/url ?url]]
(db conn))
;; alt 4, same as previous, but using a rule instead
(q '[:find ?url
:in $ %
:where [link ?url ?url]]
(db conn)
'[[(link ?from-url ?to-url)
[?from :site/url ?from-url]
[?from :site/link ?to]
[?to :site/url ?to-url]]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment