# `Selecto.ConnectionPool`

Connection pooling and management for Selecto.

Provides a high-performance connection pool using DBConnection for efficient
database connection reuse, prepared statement caching, and connection health monitoring.

## Features

- Connection pooling with configurable pool sizes
- Prepared statement caching for repeated queries
- Connection health monitoring and automatic recovery
- Adapter-owned pool startup and pooled execution
- Graceful fallback to direct connections when pooling is disabled

## Configuration

    # Application config
    config :selecto, Selecto.ConnectionPool,
      pool_size: 10,
      max_overflow: 20,
      prepared_statement_cache_size: 1000,
      connection_timeout: 5000,
      checkout_timeout: 5000

## Usage

    # Start a connection pool
    {:ok, pool} = Selecto.ConnectionPool.start_pool(connection_input)
    
    # Configure Selecto with pooled connection
    selecto = Selecto.configure(domain, {:pool, pool})
    
    # Or use default pool management
    selecto = Selecto.configure(domain, connection_input, pool: true)

# `connection_config`

```elixir
@type connection_config() :: Keyword.t() | map()
```

# `pool_options`

```elixir
@type pool_options() :: Keyword.t()
```

# `pool_ref`

```elixir
@type pool_ref() :: pid() | atom()
```

# `checkin`

```elixir
@spec checkin(pool_ref(), term()) :: :ok
```

Return a checked-out connection to the pool.

Always call this after checkout/2 to return the connection.

# `checkout`

```elixir
@spec checkout(pool_ref(), Keyword.t()) ::
  {:ok, DBConnection.conn()} | {:error, term()}
```

Checkout a connection from the pool for manual management.

This is useful for transactions or when you need to execute multiple
queries on the same connection.

## Parameters

- `pool_ref` - The pool reference
- `opts` - Options including :timeout

## Returns

- `{:ok, connection_ref}` - Connection checked out successfully
- `{:error, reason}` - Checkout failed

## Examples

    {:ok, conn} = Selecto.ConnectionPool.checkout(pool)
    try do
      run_checkout_queries(conn)
    after
      Selecto.ConnectionPool.checkin(pool, conn)
    end

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `clear_cache`

```elixir
@spec clear_cache(pool_ref()) :: :ok
```

Clear prepared statement cache for a pool.

# `execute`

```elixir
@spec execute(pool_ref(), String.t(), list(), Keyword.t()) ::
  {:ok, term()} | {:error, term()}
```

Execute a query using a pooled connection.

Automatically handles connection checkout/checkin and prepared statement caching.

# `generate_cache_key`

# `generate_pool_name`

# `get_manager_pid`

# `get_pool_pid`

# `pool_stats`

```elixir
@spec pool_stats(pool_ref()) :: map()
```

Get pool statistics for monitoring.

Returns information about pool health, connection counts, and cache statistics.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

# `start_pool`

```elixir
@spec start_pool(connection_config(), pool_options()) ::
  {:ok, pool_ref()} | {:error, term()}
```

Start a connection pool with the given configuration.

## Parameters

- `connection_config` - Database connection configuration
- `pool_options` - Pool-specific options (optional)

## Returns

- `{:ok, pool_ref}` - Pool started successfully
- `{:error, reason}` - Pool startup failed

## Examples

    # Start pool with default adapter config
    config = [
      hostname: "localhost",
      username: "user", 
      password: "pass",
      database: "mydb"
    ]
    {:ok, pool} = Selecto.ConnectionPool.start_pool(config)
    
    # Start pool with custom options and adapter
    {:ok, pool} = Selecto.ConnectionPool.start_pool(config, 
      pool_size: 20,
      adapter: SelectoDBMySQL.Adapter
    )

# `stop_pool`

```elixir
@spec stop_pool(pool_ref()) :: :ok
```

Stop a connection pool.

Gracefully shuts down the pool and all its connections.

# `transaction`

```elixir
@spec transaction(pool_ref(), (DBConnection.conn() -&gt; result), Keyword.t()) ::
  {:ok, result} | {:error, term()}
when result: term()
```

Execute a transaction on a pooled connection.

All queries in the function are executed within a database transaction.

## Examples

    Selecto.ConnectionPool.transaction(pool, fn conn ->
      run_transaction_steps(conn)
    end)

# `with_connection`

```elixir
@spec with_connection(pool_ref(), (DBConnection.conn() -&gt; result)) ::
  {:ok, result} | {:error, term()}
when result: term()
```

Execute a function with a checked-out connection.

This is the recommended way to use connections for multiple operations.
The connection is automatically returned to the pool when the function completes.

## Examples

    Selecto.ConnectionPool.with_connection(pool, fn conn ->
      run_queries_with_adapter_connection(conn)
    end)

---

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