# sqlx-turso-driver
An asynchronous [SQLx](https://github.com/launchbadge/sqlx) driver for embedded [Turso](https://github.com/tursodatabase/turso) databases.
## Features
- File-backed and in-memory databases.
- SQLx connection pools with acquire timeouts and configurable engine busy timeouts.
- Parameterized queries through `query`, `query_as` and `query_scalar`.
- Integer, floating-point, string, binary, boolean and nullable values.
- Owned rows, column-name/index access, prepared statements and column metadata.
- Row streaming, optional/single-row fetches, result collections and affected-row counts.
- Transactions with commit, rollback and deferred cleanup on drop.
- File persistence across connection close and reopen.
## Usage
### Dependencies
With the driver checkout alongside your application, add:
```toml
[dependencies]
sqlx-turso-driver = { path = "../sqlx-turso-driver" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```
Use the driver's re-exported `sqlx` for queries and connection traits.
### File database, connection pool and transactions
```rust
use std::time::Duration;
use sqlx_turso_driver::{Turso, TursoConnectOptions, connect_pool, sqlx};
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let options = TursoConnectOptions::file("app.db")?
.busy_timeout(Duration::from_secs(2));
let pool = connect_pool(options, 4).await?;
sqlx::query(
"CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, label TEXT NOT NULL)",
)
.execute(&pool)
.await?;
let mut tx = pool.begin().await?;
let result = sqlx::query("INSERT INTO notes (label) VALUES (?1)")
.bind("Hello, Turso!")
.execute(&mut *tx)
.await?;
tx.commit().await?;
println!("Inserted {} row(s)", result.rows_affected());
let notes = sqlx::query_as::<Turso, (i64, String)>(
"SELECT id, label FROM notes ORDER BY id",
)
.fetch_all(&pool)
.await?;
println!("{notes:?}");
pool.close().await;
Ok(())
}
```
Call `tx.rollback().await?` instead of `tx.commit().await?` to discard a transaction's changes.
### In-memory database
```rust
use sqlx_turso_driver::{Turso, TursoConnectOptions, sqlx};
use sqlx::{ConnectOptions, Connection};
async fn memory_example() -> Result<i64, sqlx::Error> {
let mut connection = TursoConnectOptions::memory().connect().await?;
let value = sqlx::query_scalar::<Turso, i64>("SELECT ?1")
.bind(42_i64)
.fetch_one(&mut connection)
.await?;
connection.close().await?;
Ok(value)
}
```
For a pooled in-memory database, use `connect_pool(TursoConnectOptions::memory(), 1).await?`.
### Run the example
The [local example](<examples/local.rs>) demonstrates parameter binding, commit, rollback and file close/reopen:
```sh
cargo +stable run --locked --example local
```