Created
May 10, 2016 03:32
-
-
Save fasiha/2ab2c1cb203c26a2b63532831f1b6021 to your computer and use it in GitHub Desktop.
Learn Datalog Today ported to DataScript & Clojure (JVM)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Learn Datalog Today (http://www.learndatalogtoday.org) is a great resource for | |
; reading but its interactive query interface is broken. Below is how we can | |
; load the same data into a Clojure REPL and play with it using DataScript. | |
; After running the code below, many/most/all? of the queries on Learn Datalog | |
; Today should be functional. | |
; | |
; Create a new lein project, add `[datascript "0.15.0"]` to `project.clj`'s | |
; `dependencies`, run `lein deps && lein repl` and copy-paste the following in | |
; chunks, inspecting the outputs as needed. | |
(ns user.learn-datalog-today | |
(:require [datascript.core :as d] | |
[clojure.string :as string])) | |
; raw Github assets for schema and data | |
(def data-url "https://raw.githubusercontent.com/jonase/learndatalogtoday/master/resources/db/data.edn") | |
(def schema-url "https://raw.githubusercontent.com/jonase/learndatalogtoday/master/resources/db/schema.edn") | |
; download data, remove the things that offends DataScript, and parse | |
(def data | |
(-> data-url | |
slurp | |
(string/replace ,,, #"#db/id \[:db\.part/user ([-\d]+)\]" "$1") | |
read-string)) | |
; download schema & slice and dice it into the format DataScript wants | |
(def schema | |
(-> schema-url | |
slurp | |
; DataScript doesn't need :db/id in as attributes | |
(string/replace ,,, #":db/id #db/id \[:db\.part/db\]" "") | |
; it definitely doesn't need to install attributes | |
(string/replace ,,, #":db\.install/_attribute :db\.part/db" "") | |
; it doesn't like being told about any value types other than refs | |
(string/replace ,,, #":db/valueType :db\.type/(string|long|instant)" "") | |
read-string | |
; instead of a vector of schemas, DataScript wants a nested map | |
(->> ,,, | |
(map (fn [{ident :db/ident :as schema}] | |
(let [others (dissoc schema :db/ident)] | |
{ident others})) | |
,,,) | |
(apply merge ,,,)))) | |
; create a DataScript db using the schema and dump the data into it | |
(def conn (d/create-conn schema)) | |
(d/transact! conn data) | |
; try a query | |
(d/q '[:find ?title | |
:where | |
[_ :movie/title ?title]] | |
@conn) | |
; #{["First Blood"] ["Terminator 2: Judgment Day"] ["The Terminator"] … | |
(d/q '[:find ?e | |
:where | |
[?e :person/name "Ridley Scott"]] | |
@conn) | |
; #{[38]} | |
(d/q '[:find ?title | |
:where | |
[?e :movie/title ?title] | |
[?e :movie/year 1987]] | |
@conn) | |
; #{["Lethal Weapon"] ["RoboCop"] ["Predator"]} | |
(d/q '[:find ?name | |
:where | |
[?m :movie/title "Lethal Weapon"] | |
[?m :movie/cast ?p] | |
[?p :person/name ?name]] | |
@conn) | |
; #{["Danny Glover"] ["Gary Busey"] ["Mel Gibson"]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment