### Install libsql-client with Default Features Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Add this to your Cargo.toml to use the default local, reqwest, and hrana backends. ```toml [dependencies] libsql-client = "0.34.0" ``` -------------------------------- ### Install libsql-client for Fermyon Spin Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Configure your Cargo.toml to use the spin_backend for Fermyon Spin applications. ```toml [dependencies] libsql-client = { version = "0.34.0", default-features = false, features = ["spin_backend"] } ``` -------------------------------- ### SyncClient Example in Rust Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Demonstrates synchronous database operations using `SyncClient`. This is useful in blocking contexts or runtimes that do not support async operations. It covers table creation, batch inserts, data retrieval, and transactions. ```rust use anyhow::Result; use libsql_client::{SyncClient, Statement, args}; fn main() -> Result<()> { let db = SyncClient::in_memory()?; db.execute("CREATE TABLE stock (item TEXT, qty INTEGER, price REAL)")?; db.batch([ Statement::with_args("INSERT INTO stock VALUES (?, ?, ?)", args!("apple", 100i64, 0.5f64)), Statement::with_args("INSERT INTO stock VALUES (?, ?, ?)", args!("banana", 50i64, 0.3f64)), ])?; let rs = db.execute("SELECT * FROM stock")?; for row in &rs.rows { let item: &str = row.try_get(0)?; let qty: i64 = row.try_get(1)?; let price: f64 = row.try_get(2)?; println!(ירתem}: {qty} units @ ${price:.2}"); } // apple: 100 units @ $0.50 // banana: 50 units @ $0.30 let tx = db.transaction()?; tx.execute(Statement::with_args("UPDATE stock SET qty = qty - ? WHERE item = ?", args!(10i64, "apple")))?; tx.commit()?; Ok(()) } ``` -------------------------------- ### Connect and Query Database in Cloudflare Worker Source: https://github.com/tursodatabase/libsql-client-rs/blob/main/README.md Example of connecting to the database and executing a query within a GET handler in a Cloudflare Worker. Requires the libsql_client::workers::Client. ```rust router.get_async("/", |_, ctx| async move { let db = libsql_client::workers::Client::from_ctx(&ctx).await?; let response = db .execute("SELECT * FROM table WHERE key = 'key1'") .await?; (...) ``` -------------------------------- ### Install libsql-client for Cloudflare Workers Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Use this configuration for Cloudflare Workers, disabling default features and enabling the workers_backend. Requires compilation to wasm32. ```toml [dependencies] libsql-client = { version = "0.34.0", default-features = false, features = ["workers_backend"] } ``` -------------------------------- ### Cloudflare Workers Integration with Rust Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Shows how to construct a `Client` from Cloudflare Workers environment variables (`LIBSQL_CLIENT_URL`, `LIBSQL_CLIENT_TOKEN`). Requires the `workers_backend` feature and `default-features = false` in `Cargo.toml`. This example sets up a basic HTTP endpoint to query user data. ```toml # Cargo.toml [dependencies] libsql-client = { version = "0.34.0", default-features = false, features = ["workers_backend"] } ``` ```rust use worker::{event, Env, Request, Response, Result, Router}; use libsql_client::Client; #[event(fetch)] async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result { let router = Router::new(); router .get_async("/users", |_, ctx| async move { // Reads LIBSQL_CLIENT_URL and LIBSQL_CLIENT_TOKEN from Worker secrets let db = Client::from_workers_env(&ctx.env) .map_err(|e| worker::Error::RustError(e.to_string()))?; let rs = db.execute("SELECT * FROM users").await .map_err(|e| worker::Error::RustError(e.to_string()))?; let body = format!("{} user(s) found", rs.rows.len()); Response::ok(body) }) .run(req, env) .await } ``` -------------------------------- ### Connect to Database using Environment Variables Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Constructs a Client by reading LIBSQL_CLIENT_URL and LIBSQL_CLIENT_TOKEN from environment variables. The URL scheme determines the backend. Ensure env vars are set before running. ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { // Set env vars before running: // export LIBSQL_CLIENT_URL="https://mydb.turso.io" // export LIBSQL_CLIENT_TOKEN="my-jwt-token" let db = Client::from_env().await?; db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)") .await?; println!("Table created successfully"); Ok(()) } ``` -------------------------------- ### Client::from_env Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Constructs a Client by reading LIBSQL_CLIENT_URL and LIBSQL_CLIENT_TOKEN environment variables. The URL scheme automatically selects the appropriate backend. ```APIDOC ## Client::from_env — Connect using environment variables Constructs a `Client` by reading `LIBSQL_CLIENT_URL` and the optional `LIBSQL_CLIENT_TOKEN` environment variables. The URL scheme determines which backend is selected automatically (`file://` → local, `http(s)://` → reqwest/workers/spin, `ws(s)://` → hrana, `libsql://` → converted to `https://`). ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { // Set env vars before running: // export LIBSQL_CLIENT_URL="https://mydb.turso.io" // export LIBSQL_CLIENT_TOKEN="my-jwt-token" let db = Client::from_env().await?; db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)") .await?; println!("Table created successfully"); Ok(()) } ``` ``` -------------------------------- ### Connect to Database from Environment (Rust) Source: https://github.com/tursodatabase/libsql-client-rs/blob/main/README.md Connect to a libSQL database using a URL from environment variables. Ensure the `LIBSQL_CLIENT_URL` environment variable is set. ```rust let db = libsql_client::Client::from_env().await?; ``` -------------------------------- ### Client::from_config Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Constructs a Client from an explicit Config value, allowing programmatic specification of the database URL and an optional authentication token. The URL scheme selects the backend. ```APIDOC ## Client::from_config — Connect using a `Config` struct Constructs a `Client` from an explicit `Config` value, letting you specify the database URL and an optional authentication token programmatically. The URL scheme selects the backend the same way as `from_env`. ```rust use anyhow::Result; use libsql_client::{Client, Config}; #[tokio::main] async fn main() -> Result<()> { // Remote Turso/sqld database with auth token let config = Config::new("https://mydb.turso.io")? .with_auth_token("my-jwt-token"); let db = Client::from_config(config).await?; // Local file database (no token needed) let local_config = Config { url: url::Url::parse("file:////tmp/local.db")?, auth_token: None, }; let local_db = Client::from_config(local_config).await?; local_db.execute("CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, label TEXT)").await?; Ok(()) } ``` ``` -------------------------------- ### Connect to Database using Config Struct Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Creates a Client from an explicit Config struct, allowing programmatic specification of the database URL and authentication token. Supports remote and local file-based databases. ```rust use anyhow::Result; use libsql_client::{Client, Config}; #[tokio::main] async fn main() -> Result<()> { // Remote Turso/sqld database with auth token let config = Config::new("https://mydb.turso.io")? .with_auth_token("my-jwt-token"); let db = Client::from_config(config).await?; // Local file database (no token needed) let local_config = Config { url: url::Url::parse("file:////tmp/local.db")?, auth_token: None, }; let local_db = Client::from_config(local_config).await?; local_db.execute("CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, label TEXT)").await?; Ok(()) } ``` -------------------------------- ### Client::from_workers_env for Cloudflare Workers Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Shows how to integrate `libsql-client` with Cloudflare Workers using the `Client::from_workers_env` method. This method constructs a `Client` by reading database URL and token from Worker environment secrets. ```APIDOC ## `Client::from_workers_env` — Cloudflare Workers integration Constructs a `Client` from a Cloudflare Workers `Env` object by reading the `LIBSQL_CLIENT_URL` and `LIBSQL_CLIENT_TOKEN` secrets. Requires the `workers_backend` feature with `default-features = false`. ```toml # Cargo.toml [dependencies] libsql-client = { version = "0.34.0", default-features = false, features = ["workers_backend"] } ``` ```rust use worker::{event, Env, Request, Response, Result, Router}; use libsql_client::Client; #[event(fetch)] async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result { let router = Router::new(); router .get_async("/users", |_, ctx| async move { // Reads LIBSQL_CLIENT_URL and LIBSQL_CLIENT_TOKEN from Worker secrets let db = Client::from_workers_env(&ctx.env) .map_err(|e| worker::Error::RustError(e.to_string()))?; let rs = db.execute("SELECT * FROM users").await .map_err(|e| worker::Error::RustError(e.to_string()))?; let body = format!("{} user(s) found", rs.rows.len()); Response::ok(body) }) .run(req, env) .await } ``` ``` -------------------------------- ### Create an In-Memory Database Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Instantiates a local, in-memory SQLite database, suitable for testing. Requires the `local_backend` feature, which is enabled by default. Demonstrates basic table creation, insertion, and selection. ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE example (num INTEGER, str TEXT)").await?; db.execute("INSERT INTO example VALUES (1, 'hello')").await?; let rs = db.execute("SELECT * FROM example").await?; assert_eq!(rs.columns, ["num", "str"]); assert_eq!(rs.rows.len(), 1); println!("rows_affected={}, last_insert_rowid={:?}", rs.rows_affected, rs.last_insert_rowid); // Output: rows_affected=0, last_insert_rowid=None Ok(()) } ``` -------------------------------- ### Connect to Local Database (Rust) Source: https://github.com/tursodatabase/libsql-client-rs/blob/main/README.md Connect to a local libSQL database file. The `local_backend` feature must be enabled. Requires setting the `LIBSQL_CLIENT_URL` environment variable to a file path. ```rust let db = libsql_client::local::Client::from_env()?; ``` ```rust let response = db .execute("SELECT * FROM table WHERE key = 'key1'") .await?; ``` -------------------------------- ### Configure Environment Variables for Libsql Client Source: https://github.com/tursodatabase/libsql-client-rs/blob/main/README.md Set these variables in your .dev.vars file or as secrets for database connection. ```bash LIBSQL_CLIENT_URL = "https://your-db-url.example.com" LIBSQL_CLIENT_TOKEN = "" ``` -------------------------------- ### args! macro Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt The `args!` macro simplifies binding heterogeneous Rust values into a `&[Value]` slice, eliminating the need for manual `Value` construction when parameter types vary. ```APIDOC ## `args!` macro — Convenient mixed-type parameter binding The `args!` macro converts heterogeneous Rust values into a `&[Value]` slice, avoiding manual `Value` construction when parameter types differ. ```rust use anyhow::Result; use libsql_client::{Client, Statement, args}; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE coordinates (lat REAL, long REAL, airport TEXT)").await?; db.execute(Statement::with_args( "INSERT INTO coordinates VALUES (?, ?, ?)", args!(52.22959f64, 21.0067f64, "WAW"), )).await?; db.execute(Statement::with_args( "INSERT INTO coordinates VALUES (?, ?, ?)", args!(-33.95f64, 151.1819f64, "NSW"), )).await?; let rs = db.execute("SELECT * FROM coordinates").await?; println!("{} airport(s) inserted", rs.rows.len()); // 2 airport(s) inserted Ok(()) } ``` ``` -------------------------------- ### Add Libsql Client Dependency for Workers Source: https://github.com/tursodatabase/libsql-client-rs/blob/main/README.md Add the libsql-client as a dependency with the 'workers_backend' feature enabled. Disable default features to ensure compatibility with wasm32-unknown-unknown. ```bash cargo add libsql-client --no-default-features -F workers_backend ``` -------------------------------- ### SyncClient Usage Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Demonstrates how to use the `SyncClient` for synchronous database operations in Rust. This client wraps the main `Client` and uses `futures::executor::block_on` internally, making it suitable for synchronous contexts. ```APIDOC ## `SyncClient` — Synchronous API `SyncClient` wraps `Client` and exposes identical methods without `async`/`.await`, using `futures::executor::block_on` internally. Useful in synchronous contexts or runtimes that don't support async. ```rust use anyhow::Result; use libsql_client::{SyncClient, Statement, args}; fn main() -> Result<()> { let db = SyncClient::in_memory()?; db.execute("CREATE TABLE stock (item TEXT, qty INTEGER, price REAL)")?; db.batch([ Statement::with_args("INSERT INTO stock VALUES (?, ?, ?)", args!("apple", 100i64, 0.5f64)), Statement::with_args("INSERT INTO stock VALUES (?, ?, ?)", args!("banana", 50i64, 0.3f64)), ])?; let rs = db.execute("SELECT * FROM stock")?; for row in &rs.rows { let item: &str = row.try_get(0)?; let qty: i64 = row.try_get(1)?; let price: f64 = row.try_get(2)?; println!("{item}: {qty} units @ ${price:.2}"); } // apple: 100 units @ $0.50 // banana: 50 units @ $0.30 let tx = db.transaction()?; tx.execute(Statement::with_args("UPDATE stock SET qty = qty - ? WHERE item = ?", args!(10i64, "apple")))?; tx.commit()?; Ok(()) } ``` ``` -------------------------------- ### Client::in_memory Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Creates a local, in-memory SQLite database, which is useful for testing purposes. This method requires the `local_backend` feature to be enabled. ```APIDOC ## Client::in_memory — Create an in-memory database Creates a local, in-memory SQLite database — useful for testing. Requires the `local_backend` feature (enabled by default). ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE example (num INTEGER, str TEXT)").await?; db.execute("INSERT INTO example VALUES (1, 'hello')").await?; let rs = db.execute("SELECT * FROM example").await?; assert_eq!(rs.columns, ["num", "str"]); assert_eq!(rs.rows.len(), 1); println!("rows_affected={}, last_insert_rowid={:?}", rs.rows_affected, rs.last_insert_rowid); // Output: rows_affected=0, last_insert_rowid=None Ok(()) } ``` ``` -------------------------------- ### Statement::new and Statement::with_args Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Construct SQL statements. `Statement::new` is for statements without parameters, while `Statement::with_args` binds positional `?` parameters from a slice of values. Any type convertible to `Value` can be used. ```APIDOC ## `Statement::new` and `Statement::with_args` — Build parameterized statements `Statement::new` creates a simple statement without parameters. `Statement::with_args` binds positional `?` parameters from a slice of values. Both accept any type convertible to `Value` (integers, floats, text, blobs, null). ```rust use libsql_client::{Statement, Value}; // Simple statement (no parameters) let stmt = Statement::new("SELECT * FROM sqlite_master"); // Homogeneous parameter slice (all same type) let stmt = Statement::with_args( "SELECT * FROM users WHERE country = ? AND active = ?", &["US", "true"], ); // Mixed types require explicit Value conversion let stmt = Statement::with_args( "INSERT INTO events (user_id, score, label) VALUES (?, ?, ?)", &[ Value::Integer { value: 42 }, Value::Float { value: 98.6 }, Value::Text { value: "high".into() }, ], ); println!("{stmt}"); // {"sql": "INSERT INTO events (user_id, score, label) VALUES (?, ?, ?)", "args": [42,98.6,"high"]} ``` ``` -------------------------------- ### Build Parameterized Statements with Statement::new and Statement::with_args Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Use `Statement::new` for simple SQL without parameters. Use `Statement::with_args` to bind positional `?` parameters from a slice of values. Any type convertible to `Value` (integers, floats, text, blobs, null) can be used. ```rust use libsql_client::{Statement, Value}; // Simple statement (no parameters) let stmt = Statement::new("SELECT * FROM sqlite_master"); // Homogeneous parameter slice (all same type) let stmt = Statement::with_args( "SELECT * FROM users WHERE country = ? AND active = ?", &["US", "true"], ); // Mixed types require explicit Value conversion let stmt = Statement::with_args( "INSERT INTO events (user_id, score, label) VALUES (?, ?, ?)", &[ Value::Integer { value: 42 }, Value::Float { value: 98.6 }, Value::Text { value: "high".into() }, ], ); println!("{stmt}"); // {"sql": "INSERT INTO events (user_id, score, label) VALUES (?, ?, ?)", "args": [42,98.6,"high"]} ``` -------------------------------- ### Convenient Mixed-Type Parameter Binding with args! Macro Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt The `args!` macro simplifies binding heterogeneous Rust values into a `&[Value]` slice, avoiding manual `Value` construction when parameter types differ. ```rust use anyhow::Result; use libsql_client::{Client, Statement, args}; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE coordinates (lat REAL, long REAL, airport TEXT)").await?; db.execute(Statement::with_args( "INSERT INTO coordinates VALUES (?, ?, ?)", args!(52.22959f64, 21.0067f64, "WAW"), )).await?; db.execute(Statement::with_args( "INSERT INTO coordinates VALUES (?, ?, ?)", args!(-33.95f64, 151.1819f64, "NSW"), )).await?; let rs = db.execute("SELECT * FROM coordinates").await?; println!("{} airport(s) inserted", rs.rows.len()); // 2 airport(s) inserted Ok(()) } ``` -------------------------------- ### Execute Single SQL Statement with Client::execute Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Use `Client::execute` to run a single SQL statement. It can accept plain strings or parameterized `Statement` objects. It returns a `ResultSet` with query results or affected row information. ```rust use anyhow::Result; use libsql_client::{Client, Statement}; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL)").await?; // Plain string statement let insert_rs = db.execute("INSERT INTO products (name, price) VALUES ('Widget', 9.99)").await?; println!("inserted rowid={:?}", insert_rs.last_insert_rowid); // inserted rowid=Some(1) // Parameterized statement let select_rs = db.execute(Statement::with_args( "SELECT * FROM products WHERE price < ?", &[10.0f64], )).await?; for row in &select_rs.rows { let name: &str = row.try_get(1)?; let price: f64 = row.try_get(2)?; println!("name={name}, price={price}"); // name=Widget, price=9.99 } Ok(()) } ``` -------------------------------- ### Execute Non-Transactional Batches with Client::raw_batch Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Use `Client::raw_batch` for executing multiple statements independently, without a transaction. Each statement can succeed or fail individually. It returns a `BatchResult` with step results and errors. ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE foo (bar TEXT)").await?; let batch_result = db.raw_batch([ "SELECT * FROM foo", "INSERT INTO foo(bar) VALUES ('hello')", "SELECT * FROM foo", ]).await?; for (i, result) in batch_result.step_results.iter().enumerate() { match result { Some(stmt_result) => println!("step {i}: {} row(s)", stmt_result.rows.len()), None => println!("step {i}: skipped or errored"), } } Ok(()) } ``` -------------------------------- ### Execute Transactional Batches with Client::batch Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Use `Client::batch` to execute multiple statements within an implicit transaction. All statements succeed or the entire batch is rolled back. It returns a vector of `ResultSet`s, one for each statement. ```rust use anyhow::Result; use libsql_client::{Client, Statement}; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE counter(country TEXT PRIMARY KEY, value INTEGER)").await?; let results = db.batch([ Statement::with_args("INSERT OR IGNORE INTO counter VALUES (?, 0)", &["US"]), Statement::with_args("UPDATE counter SET value = value + 1 WHERE country = ?", &["US"]), "SELECT * FROM counter", ]).await?; assert_eq!(results.len(), 3); let select_rs = &results[2]; let count: i64 = select_rs.rows[0].try_get(1)?; println!("counter value={count}"); // counter value=1 Ok(()) } ``` -------------------------------- ### Client::execute Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Executes a single SQL statement and returns a ResultSet. This method can handle both plain SQL strings and parameterized statements. ```APIDOC ## Client::execute ### Description Executes one SQL statement and returns a `ResultSet` containing the column names, rows, number of affected rows, and the last inserted row ID. ### Method `execute` ### Parameters - `statement`: `Statement` or `&str` - The SQL statement to execute. ### Request Example ```rust // Plain string statement let insert_rs = db.execute("INSERT INTO products (name, price) VALUES ('Widget', 9.99)").await?; // Parameterized statement let select_rs = db .execute(Statement::with_args( "SELECT * FROM products WHERE price < ?", &[10.0f64], )) .await?; ``` ### Response #### Success Response - `ResultSet`: Contains column names, rows, affected rows count, and last inserted row ID. ### Response Example ```rust // For INSERT statement println!("inserted rowid={{:?}}", insert_rs.last_insert_rowid); // inserted rowid=Some(1) // For SELECT statement for row in &select_rs.rows { let name: &str = row.try_get(1)?; let price: f64 = row.try_get(2)?; println!("name={{name}}, price={{price}}"); // name=Widget, price=9.99 } ``` ``` -------------------------------- ### Manage Interactive Transactions with Client::transaction Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Use `Client::transaction` to open an interactive transaction for fine-grained control. Changes are persisted with `commit()` or discarded with `rollback()`. Each `execute` call within the transaction participates in the same transaction. ```rust use anyhow::Result; use libsql_client::{Client, Statement, args}; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance REAL)").await?; db.execute("INSERT INTO accounts VALUES (1, 1000.0), (2, 500.0)").await?; let tx = db.transaction().await?; let debit_res = tx.execute(Statement::with_args( "UPDATE accounts SET balance = balance - ? WHERE id = ?", args!(200.0f64, 1i64), )).await; if debit_res.is_err() { tx.rollback().await?; return Err(debit_res.unwrap_err()); } tx.execute(Statement::with_args( "UPDATE accounts SET balance = balance + ? WHERE id = ?", args!(200.0f64, 2i64), )).await?; tx.commit().await?; println!("Transfer committed successfully"); Ok(()) } ``` -------------------------------- ### Client::raw_batch Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Executes multiple SQL statements independently without a transaction. Each statement can succeed or fail individually. Returns a BatchResult. ```APIDOC ## Client::raw_batch ### Description Executes multiple statements without wrapping them in a transaction. Each statement can independently succeed or fail. Returns a `BatchResult` containing raw step results and step errors. ### Method `raw_batch` ### Parameters - `statements`: An iterable of `&str` - The SQL statements to execute. ### Request Example ```rust let batch_result = db.raw_batch([ "SELECT * FROM foo", "INSERT INTO foo(bar) VALUES ('hello')", "SELECT * FROM foo", ]).await?; ``` ### Response #### Success Response - `BatchResult`: Contains `step_results` (optional `ResultSet` for each step) and `step_errors`. ### Response Example ```rust for (i, result) in batch_result.step_results.iter().enumerate() { match result { Some(stmt_result) => println!("step {{i}}: {{}} row(s)", stmt_result.rows.len()), None => println!("step {{i}}: skipped or errored"), } } ``` ``` -------------------------------- ### Client::batch Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Executes multiple SQL statements within an implicit transaction. All statements succeed or the batch is rolled back. Returns a vector of ResultSets. ```APIDOC ## Client::batch ### Description Wraps multiple statements in an implicit `BEGIN`/`END` transaction. All statements either succeed together or the entire batch is rolled back. Returns a `Vec`, one per statement. ### Method `batch` ### Parameters - `statements`: An iterable of `Statement` or `&str` - The SQL statements to execute. ### Request Example ```rust let results = db.batch([ Statement::with_args("INSERT OR IGNORE INTO counter VALUES (?, 0)", &["US"]), Statement::with_args("UPDATE counter SET value = value + 1 WHERE country = ?", &["US"]), "SELECT * FROM counter", ]).await?; ``` ### Response #### Success Response - `Vec`: A vector containing a `ResultSet` for each executed statement. ### Response Example ```rust assert_eq!(results.len(), 3); let select_rs = &results[2]; let count: i64 = select_rs.rows[0].try_get(1)?; println!("counter value={{count}}"); // counter value=1 ``` ``` -------------------------------- ### Client::transaction Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Opens an interactive transaction for fine-grained control. Changes are persisted with `commit()` or discarded with `rollback()`. ```APIDOC ## Client::transaction ### Description Opens an interactive transaction for fine-grained control. Each `execute` call within the transaction participates in the same transaction. Call `commit()` to persist or `rollback()` to discard all changes. ### Method `transaction` ### Parameters None ### Request Example ```rust let tx = db.transaction().await?; // Perform operations within the transaction tx.execute(Statement::with_args( "UPDATE accounts SET balance = balance - ? WHERE id = ?", args!(200.0f64, 1i64), )).await; // Commit or rollback tx.commit().await?; // or tx.rollback().await?; ``` ### Response #### Success Response - `Transaction`: An object representing the interactive transaction. ### Response Example ```rust println!("Transfer committed successfully"); ``` ``` -------------------------------- ### Extract Column Values by Name with Row::try_column Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Retrieves a value from a `Row` by column name, converting it to the requested Rust type. Requires the `mapping_names_to_values_in_rows` feature (enabled by default). ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE users (id INTEGER, name TEXT, age INTEGER)").await?; db.execute("INSERT INTO users VALUES (1, 'Alice', 30)").await?; let rs = db.execute("SELECT * FROM users").await?; let row = &rs.rows[0]; let id: i64 = row.try_column("id")?; let name: &str = row.try_column("name")?; let age: i64 = row.try_column("age")?; println!("id={id}, name={name}, age={age}"); // id=1, name=Alice, age=30 Ok(()) } ``` -------------------------------- ### Extract Column Values by Index with Row::try_get Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Retrieves a value from a `Row` at a given zero-based column index, converting it to the requested Rust type. Returns an error if the index is out of bounds or the type conversion fails. ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE example (num INTEGER, str TEXT, score REAL)").await?; db.execute("INSERT INTO example VALUES (42, 'hello', 3.14)").await?; let rs = db.execute("SELECT * FROM example").await?; let row = &rs.rows[0]; let num: i64 = row.try_get(0)?; let text: &str = row.try_get(1)?; let score: f64 = row.try_get(2)?; println!("num={num}, text={text}, score={score}"); // num=42, text=hello, score=3.14 Ok(()) } ``` -------------------------------- ### Deserialize Rows into Rust Structs with de::from_row Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Deserializes a `Row` directly into any type implementing `serde::Deserialize`. Struct field names must match column names exactly. Supported field types include `String`, `Vec`, `i64`, `f64`, `Option`, and `()`. Requires the `mapping_names_to_values_in_rows` feature. ```rust use anyhow::Result; use libsql_client::{Client, de}; #[derive(Debug, serde::Deserialize)] struct User { id: i64, name: String, score: f64, bio: Option, } #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE users (id INTEGER, name TEXT, score REAL, bio TEXT)").await?; db.execute("INSERT INTO users VALUES (1, 'Alice', 9.5, 'Engineer')").await?; db.execute("INSERT INTO users VALUES (2, 'Bob', 7.2, NULL)").await?; let users: Vec = db .execute("SELECT * FROM users") .await? .rows .iter() .map(de::from_row) .collect::, _>>()?; for user in &users { println!("{:?}", user); } // User { id: 1, name: "Alice", score: 9.5, bio: Some("Engineer") } // User { id: 2, name: "Bob", score: 7.2, bio: None } Ok(()) } ``` -------------------------------- ### de::from_row Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Deserialize a `Row` directly into a Rust struct that implements `serde::Deserialize`. Struct field names must precisely match column names. Supported field types include `String`, `Vec`, `i64`, `f64`, `Option`, and `()`. This requires the `mapping_names_to_values_in_rows` feature. ```APIDOC ## `de::from_row` — Deserialize rows into Rust structs Deserializes a `Row` directly into any type implementing `serde::Deserialize`. Struct field names must match column names exactly. Supported field types: `String`, `Vec`, `i64`, `f64`, `Option`, and `()`. Requires the `mapping_names_to_values_in_rows` feature. ```rust use anyhow::Result; use libsql_client::{Client, de}; #[derive(Debug, serde::Deserialize)] struct User { id: i64, name: String, score: f64, bio: Option, } #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE users (id INTEGER, name TEXT, score REAL, bio TEXT)").await?; db.execute("INSERT INTO users VALUES (1, 'Alice', 9.5, 'Engineer')").await?; db.execute("INSERT INTO users VALUES (2, 'Bob', 7.2, NULL)").await?; let users: Vec = db .execute("SELECT * FROM users") .await?; .rows .iter() .map(de::from_row) .collect::, _>>()?; for user in &users { println!("{:?}", user); } // User { id: 1, name: "Alice", score: 9.5, bio: Some("Engineer") } // User { id: 2, name: "Bob", score: 7.2, bio: None } Ok(()) } ``` ``` -------------------------------- ### Row::try_column Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Extract column values from a `Row` by their column name. This method requires the `mapping_names_to_values_in_rows` feature and converts the value to the requested Rust type. ```APIDOC ## `Row::try_column` — Extract column values by name Retrieves a value from a `Row` by column name, converting it to the requested Rust type. Requires the `mapping_names_to_values_in_rows` feature (enabled by default). ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE users (id INTEGER, name TEXT, age INTEGER)").await?; db.execute("INSERT INTO users VALUES (1, 'Alice', 30)").await?; let rs = db.execute("SELECT * FROM users").await?; let row = &rs.rows[0]; let id: i64 = row.try_column("id")?; let name: &str = row.try_column("name")?; let age: i64 = row.try_column("age")?; println!("id={id}, name={name}, age={age}"); // id=1, name=Alice, age=30 Ok(()) } ``` ``` -------------------------------- ### Row::try_get Source: https://context7.com/tursodatabase/libsql-client-rs/llms.txt Extract column values from a `Row` by their zero-based index. This method attempts to convert the value to the specified Rust type, returning an error if the index is invalid or the conversion fails. ```APIDOC ## `Row::try_get` — Extract column values by index Retrieves a value from a `Row` at a given zero-based column index, converting it to the requested Rust type. Returns an error if the index is out of bounds or the type conversion fails. ```rust use anyhow::Result; use libsql_client::Client; #[tokio::main] async fn main() -> Result<()> { let db = Client::in_memory()?; db.execute("CREATE TABLE example (num INTEGER, str TEXT, score REAL)").await?; db.execute("INSERT INTO example VALUES (42, 'hello', 3.14)").await?; let rs = db.execute("SELECT * FROM example").await?; let row = &rs.rows[0]; let num: i64 = row.try_get(0)?; let text: &str = row.try_get(1)?; let score: f64 = row.try_get(2)?; println!("num={num}, text={text}, score={score}"); // num=42, text=hello, score=3.14 Ok(()) } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.