# `Lotus.Source.Adapters.Ecto.SQL.FilterInjector`
[🔗](https://github.com/elixir-lotus/lotus/blob/v1.0.0/lib/lotus/source/adapters/ecto/sql/filter_injector.ex#L1)

Shared helpers for SQL-based sources to inject filter conditions into queries.

Wraps the original query in a CTE and appends WHERE clauses using parameterized
queries. Each SQL source calls this with its own `quote_fn` and `placeholder_fn`
for database-specific identifier quoting and parameter placeholders.

## Example

    quote_fn = fn id -> ~s("#{id}") end
    placeholder_fn = fn idx -> "$#{idx}" end
    Lotus.Source.Adapters.Ecto.SQL.FilterInjector.apply("SELECT * FROM users", [25], [
      %Lotus.Query.Filter{column: "region", op: :eq, value: "US"}
    ], quote_fn, placeholder_fn)
    #=> {~s(WITH _base AS (SELECT * FROM users) SELECT * FROM _base WHERE "region" = $2), [25, "US"]}

# `apply`

```elixir
@spec apply(
  String.t(),
  list(),
  [Lotus.Query.Filter.t()],
  (String.t() -&gt; String.t()),
  (pos_integer() -&gt;
     String.t())
) ::
  {String.t(), list()}
```

Wraps the given SQL in a CTE and appends parameterized WHERE clauses for each filter.

`quote_fn` is a 1-arity function that quotes an identifier for the target database.
`placeholder_fn` is a 1-arity function that takes a 1-based parameter index and
returns the placeholder string (e.g., `"$1"` for Postgres, `"?"` for MySQL).

Returns `{sql, params}` where params is the updated parameter list with filter
values appended. Returns `{sql, params}` unchanged if filters is empty.

---

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