Liking cljdoc? Tell your friends :D

qslice.core

A namespace for constructing "query slices" or "qslices".

A qslice is a group of datomic query :where clauses with additional metadata related to vars. The point of this metadata is to track where a var's binding is expected to come from and whether any other slice can use the var.

  • require: Some other query slice must bind this var first.
  • provide: The clauses bind this var for later query slices later to :require.
  • let: Binding forms (as in datomic query :in, not clojure destructuring let) with their values (as in datomic query :args). The vars in the binding forms must appear in :where or :provide and may not appear in :require.

Once a qslice is created via qslice, you may :let-bind any vars in the :where clause to values via with-let. Those bindings and values will be added to the :in and :args of the final compiled query.

(As a convenience, you may also create and bind at the same time by adding a :let argument to qslice)

(Additionally, you can :must-let vars for safety. This makes it an error to fail to :let these vars.)

You can also add a cost score to qslices using with-selectivity to influence clause order. Lower values will appear earlier in the query.

Once you have a collection of bound qslices, you can "compile" them to a datomic query using compiled-query. This function takes a collection of qslices and "output" forms (like :find, :with, :keys, etc) and returns a query+args map you can give to d/query.

The real magic is that vars that are not required or provided in a qslice will be automatically munged in the where clauses that appear in the query so that the same var name will never appear for any other qslice in the set. This means you can write a bunch of qslices independently, with natural-looking :where clauses and possibly the same var names across slices, and combine them into a single query safely without unexpected unification.

You still need to coordinate :provide and :require var contracts among qslices, but the qslice machinery will enforce those contracts come query time.

The public functions of this namespace and their expected call sequence:

qslice with-name name with-selectivity with-let with-let* with-let-locked let-locked? compiled-query compiled-slice-order-names

These are convenience qslice constructors:

db-qslice rule-qslice

These are qslice "combinators": they accept qslices and return a different one.

or-qslice

A namespace for constructing "query slices" or "qslices".

A qslice is a group of datomic query :where clauses with additional metadata
related to vars. The point of this metadata is to track where a var's binding
is expected to come from and whether any other slice can use the var.

* require: Some other query slice must bind this var first.
* provide: The clauses bind this var for later query slices later to :require.
* let: Binding forms (as in datomic query :in, not clojure destructuring `let`)
  with their values (as in datomic query :args).
  The vars in the binding forms must appear in :where or :provide
  and may not appear in :require.

Once a qslice is created via `qslice`, you may :let-bind any vars in the :where
clause to values via `with-let`. Those bindings and values will be
added to the :in and :args of the final compiled query.

(As a convenience, you may also create and bind at the same time by adding
a `:let` argument to `qslice`)

(Additionally, you can `:must-let` vars for safety. This makes it an error
to fail to :let these vars.)

You can also add a cost score to qslices using `with-selectivity`
to influence clause order.
Lower values will appear earlier in the query.

Once you have a collection of bound qslices,
you can "compile" them to a datomic query using `compiled-query`.
This function takes a collection of qslices and "output" forms
(like :find, :with, :keys, etc) and returns a query+args map you can give
to d/query.

The real magic is that *vars that are not required or provided in a qslice
will be automatically munged* in the where clauses that appear in the query
so that the same var name will never appear for any other qslice in the set.
This means you can write a bunch of qslices independently, with
natural-looking :where clauses and possibly the same var names across slices,
and combine them into a single query safely without unexpected unification.

You still need to coordinate :provide and :require var contracts among
qslices, but the qslice machinery will enforce those contracts come query
time.

The public functions of this namespace and their expected call sequence:

`qslice`
`with-name`
`name`
`with-selectivity`
`with-let`
`with-let*`
`with-let-locked`
`let-locked?`
`compiled-query`
`compiled-slice-order-names`

These are convenience qslice constructors:

`db-qslice`
`rule-qslice`

These are qslice "combinators": they accept qslices and return a different one.

`or-qslice`
raw docstring

compiled-queryclj

(compiled-query qslices find-clause)

Compile a collection of qslices into a datomic query-map suitable for d/qseq or d/query (not datomic.api/q).

At least one qslice and a find-clause must be provided. The qslices must all have :let bindings that satisfy their own :must-let, and must satisfy each-other's :provide and :require.

find-clause can be a simple :find vector, or it can be a map with keys :find :with :keys :syms :strs with datomic's meaning. Vars in :find and :with must be :provide-ed by the qslices. (Note that :in and :where are ignored.)

Returns a query map with :query, :args, and :slice-order set.

:slice-order is a vector of maps, one per slice, in the order that the slices were compiled into the query. Each map has:

  • :slice-idx The index of the slice in the input qslices collection.
  • :name The slice's name.
  • :selectivity The slice's selectivity value.
