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
)
Summary
Functions
Checks out a connection from the pool by verifying it's still alive.
Opens a connection to LibSQL using the native Rust layer.
Disconnects from the database by closing the underlying native connection.
Begins a new database transaction.
Closes the query. Currently a no-op as queries are stateless.
Commits the current transaction.
Deallocates a cursor, freeing its resources.
Declares a cursor for streaming query results.
Executes an SQL query, delegating to transactional or non-transactional logic depending on the connection state.
Fetches the next batch of rows from a cursor.
Prepares a query for execution. Returns the query unchanged as preparation is handled during execution.
Rolls back the current transaction.
Checks the current transaction status.
Pings the current connection to ensure it is still alive.
Functions
Checks out a connection from the pool by verifying it's still alive.
@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).
@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.
Begins a new database transaction.
The transaction behaviour (deferred/immediate/exclusive) can be controlled via options passed to the Native module.
Closes the query. Currently a no-op as queries are stateless.
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.
Deallocates a cursor, freeing its resources.
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.
@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.
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.
Prepares a query for execution. Returns the query unchanged as preparation is handled during execution.
Rolls back the current transaction.
Discards all changes made within the transaction and returns the connection to autocommit mode.
Checks the current transaction status.
@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.