The one real reconciliation pipeline implementation: Ontology.load!/1 ->
engine prepare!/2 + run/2 -> Render.render/2 -> Actuate.write_file!/3
(or Actuate.eval_code!/2 under mode: eval).
Extracted as a plain, Mix.Task/Igniter-free function specifically so it
can be called by both a CLI entry point (Mix.Tasks.GgenIgniter.Sync) and a
persistent in-process caller (GgenIgniter.Controller) without duplicating
the ontology-load/engine-run/render/actuate logic in two places. This
module is the shared implementation; GgenIgniter.Controller calls
run/1 directly and adds only in-process state around it.
Mix.Tasks.GgenIgniter.Sync itself is left unchanged in this pass (a
separate, concurrent effort owns wiring the CLI to delegate here) -- so for
now this is a second entry point into the same real query engines/render/
actuate modules sync.ex already uses, not yet the CLI's own call path.
Once that wiring lands, sync.ex's igniter/1 and GgenIgniter.Controller
will both terminate in this one function.
Deliberately bounded relative to Mix.Tasks.GgenIgniter.Sync
This is a bounded, real proof-of-concept slice covering exactly the spine
named for it: ontology-load -> engine-run -> render -> actuate. It does
NOT (yet) implement Mix.Tasks.GgenIgniter.Sync's fuller surface:
- No template frontmatter parsing (
GgenIgniter.Frontmatter) -- a template's file content is used verbatim as the EEx body. - No
--for-eachmulti-row fan-out -- exactly one render, exactly one actuation perrun/1call. - No
inject: truesplice mode --mode: filealways dispatches toActuate.write_file!/3(whole-file guarded write), neverActuate.inject_content!/5.
The --pack/--pack-dir convention (GgenIgniter.Pack) IS supported,
reused verbatim (not duplicated), since pack-shaped fixtures are the
natural unit a reconciliation controller tracks by key.
Options (opts, a plain keyword list)
Mirrors the subset of Mix.Tasks.GgenIgniter.Sync's own -- flags this
function's bounded scope covers:
:ontology-- path to the Turtle ontology file. Falls back to the pack'sontology.ttlwhen:pack/:pack_diris given.:query-- one"name=path.rq"string, or a list of them (repeatable--queryequivalent). Merged with pack-discoveredgates/*.rqqueries when a pack is given (pack queries first, explicit:queryentries override same-named pack queries -- same tie-break assync.ex).:template-- path to the EEx template file. Falls back to the pack's single auto-discovered template when:pack/:pack_diris given.:pack/:pack_dir-- seeGgenIgniter.Pack.:engine--"oxigraph"(default),"sparql", or"qlever".:mode--"file"(default) or"eval".:out-- required formode: "file"; EEx-rendered against the query bindings (a static path with no<%= %>round-trips unchanged).:unless_exists,:skip_if,:dry_run-- forwarded toActuate.write_file!/3unchanged.
Return value
{:ok, result} where result is a plain map (see result/0) describing
what actually happened -- real engine name, real resolved paths, real row
counts, and the real Actuate outcome/eval value. Raises on a real,
unrecoverable pipeline failure (bad ontology path, missing template, engine
error) -- this function is a faithful, un-defensive mirror of what the
pipeline actually does; a caller that needs a non-raising boundary (e.g.
GgenIgniter.Controller) wraps this call itself rather than this function
hiding real failures behind a swallowed error tuple.
Summary
Types
@type result() :: %{ engine: String.t(), ontology_path: String.t(), template_path: String.t(), query_count: non_neg_integer(), total_rows: non_neg_integer(), mode: :file | :eval, out_path: String.t() | nil, outcome: GgenIgniter.Actuate.outcome() | nil, value: term(), notice: String.t() }