Ok after admitting that I'd better go the DNF route to compute a keyset (set of columns that are a key on the result set) I realized that if the query had a cycle (does it occur often in practice?) my algorithm would fail to return a proper key.
As usual to deal with cycles, at some point I have to switch from a graph of nodes to a graph of SCCs. It works, in the absence of cycle the keyset is minimal, with cycles the keyset may not be minimal (there may be redundancy but it no case non-key vars would be included).
Birth of a protocol
Here we go (there's nothing yet about instantiation)
(defprotocol Template
(query [t]
"returns the query for this template")
(used-vars [t]
"vars used in its own body (not by nested templates)")
(children [t] "returns a map of ids (mount points) to templates"))
So, using the TODO example with 4 templates: the with, the inner with, the title and the status:
only with returns a query: {[title done] :item/attrs}whose keyvars are [?id421] (the item eid); with has no used vars on its own but it has one child,
inner with has no query, no used vars and two children,
each children has no query, one used var each and no child.
(I wonder if "inner with" is there to stay.)
Death of a protocol
A protocol where all methods have no args is not a protocol: it's a map!
Let's start with a simple case: the foreign template -- that is the template which calls clojure code.
(defn foreign-template [vars f]
{:vars vars
:instance f})
Keysets (cont & end)
Ok after admitting that I'd better go the DNF route to compute a keyset (set of columns that are a key on the result set) I realized that if the query had a cycle (does it occur often in practice?) my algorithm would fail to return a proper key.
As usual to deal with cycles, at some point I have to switch from a graph of nodes to a graph of SCCs. It works, in the absence of cycle the keyset is minimal, with cycles the keyset may not be minimal (there may be redundancy but it no case non-key vars would be included).
Birth of a protocol
Here we go (there's nothing yet about instantiation)
So, using the TODO example with 4 templates: the
with
, the innerwith
, the title and the status:with
returns a query:{[title done] :item/attrs}
whose keyvars are[?id421]
(the item eid);with
has no used vars on its own but it has one child,with
has no query, no used vars and two children,(I wonder if "inner with" is there to stay.)
Death of a protocol
A protocol where all methods have no args is not a protocol: it's a map!
Let's start with a simple case: the foreign template -- that is the template which calls clojure code.
The idea is to call
f
with values bound tovars
.Now, to
with
:So
q
is executed and for each returned row, children are instantiated. Each instance is identified by the key (derived from the query).