From 15feba7d6a437d89d179f67e392a84455fd92882 Mon Sep 17 00:00:00 2001 From: Timo Kramer Date: Tue, 18 Oct 2022 16:54:36 +0200 Subject: [PATCH] fixup! add first draft for the clerks notebooks --- deps.edn | 8 +-- dev/sandbox.clj | 8 ++- notebooks/crash_course.clj | 98 +++++++++++++++++++++++++++++++++++++ notebooks/minimal_start.clj | 85 -------------------------------- 4 files changed, 105 insertions(+), 94 deletions(-) create mode 100644 notebooks/crash_course.clj delete mode 100644 notebooks/minimal_start.clj diff --git a/deps.edn b/deps.edn index eb42819dc..aa02beb07 100644 --- a/deps.edn +++ b/deps.edn @@ -28,10 +28,10 @@ :extra-deps {org.clojure/tools.namespace {:mvn/version "1.2.0"} clj-http/clj-http {:mvn/version "3.12.3"} criterium/criterium {:mvn/version "0.4.6"} - org.clojure/tools.cli {:mvn/version "1.0.206"} - io.github.nextjournal/clerk {:mvn/version "0.8.451"} - incanter/incanter-core {:mvn/version "1.9.3"} - incanter/incanter-charts {:mvn/version "1.9.3"}}} + org.clojure/tools.cli {:mvn/version "1.0.206"} + io.github.nextjournal/clerk {:mvn/version "0.11.603"} + incanter/incanter-core {:mvn/version "1.9.3"} + incanter/incanter-charts {:mvn/version "1.9.3"}}} :test {:extra-paths ["test"] :extra-deps {lambdaisland/kaocha {:mvn/version "1.70.1086"} diff --git a/dev/sandbox.clj b/dev/sandbox.clj index 0c1acc700..7de38ec83 100644 --- a/dev/sandbox.clj +++ b/dev/sandbox.clj @@ -63,8 +63,6 @@ (:schema @conn) - - (d/transact conn (vec (repeatedly 5000 (fn [] {:age (long (rand-int 1000)) :name (str (rand-int 1000))})))) @@ -93,11 +91,11 @@ (clerk/clear-cache!) - (clerk/show! "notebooks/minimal_start.clj") + (clerk/show! "notebooks/crash_course.clj") (clerk/show! "notebooks/schema.clj") (clerk/show! "notebooks/store.clj") ;; there are race conditions somehwere when creating and deleting many dbs (clerk/show! "notebooks/time_travel.clj") - (clerk/show! "notebooks/time_variance.clj") + (clerk/show! "notebooks/time_variance.clj")) - ) + diff --git a/notebooks/crash_course.clj b/notebooks/crash_course.clj new file mode 100644 index 000000000..a60df4a33 --- /dev/null +++ b/notebooks/crash_course.clj @@ -0,0 +1,98 @@ +;; # Datahike Crash Course +(ns datahike.notebooks.crash-course + (:require [datahike.api :as d])) + +(def cfg {:store {:backend :file + :path "/tmp/example"}}) + +;; ## Create a database +;; Per default configuration we enforce a strict +;; schema and keep all historical data. +(when (d/database-exists? cfg) + (d/delete-database cfg)) + +(d/create-database cfg) + +;; ## Connect to database +(def conn (d/connect cfg)) + +(:config @conn) + +;; ## Transact data +;; The first transaction will be the schema we are using. +;; You may also add this within database creation by adding :initial-tx +;; to the configuration. +(d/transact conn [{:db/ident :name + :db/valueType :db.type/string + :db/cardinality :db.cardinality/one} + {:db/ident :age + :db/valueType :db.type/long + :db/cardinality :db.cardinality/one}]) + +;; You can take a look at your current schema. +(d/schema @conn) + +;; Lets add some data. +(def tx-report (d/transact conn [{:name "Alice", :age 20} + {:name "Bob", :age 30} + {:name "Charlie", :age 40} + {:age 15} + {:name "Daisy"}])) + +;; The transact-fn returns a transaction-report for you to inspect. +;; It's a map and the tx-data-key returns a vector of datoms in the form +;; `[entity-id attribute value transaction-id]`. +(:tx-data tx-report) + +;; ## Query the database. +(d/q '[:find ?entity-id ?name ?age + :where + [?entity-id :name ?name] + [?entity-id :age ?age]] + @conn) + +;; Update the entity with the entity-id 3 using a hash-map as argument. +;; Alice is now 25 years old instead of 20 +(d/transact conn {:tx-data [{:db/id 3 :age 25}]}) + +;; If you want to work with queries like in +;; https://grishaev.me/en/datomic-query/, +;; you can pass a hashmap to the query-fn like this. +(d/q {:query '{:find [?e ?n ?a] + :where [[?e :name ?n] + [?e :age ?a]]} + :args [@conn]}) + +;; Or you use the vector-format. +(d/q '[:find ?age + :where + [?entity-id :name "Alice"] + [?entity-id :age ?age]] + @conn) + +;; ## Query the history of the data +;; Just pass the db derived from the history-fn to the query. +;; You then receive the actual and the old value of Alice's age. +(d/q '[:find ?age + :where + [?entity-id :name "Alice"] + [?entity-id :age ?age]] + (d/history @conn)) + +;; ## Pull-API +;; For querying Datahike you can also use the pull-API. +;; With the pull-API you don't need to specify what data to query for, +;; you just pull all attributes of an entity with a wildcard. +(d/pull @conn '[*] 3) + +;; Or you limit your pull of an entity's data specifying the attributes. +(d/pull @conn '[:name :db/id] 3) + +(d/pull @conn '[*] 7) + +;; ## Cleaning up +;; You might need to release the connection for specific stores like leveldb. +(d/release conn) + +;; Delete the database if it is not needed any more. +(d/delete-database cfg) diff --git a/notebooks/minimal_start.clj b/notebooks/minimal_start.clj deleted file mode 100644 index 5d2f54277..000000000 --- a/notebooks/minimal_start.clj +++ /dev/null @@ -1,85 +0,0 @@ -(ns datahike.notebooks.minimal-start - (:require [datahike.api :as d])) - -(def cfg {:store {:backend :file - :path "/tmp/example"}}) - -;; create a database at this place, per default configuration we enforce a strict -;; schema and keep all historical data - -(when (d/database-exists? cfg) - (d/delete-database cfg)) - -(d/create-database cfg) - -(def conn (d/connect cfg)) - -(:config @conn) - -;; the first transaction will be the schema we are using -;; you may also add this within database creation by adding :initial-tx -;; to the configuration -(d/transact conn [{:db/ident :name - :db/valueType :db.type/string - :db/cardinality :db.cardinality/one} - {:db/ident :age - :db/valueType :db.type/long - :db/cardinality :db.cardinality/one}]) - -(d/schema @conn) - -;; lets add some data and wait for the transaction -(d/transact conn [{:name "Alice", :age 20 } - {:name "Bob", :age 30 } - {:name "Charlie", :age 40 } - {:age 15} - {:name "Daisy"}]) - -;; [entity-id attribute value transaction-id added?] -;; [Entity_ID Attribute Value] -;; [3 :name "Alice"] -;; [3 :age 20] - -;; search the data -(d/q '[:find ?entity-id ?name ?age - :where - [?entity-id :name ?name] - [?entity-id :age ?age]] - @conn) - -;; add new entity data using a hash map -(d/transact conn {:tx-data [{:db/id 3 :age 25}]}) - -;; if you want to work with queries like in -;; https://grishaev.me/en/datomic-query/, -;; you may use a hashmap -(d/q {:query '{:find [?e ?n ?a ] - :where [[?e :name ?n] - [?e :age ?a]]} - :args [@conn]}) - -(d/q '[:find ?age - :where - [?entity-id :name "Alice"] - [?entity-id :age ?age]] - @conn) - -;; query the history of the data -(d/q '[:find ?age - :where - [?entity-id :name "Alice"] - [?entity-id :age ?age]] - (d/history @conn)) - -;; pull API -(d/pull @conn '[*] 3) - -(d/pull @conn '[:name :db/id] 3) - -(d/pull @conn '[*] 7) - -;; you might need to release the connection for specific stores like leveldb -(d/release conn) - -;; clean up the database if it is not need any more -(d/delete-database cfg)