Skip to content
Kristian Mandrup edited this page Feb 29, 2016 · 19 revisions

A brief API overview (WIP)

Setup

(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")})

Indexes

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] ]))]
  ))

Connect

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 }})]

Queries

For queries you can either use d/q or q/pull just like in Datomic.

Datalog queries in-depth: query and pull

d/q

;; 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]}))

d/pull

;; 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)))

Filter

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>"]}

Transactions

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...

Clone this wiki locally