spark.spec-tacular.datomic
Datomic interface for the spec-tacular DSL
assoc!
(assoc! conn-ctx si & {:as updates})
Updates the given entity in database in the given connection. Returns the new entity.
The entity must be an object representation of an entity on the database (for example, returned from a query, create!, or an earlier assoc!).
Attempting to retract a :component
field (by setting that field to nil
) retracts the entire component instance.
Get the Datomic :db/id
from the object using the :db-ref
field.
Aborts if the entity does not exist in the database (use create! instead).
ConnCtx
A connection context. The only mandatory field is the :conn
, which provides the actual connection to the database.
Other option fields include:
:transaction-log
, any object which can be converted to Datomic transaction data
count-all-by-spec
(count-all-by-spec db spec)
Returns the number of entities with the given spec in the database.
create!
(create! conn-ctx new-si)
Creates a new instance of the given entity on the database in the given connection context. Returns a representation of the newly created object.
Get the Datomic :db/id
from the object using the :db-ref
field.
Aborts if the entity already exists in the database (use assoc! instead).
create-graph!
(create-graph! conn-ctx new-si-coll)
Creates every new instance contained in the given collection, and returns the new instances in a collection of the same type, and in the same order where applicable. For every object that is identical?
in the given graph, only one instance is created on the database.
create-graph! does not support arbitrarly nested collections.
Currently supports sets, lists, vector, and sequences.
Aborts if any entities already exist on the database.
get-all-by-spec
macro
(get-all-by-spec db spec)
Returns all the entities in the database with the given spec.
If the spec is a keyword at compile-time, the resulting entity is cast to the correct type. Otherwise, the resulting entity is a generic SpecInstance
graph-transaction-data
(graph-transaction-data conn-ctx new-si-coll)
Returns Datomic transaction data that would create the given graph on the database given in conn-ctx
. Also contains meta-data :tmpids
and :specs
for the expected temp-ids and specs, respectively.
instance-transaction-data
(instance-transaction-data conn-ctx new-si)
Returns the Datomic transaction data that would create the given spec instance on the database given in conn-ctx
.
pull
(pull db pattern instance)
Executes a Datomic pull after datomifying the given pattern with respect to the given instance.
q
macro
(q & stx)
Returns a set of results from the Datomic query. See the README for examples. Also see Datomic’s documentation for query, which we both restrict and expand upon.
(q :find FIND-EXPR+ :in DB-EXPR :where CLAUSE+)
FIND-EXPR = VAR
| VAR .
| (pull VAR pattern)
| (instance SpecName ?variable)
| (aggregate expr* VAR)
| [VAR+ ]
| [VAR ...]
DB-EXPR | expr
VAR = ?variable
| SpecName
CLAUSE = SPEC-CLAUSE
| any otherwise valid Datomic clause
SPEC-CLAUSE = [SpecName SPEC-RHS]
| [?variable [SpecName SPEC-RHS]]
SPEC-RHS = % | %n | SpecName
| {keyword (SPEC-CLAUSE | expr),+}
Every SpecName
must be a keyword at compile-time. Every ?variable
is quoted, so you do not have to quote them yourself. Anything expr
that is not a ?variable
or a SpecName
is left unchanged (so you can perform operations inside of queries as long as it does not confuse the query syntax).
The FIND-EXPR
are used as the :find
arguments to the Datomic query. The syntax is the same, except we include (instance
SpecName ?variable)
for casting any database type to SpecName
on its way off the database. This is done automatically for FIND-EXPRS
that terminate with SpecName
s rather than ?variable
s. The aggregate
function must adhere to Datomic’s requirements: either one of the build-in aggregators or a fully qualified function already imported into the namespace, where the aggregated variable is the final argument.
The value of :in
is used as the database; no other arguments to :in
are allowed at the moment.
Each :where
clause is expanded to one or more Datomic clauses. All Datomic where clause syntax is (intended to be) supported. The SPEC-CLAUSE
form finds spec-tacular instances on the database with the fields given in SPEC-RHS
.
Using %
and %n
is analogous to #
and %
in Clojure: %
inserts the first SpecName
in the FIND-EXPR
if there is only one, or %1
references the first, and %2
the second, etc.
query
added in 0.6.0
(query {find-elems :find, clauses :where, :as m} & args)
Runtime support for spec-tacular queries. Akin to the map syntax for datomic.api/q
, this form expects data (rather than syntax), and attempts to unroll spec-tacular maps into valid Datomic :where
clauses.
(query {:find FIND-EXPR :in IN-EXPR :where (WHERE-CLAUSE+)} expr+)
FIND-EXPR = VAR
| VAR .
| (spec-pull VAR SpecName spec-tacular-pattern)
| (pull VAR datomic-pattern)
| (instance SpecName ?variable)
| [VAR+ ]
| [VAR ...]
DB-EXPR | expr
VAR = ?variable
| SpecName
CLAUSE = SPEC-CLAUSE
| any otherwise valid Datomic clause
SPEC-CLAUSE = [?variable SPEC-RHS]
SPEC-RHS | {:spec-tacular/spec SpecName,
keyword (?variable | constant | spec-instance),+}
Note that SPEC-RHS
is no longer recursive via SPEC-CLAUSE
. If SpecName
names a UnionSpec, we create an or
that tries every branch.
If any Exception
s occur enroute, a clojure.lang.ExceptionInfo
is thrown with additional information about the query that was executed.
This function uses spark.spec-tacular.datomic.query-helpers
in order to datomify the FIND-EXPR
and each WHERE-CLAUSE
.
refresh
(refresh conn-ctx si)
Returns an updated representation of the Datomic entity at the given instance’s :db-ref
.
The entity must be an object representation of an entity on the database (see assoc! for an explanation).
retract!
added in 0.5.1
(retract! conn-ctx si & [field-name])
Removes the given instance from the database using :db.fn/retractEntity
. Returns nil
.
update!
(update! conn-ctx si-old si-new)
Calculate a shallow difference between the two spec instances and uses assoc! to change the entity on the database.