«

Log API

Datomic's database log is a recording of all transaction data in historic order, organized for efficient access by transaction.

Client Tx-Range

You can access the log via the tx-range API function.

(d/tx-range conn {:start 1000 :end 1020})

The arguments are startT (inclusive), and endT (exclusive). Legal values for these arguments are:

  • Txes (transaction entity ids)
  • Ts (as e.g. returned from Database.nextT)
  • Transaction instants (java.util.Dates)
  • Nil (to represent the beginning/end of the log)

Tx-range returns a collection of transactions, each of which contains key/value pairs:

Keyword Value
:t The transaction t
:data A collection of datoms

The datoms implement the datomic.Datom interface. In Clojure, they act as both sequential and associative collections, and can be destructured accordingly.

Peer (d/log) and (d/tx-range)

(d/log) returns an immutable log value.

(d/log conn)
=> #datomic.log.LogValue{:db datomic.db.Db@b4f7bc6f, :olookup #object[datomic.cache$lookup_cache$reify__12495 0x21ff3fe3 "datomic.cache$lookup_cache$reify__12495@21ff3fe3"], :root-id #uuid "6643ba96-0cc9-46fd-8390-21b5e6001fd9", :tail #datomic.db.MemLog{:txes []}}

Given a log, you can retrieve an Iterable over a range in the log with tx-range:

(d/tx-range log 1000 1020)
=> #object[datomic.log$tx_range$reify__15766 0x614504c7 "datomic.log$tx_range$reify__15766@614504c7"]

The arguments are startT (inclusive), and endT (exclusive). Legal values for these arguments are:

  • Txes: transaction entity ids
  • Ts: as e.g. returned from Database.nextT
  • Transaction instants: java.util.Dates
  • Null: to represent the beginning/end of the log

Each map represents a single transaction and contains two key/value pairs:

Keyword Value
:t The transaction t
:data A collection of datoms

The datoms implement the (d/datoms) interface. In Clojure, they act as both sequential and associative collections, and can be destructured accordingly.

Log in Query: tx-ids and tx-data

The log API includes two convenience functions that are available within the query. The tx-ids function takes arguments similar to txRange above, but returns a collection of transaction entity ids. You will typically use the collection binding form [?tx …] to capture the results:

[(tx-ids ?log ?t1 ?tx) [?tx ...]]

The following example query returns the count of transactions within the range [t1, t2):

(d/q '[:find (count ?tx)
       :in $ ?log ?t1 ?t2
       :where [(tx-ids ?log ?t1 ?t2) [?tx ...]]]
     (d/db conn) (d/log conn) t1 t2)

The tx-data function returns the datoms associated with a particular t or tx. You will typically use the relation binding form [ [?e ?a ?v _ ?op ] ] to capture the results:

[(tx-data ?log ?tx) [[?e ?a ?v _ ?op]]]

Note the underscore binding. You should not bind the ?tx position, as ?tx is already bound on input to the function.

tx-data is the efficient way to get transaction data given t or tx. A common scenario is to use tx-data in combination with tx-ids, to return the datoms associated with a range in time. The following example query returns all the entities that were modified on August 1, 2013:

(d/q '[:find ?e
       :in $ ?log ?t1 ?t2
       :where [(tx-ids ?log ?t1 ?t2) [?tx ...]]
              [(tx-data ?log ?tx) [[?e]]]]
     (d/db conn) (d/log conn) #inst "2013-08-01" #inst "2013-08-02")

Implementation

Datomic's log is stored as a shallow tree of segments, where each segment typically contains thousands of datoms. The most recent data in the log is also maintained in memory on all transactor and peer processes.