# `GgenIgniter.Query.Qlever`
[🔗](https://github.com/seanchatmangpt/ggen_igniter/blob/v26.9.8/lib/ggen_igniter/query/qlever.ex#L21)

Alternate `GgenIgniter.Query`-shaped engine backed by a real QLever SPARQL
endpoint, via `gno`'s `Gno.Store.Adapters.Qlever` adapter for endpoint
resolution and `SPARQL.Client` (both real, hex-published deps -- rdf-elixir's
own `sparql_client`) for protocol execution.

Same contract as `GgenIgniter.Query.run/2`: `(source, query_string) :: [map()]`.
Here `source` is a `Gno.Store.Adapters.Qlever` struct (not an `%RDF.Graph{}` --
QLever is a remote, already-loaded store, not an in-process graph) instead of
the `%RDF.Graph{}` the default `sparql`-engine-backed `GgenIgniter.Query` takes.

## Why this module exists

`ggen_igniter/test/ash_r2rml_gate_integration_test.exs` pinned a real,
reproducing bug in the `sparql` 0.3.12 engine (a `FILTER NOT EXISTS` +
`BIND(constant)` inside `UNION` -- a shape both of `ash_r2rml`'s real gate
queries use -- raises `Protocol.UndefinedError`). This module is the
alternate-engine escape hatch: the identical query text against a real,
independent SPARQL 1.1 engine (QLever), executed over its query endpoint.

## Note on `Gno.select/1`

`Gno.select/1` (the top-level `Gno.Manifest`-driven convenience API) works
fine once a manifest is authored correctly (in particular, once shared
resources like a store description live in DCATR's "default graph" so its
Manifest Graph Expansion can pull them into the service-manifest graph --
see `~/dev/ggen_igniter/config/gno/test/store.ttl` for a real example, and
https://github.com/rdf-elixir/gno/pull/2 for an unrelated real doc-comment
fix found along the way). This module deliberately bypasses `Gno.Manifest`
entirely: it takes a plain `%RDF.Graph{}` (the same type
`GgenIgniter.Ontology.load!/1` already produces) and a store resource IRI,
and loads just that one `Gno.Store.Adapters.Qlever` resource directly via
`Grax.load/3` -- no `gno:Service`/`dcatr:Repository` manifest ceremony
needed when all `ggen_igniter.sync` wants is "run this query against this
QLever endpoint."

## Optional dependency

`:gno` is `optional: true` in `mix.exs` (so is `:tesla`, which `gno` itself
depends on). This module body only compiles when
`Code.ensure_loaded?(Gno.Store.Adapters.Qlever)` is true at compile time --
see the top of `qlever.ex` for the `else` branch a consumer without `:gno`
gets instead.

# `load_store!`

```elixir
@spec load_store!(RDF.Graph.t(), RDF.IRI.t() | String.t()) ::
  Gno.Store.Adapters.Qlever.t()
```

Loads a `Qlever` store description from a real manifest Turtle graph.

`graph` must contain a `gnoa:Qlever`-typed resource at `store_id`.

# `run`

```elixir
@spec run(Gno.Store.Adapters.Qlever.t(), String.t()) :: [map()]
```

Runs `query_string` against the real QLever endpoint described by `store`.

Same return shape as `GgenIgniter.Query.run/2`: a list of string-keyed maps,
values unwrapped from `RDF.IRI`/`RDF.Literal` to bare Elixir values.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
