Skip to content
bmillare edited this page Feb 1, 2013 · 17 revisions

If you want to connect with to remote database with ssh, be sure to forward 3 ports (e.g. 4334, 4335, and 4336).

(require '[datomic.api :as d])

(def uri "datomic:free://localhost:4334/test")
(d/create-database uri)
(def conn (d/connect uri))

Basics

Transactions

At transaction is a set of transaction statements. Where statements can be an addition or retraction of a fact, or an invocation of a data function.

[:db/add entity-id attribute value]
[:db/retract entity-id attribute value]
[data-fn args*]

A hashmap is a concise alternative to specify one or more :db/add operations.

{:db/id entity-id
attribute value
attribute value
...}

To make a transaction to the database, call transact.

Example: (Note a set is represented as a vector in this case)

(d/transact conn [{:db/id #db/id[:mygroup]
                   :somenamespace/someattribute "some value"
                   :mygroup/age 37}])

entity-id can be a temporary id, an existing id already in the database, or an identifier for an entity already in the database. A temporary id gets resolved to an actual id when the transaction is processed. "identifiers" are basically keywords that function as an alias to the actual entity. This is used for attribute, partitions, etc entities. :db/ident attribute allows you to assign a keyword identifier to a given entity.

literal representation of temp-id

#db/id[partition-name value*]

Special function [:db.fn/retractEntity entity-id]

For more details see http://docs.datomic.com/transactions.html

Querying

You will need to get an instance of the db from the connection.

(d/q '{:find [?id] :where [[?id :attribute :value]]} (d/db conn))

Defining attributes

In datomic, a schema must be specified for all existing attributes. A schema is merely a set of datums for each attribute. We must have preexisting attributes to do this.

Required attributes about attributes

:db/ident name of attribute as a keyword :<namespace.namespace...>/

:db/valueType can be: :db.type/[keyword, string, boolean, long, bigint, float, double, bigdec, ref, instant, uuid, uri, bytes]

:db/cardinality :db.cardinality/[one many]

Optional

:db/doc :db/unique -> :db.unique/[value identity nil] :db/index :db/fulltext :db/isComponent :db/noHistory

Installing an attribute

  1. create attribute entity
  2. associate attribute entity with the built-in database partition entity :db.part/db. We can do this with sugar using the reverse reference mechanism.
(d/transact conn [{:db.install/_attribute :db.part/db
                   :db/id #db/id[:db.part/db]
                   :db/ident :person/name
                   :db/valueType :db.type/string
                   :db/cardinality :db.cardinality/one
                   :db/doc "A person's name"}])

Note that for installing attributes (and also partitions), I recommend you put the :db.install/... attribute first, as this makes it feel like a function call and will reduce the rate of keyboard errors as its the first on the list.

Partitions

Builtin Partitions :db.part/db system entities and schema definitions :db.part/tx transactions partitions :db.part/user experimentation

[{:db.install/_partition :db.part/db
  :db/id #db/id[:db.part/db],
  :db/ident :communities}]

Typical Patterns for Schemas

  • You can use namespaces to associate an attribute with a particular partition. So for example, you can create the partition :person, and then create the attribute :person/age.

Clone this wiki locally