# `EctoLibSql`
[🔗](https://github.com/ocean/ecto_libsql/blob/v0.9.1/lib/ecto_libsql.ex#L1)

DBConnection implementation for LibSQL and Turso databases.

This module provides the core database connection functionality for LibSQL/Turso,
implementing the `DBConnection` behaviour. It supports three connection modes:

- **Local**: SQLite files on the local filesystem
- **Remote**: Direct connections to Turso cloud databases
- **Remote Replica**: Local SQLite files that sync with remote Turso databases

## Features

- Connection management via Rust NIFs for high performance
- Full transaction support with multiple isolation levels
- Query execution in both transactional and non-transactional contexts
- Cursor support for streaming large result sets
- Prepared statement caching
- Batch operations (transactional and non-transactional)
- Vector similarity search
- Database encryption

## Connection Options

- `:database` - Path to local SQLite database file
- `:uri` - Remote LibSQL server URI (e.g., `"libsql://your-db.turso.io"`)
- `:auth_token` - Authentication token for remote connections
- `:sync` - Enable automatic sync for embedded replicas (boolean)
- `:encryption_key` - Encryption key for local database (min 32 characters)

## Examples

    # Local database
    {:ok, conn} = DBConnection.start_link(EctoLibSql, database: "local.db")

    # Remote Turso database
    {:ok, conn} = DBConnection.start_link(EctoLibSql,
      uri: "libsql://your-db.turso.io",
      auth_token: "your-token"
    )

    # Embedded replica (local + remote sync)
    {:ok, conn} = DBConnection.start_link(EctoLibSql,
      database: "local.db",
      uri: "libsql://your-db.turso.io",
      auth_token: "your-token",
      sync: true
    )

# `checkout`

Checks out a connection from the pool by verifying it's still alive.

# `connect`

```elixir
@spec connect(Keyword.t()) :: {:ok, EctoLibSql.State.t()} | {:error, term()}
```

Opens a connection to LibSQL using the native Rust layer.

Returns `{:ok, state}` on success or `{:error, reason}` on failure.
Automatically uses remote replica if the opts provided database, uri, and auth token.

## Options

- `:database` - Path to local SQLite database file
- `:uri` - Remote LibSQL server URI (e.g., `"libsql://your-db.turso.io"`)
- `:auth_token` - Authentication token for remote connections
- `:sync` - Enable automatic sync for embedded replicas (boolean)
- `:encryption_key` - Encryption key for local database (min 32 characters)
- `:busy_timeout` - Busy timeout in milliseconds (default: 5000)
                    Controls how long SQLite waits for locks before returning SQLITE_BUSY.
                    Set to 0 to disable (not recommended for production).

# `disconnect`

```elixir
@spec disconnect(term(), EctoLibSql.State.t()) ::
  :ok | {:error, term(), EctoLibSql.State.t()}
```

Disconnects from the database by closing the underlying native connection.

Removes the connection from the Rust connection registry and cleans up any resources.

# `handle_begin`

Begins a new database transaction.

The transaction behaviour (deferred/immediate/exclusive) can be controlled
via options passed to the Native module.

# `handle_close`

Closes the query. Currently a no-op as queries are stateless.

# `handle_commit`

Commits the current transaction.

The state must contain a valid transaction ID. For embedded replicas with
auto-sync enabled, this will also trigger a sync to the remote database.

# `handle_deallocate`

Deallocates a cursor, freeing its resources.

# `handle_declare`

Declares a cursor for streaming query results.

Cursors allow you to iterate through large result sets in chunks, which is
more memory-efficient than loading all rows at once.

# `handle_execute`

```elixir
@spec handle_execute(
  EctoLibSql.Query.t() | String.t(),
  list(),
  Keyword.t(),
  EctoLibSql.State.t()
) ::
  {:ok, EctoLibSql.Query.t(), EctoLibSql.Result.t(), EctoLibSql.State.t()}
  | {:error, EctoLibSql.Error.t(), EctoLibSql.State.t()}
```

Executes an SQL query, delegating to transactional or non-transactional logic
depending on the connection state.

# `handle_fetch`

Fetches the next batch of rows from a cursor.

Cursors are used for streaming large result sets without loading everything
into memory at once. Automatically deallocates the cursor when no more rows
are available.

# `handle_prepare`

Prepares a query for execution. Returns the query unchanged as preparation
is handled during execution.

# `handle_rollback`

Rolls back the current transaction.

Discards all changes made within the transaction and returns the connection
to autocommit mode.

# `handle_status`

Checks the current transaction status.

# `ping`

```elixir
@spec ping(EctoLibSql.State.t()) ::
  {:ok, EctoLibSql.State.t()}
  | {:disconnect, :ping_failed, EctoLibSql.State.t()}
```

Pings the current connection to ensure it is still alive.

---

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