I need to learn Datalog and Datomic. A quick Youtube search found me this fantastic talk, by Norbert Wójtowicz, with which I can almost feel the needed knowledge start marching into my brain. Now I need to quickly get me a Datomic database to practice with!
A quick way to create a Datomic database, populate, and query it, is to follow the Datomic Getting Started guide. However, using Datomic Cloud for the first time, it takes a while before getting down to writing and reading stuff to and from the database. So here is an even quicker, almost zero-conf, alternative, using Datomic Free and a memory database.
I like to experiment with Clojure things in files in a REPL powered editor. Therefore this mini-guide starts like so:
1. Create a fresh project. I use Leiningen here. But I could have used whatever.
$ lein new datomic-shortcut
Open the project in your favorite Clojure editor and connect to the REPL.
From here on this is almost a replica of the Getting Started guide, but the API is a tad different than the client API used there, so I have made some slight adaptions.
2. Add dependency. This is the latest Datomic Free that I found on Clojars:
[com.datomic/datomic-free "0.9.5697"]
3. Require the Datomic API. The Leiningen project will have the file src/datomic_shortcut/core.clj
already created. Select all text in it and replace with this.
(ns datomic-shortcut.core
(:require [datomic.api :as d]))
4. Create the database and the connection. In order to not having to start a transactor or anything, we use a memory database.
(def db-uri "datomic:mem://foo")
(comment
(d/create-database db-uri)
(def conn (d/connect db-uri)))
I have ”hidden” all database touching things inside (comment ...)
forms so that I can load the file in the REPL w/o recreating the database and such. Just evaluate them one by one, top to bottom, regardless if they are inside a comment or not.
5. Add the movie schema to the database.
(def movie-schema [{:db/ident :movie/title
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "The title of the movie"}
{:db/ident :movie/genre
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "The genre of the movie"}
{:db/ident :movie/release-year
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/doc "The year the movie was released in theaters"}])
(comment
@(d/transact conn movie-schema)
;; => {:db-before ...,
;; ...}
)
6. Add some movies.
(def first-movies [{:movie/title "The Goonies"
:movie/genre "action/adventure"
:movie/release-year 1985}
{:movie/title "Commando"
:movie/genre "thriller/action"
:movie/release-year 1985}
{:movie/title "Repo Man"
:movie/genre "punk dystopia"
:movie/release-year 1984}])
(comment
@(d/transact conn first-movies)
;; => {:db-before ...,
;; ...}
)
7. Query the titles back out. I’m sorry that I can’t say anything about the query, I need to learn more Datalog first.
(def all-titles-q '[:find ?movie-title
:where
[_ :movie/title ?movie-title]])
(comment
(d/q all-titles-q (d/db conn))
;; => #{["Commando"] ["The Goonies"] ["Repo Man"]}
)
That’s it! Seven is the most magic number, as my youngest son often tells me. I will now spend some more time at this seventh step to get at least some of Norbert’s lesson to stick.