Compile a collection of qslices into a datomic query-map suitable for
d/qseq or d/query (not datomic.api/q).

At least one qslice and a find-clause must be provided.
The qslices must all have :let bindings that satisfy their own :must-let,
and must satisfy each-other's :provide and :require.

find-clause can be a simple :find vector, or it can be a map with keys
:find :with :keys :syms :strs with datomic's meaning.
Vars in :find and :with must be :provide-ed by the qslices.
(Note that :in and :where are ignored.)

Returns a query map with :query, :args, and :slice-order set.

:slice-order is a vector of maps, one per slice, in the order that the
slices were compiled into the query. Each map has:

* :slice-idx   The index of the slice in the input `qslices` collection.
* :name        The slice's name.
* :selectivity The slice's selectivity value.
sourceraw docstring

compiled-slice-order-namesclj

(compiled-slice-order-names {:as _compiled-query :keys [slice-order]})

Convenience functions which prints the slice names in :slice-order of a compiled query. Omits names $, %, nil, and empty-string. This is for producing a small, loggable summary of the order of slices in the final query.

Convenience functions which prints the slice names in :slice-order
of a compiled query. Omits names $, %, nil, and empty-string.
This is for producing a small, loggable summary of the order of slices
in the final query.
sourceraw docstring

db-qsliceclj

(db-qslice)
(db-qslice db)
(db-qslice db-sym db)

Return a qslice that provides a datasource (e.g. $). If called with one argument, $ will be bound to that value. If called with two arguments, the first argument is the datasource binding symbol and the second the value (e.g. (db-qslice $h (d/history db))).

Return a qslice that provides a datasource (e.g. $).
If called with one argument, $ will be bound to that value.
If called with two arguments, the first argument is the datasource binding
symbol and the second the value (e.g. `(db-qslice $h (d/history db))`).
sourceraw docstring

let-locked?clj

(let-locked? qs)

Returns whether the current qslice was locked via with-let-locked.

Returns whether the current qslice was locked via `with-let-locked`.
sourceraw docstring

nameclj

Retrieve the name of a qslice previously set via with-name. The default name of a qslice is the empty string.

Retrieve the name of a qslice previously set via with-name.
The default name of a qslice is the empty string.
sourceraw docstring

or-qsliceclj

(or-qslice qslices)

Returns a qslice which behaves as if all the supplied qslices were or-joined together.

Let bindings will be combined, possibly with shading to avoid collisions. The returned qslice will be let-locked. Name will be combined as "or(qslice1 qslice2 ...)". Selectivity will be the minimum found among all input qslices.

There are limitations to what qslices can be combined. All the following conditions must hold or this function will throw:

  • All qslices must provide the exact same vars.
  • At most one datasource may be required by each qslice. This is a datomic restriction: rules may only access one datasource.
  • All required datasources must be named $. This is for implementation convenience and could be lifted in the future.
  • All qslices must-let bindings must be satisfied. This is because you cannot know what the name of the var will be after shading.
  • No qslices may share owned vars (i.e. vars both provided and must-let). This is for ease of implementation and because the correct semantics for combining their let-bindings is not yet clear.
Returns a qslice which behaves as if all the supplied qslices were or-joined
together.

Let bindings will be combined, possibly with shading to avoid collisions.
The returned qslice will be let-locked.
Name will be combined as "or(qslice1 qslice2 ...)".
Selectivity will be the minimum found among all input qslices.

There are limitations to what qslices can be combined. All the following
conditions must hold or this function will throw:

* All qslices must provide the exact same vars.
* At most one datasource may be required by each qslice.
  This is a datomic restriction: rules may only access one datasource.
* All required datasources must be named $.
  This is for implementation convenience and could be lifted in the future.
* All qslices must-let bindings must be satisfied.
  This is because you cannot know what the name of the var will be after shading.
* No qslices may share owned vars (i.e. vars both provided and must-let).
  This is for ease of implementation and because the correct semantics for
  combining their let-bindings is not yet clear.
sourceraw docstring

qsliceclj

(qslice &
        {:keys [require provide must-let where name selectivity]
         let-param :let})

Construct and return a query slice.

Accepts the following arguments as a single map or variadic arguments:

  • :where A collection of datomic :where clauses, as in a datomic query.
  • :let A collection of pairs of :in binding-forms with their :args value. You can also provide this after construction using when-let or when-let*.
  • :name An optional name for this slice, default "". You can also provide this after construction using with-name.
  • :provide A collection of datomic vars ($datasources, %, or ?variables) that this slice will provide via :let, with-let, or in its :where. These variables can be used by other slices.
  • :require A collection of datomic vars that this slice uses but another slice must :provide. It automatically includes any datasources or % (if a rule invocation is seen) found in :where that is not in :provide.
  • :must-let A collection of datomic vars which must be :let or with-let by this qslice before constructing a datomic query. Note that datasources or rules in :provide and datasources in :where but not in :require are automatically added to :must-let because there is no other way to provide them.
  • :selectivity An optional long, default 0, which influences the order of this qslice's :where clauses among other qslices in a compiled query. Lower values appear earlier in the query. This is useful to encourage faster or more selective clauses to appear earlier or slower clauses to appear later in the query.

