-
-
Notifications
You must be signed in to change notification settings - Fork 311
API overview
The data model in both Datascript and Datomic is based around atomic facts called datoms. A datom is a 4-tuple consisting of:
- Entity ID
- Attribute
- Value
- Transaction ID
The Entity ID, Attribute and Value for each datom must be provided. The transaction ID is generated.
To use Datascript, first require the namespaces you need such as datascript.core
and datascript.db
etc.
Then optionally define your database schema and populate it with intial datoms using d/datom
as shown below.
(ns ds.core
(:require [datascript.core :as d]
[datascript.db :as db]))
;; define schema
(def schema { :aka { :db/cardinality :db.cardinality/many }})
;; populate db with initial datoms
(def datoms #{(d/datom 1 :age 17)
(d/datom 1 :name "Ivan")})
When you create the database, you can use :db/index
to create indexes for attributes, such as for age
in this example: { :age { :db/index true } }
. Then when you add atoms such as [:db/add 1 :age 44]
they will be indexed accordingly.
See index tests for more examples.
(deftest test-datom-index
(let [db (-> (d/empty-db { :age { :db/index true } })
(d/db-with [ [:db/add 1 :name "Petr"]
[:db/add 1 :age 44]
[:db/add 2 :name "Ivan"]
[:db/add 2 :age 25]
[:db/add 3 :name "Sergey"]
[:db/add 3 :age 11] ]))]
))
d/create-conn
can be used to create a connection to a DB (or schema).
Examples taken from conn tests where you can find more usage examples.
(deftest test-conn
(let [conn (d/create-conn)]
(deftest test-conn-schema
(let [conn (d/create-conn {:aka { :db/cardinality :db.cardinality/many }})]
Entities are identified using db/id
such as for the datom {:db/id 1, :name "Ivan"}
.
You can then get an entity by its identity, such as 1
using (d/entity db 1)
.
In the example below we store the entity in the local var e
and then test the name of the entity with
(is (= (:name e) "Ivan"))
See entity tests for more examples.
(deftest test-entity
(let [db (-> (d/empty-db)
(d/db-with [{:db/id 1, :name "Ivan", :age 19}
{:db/id 2, :name "Katerina", :sex "female"}]))
e (d/entity db 1)]
(is (= (:name e) "Ivan"))
For queries you can either use d/q
or q/pull
just like in Datomic.
Datalog queries in-depth: query and pull
;; query
(deftest test-joins
(let [db (-> (d/empty-db)
(d/db-with [ { :db/id 1, :name "Ivan", :age 15 }
{ :db/id 2, :name "Petr", :age 37 }
{ :db/id 3, :name "Ivan", :age 37 }
{ :db/id 4, :age 15 }]))]
(is (= (d/q '[:find ?e
:where [?e :name]] db)
#{[1] [2] [3]}))
;; define schema
(def ^:private test-schema
{:name { :db/valueType :db.type/string }})
;; datoms for DB
(def test-datoms
(->>
[[1 :name "Petr"]]))
;; initialize db with datoms and schema
(def ^:private test-db (d/init-db test-datoms test-schema))
(deftest test-pull-attr-spec
(is (= {:name "Petr"}
;; make a pull query from test-db
(d/pull test-db '[:name] 1)))
d/filter
can be used to filter a database, given a filter function such as remove-pass
or remove-ivan
as shown below.
(deftest test-filter-db
(let [db (-> (d/empty-db {:aka { :db/cardinality :db.cardinality/many }})
(d/db-with [{:db/id 1
:name "Petr"
:email "[email protected]"
:aka ["I" "Great"]
:password "<SECRET>"}
remove-pass (fn [_ datom] (not= :password (:a datom)))
remove-ivan (fn [_ datom] (not= 2 (:e datom)))
(d/filter db remove-pass) #{}
(d/filter db remove-ivan) #{["<SECRET>"] ["<UNKWOWN>"]}
d/transact!
is used to transact on a connection, such as adding new datoms via db/add
(deftest test-transact!
(let [conn (d/create-conn {:aka { :db/cardinality :db.cardinality/many }})]
(d/transact! conn [[:db/add 1 :name "Ivan"]])
More to follow...