# `Selecto.Performance.Hooks`

Performance monitoring hooks for Selecto query execution.

Provides configurable hooks that can be inserted at various points
in the query execution pipeline to collect performance metrics,
trigger optimizations, and enable monitoring.

# `chain_hooks`

Chain multiple hooks together.

## Examples

    combined = Hooks.chain_hooks([
      timing_hook,
      logging_hook,
      metrics_hook
    ])
    
    Hooks.register(:after_execution, combined)

# `conditional_hook`

Create a conditional hook that only runs when condition is met.

## Examples

    # Only log queries that touch certain tables
    # Note: Use LogSanitizer.sanitize_query/2 to avoid logging parameters
    hook = Hooks.conditional_hook(
      fn ctx -> String.contains?(ctx.sql, "users") end,
      fn ctx ->
        Logger.info("User table query detected (params redacted)")
        ctx
      end
    )

# `create_hook`

Create a custom hook for specific monitoring needs.

## Examples

    # Hook to track queries by user
    hook = Hooks.create_hook(:user_tracking, fn context ->
      user_id = context.options[:user_id]
      :telemetry.execute([:app, :query, :by_user], %{count: 1}, %{user_id: user_id})
      context
    end)
    
    Hooks.register(:before_execution, hook)

# `install_default_hooks`

Install default performance monitoring hooks.

This sets up a standard set of hooks for:
- Query timing
- Metrics collection
- Slow query logging
- EXPLAIN ANALYZE for slow queries

# `register`

Register a hook function for a specific hook point.

## Hook Points

- `:before_query_build` - Called before SQL generation starts
- `:after_query_build` - Called after SQL is generated
- `:before_execution` - Called before query execution
- `:after_execution` - Called after successful execution
- `:on_error` - Called when an error occurs
- `:on_cache_hit` - Called when query result is found in cache
- `:on_cache_miss` - Called when query result is not in cache

## Examples

    # Register a timing hook
    Hooks.register(:before_execution, fn context ->
      Map.put(context, :start_time, System.monotonic_time(:millisecond))
    end)
    
    # Register a logging hook
    Hooks.register(:after_execution, fn ctx ->
      Logger.info("Query executed in #{ctx.execution_time}ms")
      ctx
    end)

# `restore_hooks`

Restore a hook snapshot into the current process.

# `run_hooks`

Execute all registered hooks for a hook point.

Hooks are executed in reverse order of registration (LIFO).
Each hook receives the context and should return an updated context.

# `snapshot_hooks`

Snapshot currently registered hooks for the current process.

Useful when execution is delegated to another process (for example timeout
wrappers) and hooks should be propagated.

# `unregister`

Unregister all hooks for a specific hook point.

# `with_hooks`

Wrap a query execution with performance hooks.

This is the main entry point for integrating hooks into query execution.

---

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