Note that this constructor is moderately costly because it performs form-walking and invariant checks. Therefore, if the qslice will be reused only with different :name, :let, or :selectivity values, it is better to construct the base qslice once and modify it with with-name, with-let, with-let*, or with-selectivity repeatedly.

Construct and return a query slice.

Accepts the following arguments as a single map or variadic arguments:

* `:where` A collection of datomic `:where` clauses, as in a datomic query.
* `:let` A collection of pairs of :in binding-forms with their :args value.
  You can also provide this after construction using `when-let` or `when-let*`.
* `:name` An optional name for this slice, default "".
  You can also provide this after construction using `with-name`.
* `:provide` A collection of datomic vars ($datasources, %, or ?variables)
  that this slice will provide via :let, `with-let`, or in its :where.
  These variables can be used by other slices.
* `:require` A collection of datomic vars that this slice uses but another
  slice must :provide.
  It automatically includes any datasources or % (if a rule invocation is seen)
  found in :where that is not in :provide.
* `:must-let` A collection of datomic vars which *must* be `:let` or
  `with-let` by *this* qslice before constructing a datomic query.
  Note that datasources or rules in :provide and datasources in :where
  but not in :require are automatically added to :must-let because there is
  no other way to provide them.
* :selectivity An optional long, default 0, which influences the order
  of this qslice's :where clauses among other qslices in a compiled query.
  Lower values appear earlier in the query.
  This is useful to encourage faster or more selective clauses to appear
  earlier or slower clauses to appear later in the query.

Note that this constructor is moderately costly because it performs
form-walking and invariant checks.
Therefore, if the qslice will be reused only with different :name, :let, or
:selectivity values, it is better to construct the base qslice once and modify
it with `with-name`, `with-let`, `with-let*`, or `with-selectivity`
repeatedly.
sourceraw docstring

rule-qsliceclj

(rule-qslice)
(rule-qslice rules)

Return a qslice that provides rules (%). If called with an argument, % will be bound to that value.

Return a qslice that provides rules (%).
If called with an argument, % will be bound to that value.
sourceraw docstring

with-letclj

(with-let qs & binding-form->value)

Bind or re-bind values to the qslice.

Arguments after the qslice are alternating binding-forms and values, e.g.:

(with-let the-qslice '?a 1 '[?b ...] 2)

Or a single argument of pairs of binding-forms and value, which will be delegated to with-let*. e.g.:

(with-let the-qslice {'?a 1 '[?b ...] 2}) (with-let the-qslice [['?a 1] ['[?b ...] 2]])

with-let calls do not accumulate: each call completely replaces the previous :let state of the qslice.

Bind or re-bind values to the qslice.

Arguments after the qslice are alternating binding-forms and values, e.g.:

(with-let the-qslice '?a 1 '[?b ...] 2)

Or a single argument of pairs of binding-forms and value, which will be
delegated to `with-let*`. e.g.:

(with-let the-qslice {'?a 1 '[?b ...] 2})
(with-let the-qslice [['?a 1] ['[?b ...] 2]])

`with-let` calls do not accumulate: each call completely replaces the
previous :let state of the qslice.
sourceraw docstring

with-let*clj

(with-let* qs binding-form->value)

Binds values to the qslice. Accepts a seqable of pairs of argument and value.

with-let* calls do not accumulate: each call completely replaces the previous :let state of the qslice.

Binds values to the qslice. Accepts a seqable of pairs of argument and value.

`with-let*` calls do not accumulate: each call completely replaces the
previous :let state of the qslice.
sourceraw docstring

with-let-lockedclj

(with-let-locked qs)

Asserts that all must-lets are satisfied and returns a qslice which cannot be with-let again.

This is a utility function for combinators whose behavior would be undefined if the qslice was rebound.

Asserts that all must-lets are satisfied and returns a qslice which cannot be
with-let again.

This is a utility function for combinators whose behavior would be undefined
if the qslice was rebound.
sourceraw docstring

with-nameclj

(with-name qs name)

Set a name for this qslice. This is for informational purposes only and does not affect compiled queries.

Set a name for this qslice.
This is for informational purposes only and does not affect compiled queries.
sourceraw docstring

with-selectivityclj

(with-selectivity qs selectivity)
source

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close