Expand description
A Cloudflare Durable Objects driver for sqlx.
Do is an sqlx::Database over a
Durable Object’s SQL storage, so code written against sqlx’s runtime API –
sqlx::query, sqlx::query_as, #[derive(sqlx::FromRow)], Executor –
runs inside a SQLite-backed Durable Object with the database type swapped.
use sqlx_cloudflare_do::{Do, DoConnection};
use worker::{durable_object, DurableObject, Env, Request, Response, State};
#[derive(sqlx::FromRow)]
struct User {
id: i64,
name: String,
}
#[durable_object]
pub struct Users {
conn: DoConnection,
}
impl DurableObject for Users {
fn new(state: State, _env: Env) -> Self {
// One connection for the object's lifetime: it is only a handle to
// storage the object already owns.
Self { conn: DoConnection::new(state.storage()) }
}
async fn fetch(&self, _req: Request) -> worker::Result<Response> {
let user = sqlx::query_as::<Do, User>("SELECT id, name FROM users WHERE id = ?")
.bind(1_i64)
.fetch_one(&self.conn)
.await
.map_err(|e| worker::Error::RustError(e.to_string()))?;
Response::ok(user.name)
}
}The database lives in the Durable Object: queries never leave the process,
and each one runs to completion before its future first returns. The class
must be declared with new_sqlite_classes in wrangler.toml – the
key-value-backed kind has no SQL storage.
§What Durable Object storage cannot do
Each of these fails loudly rather than pretending:
begin(). It returns an error:sql.execrejectsBEGINandSAVEPOINT. Transactions take a callback instead –DoConnection::transaction– andDoConnection::execute_batchruns several statements atomically without one.- Integers beyond ±(2^53 − 1). Values cross as JavaScript numbers, so
binding a wider
i64is an encode error rather than a rounded value. Seetypes. query!anddescribe. sqlx’s macros only know its built-in drivers, andsql.execcannot describe a statement without running it.
There is no sqlx::Pool either – a Durable Object’s storage has nothing
to pool – and no sqlx::migrate!.
This crate only runs on wasm32-unknown-unknown, inside a Worker. It
compiles on other targets so that docs, unit tests and cargo check work,
but its Send impls lean on Durable Objects being single-threaded: do not
call it from a threaded host.
Modules§
- types
Encode,DecodeandTypefor the Rust types Durable Object storage can store.
Structs§
- Do
- The Cloudflare Durable Object storage driver: the type sqlx code names in
Executor<'_, Database = Do>,sqlx::query_as::<Do, _>and so on. - DoArguments
- The parameters bound to one query, in placeholder order.
- DoColumn
- A column of a Durable Object storage result.
- DoConnect
Options - The options type sqlx requires of every connection.
- DoConnection
- A connection to a Durable Object’s SQL storage.
- DoDatabase
Error - An error the database returned for a statement.
- DoQuery
Result - What a statement did.
- DoRow
- A row of a Durable Object storage result.
- DoStatement
- A “prepared” Durable Object storage statement: the SQL and nothing else.
- DoTransaction
- An open transaction: the executor
DoConnection::transactionhands its callback. - DoTransaction
Manager - Refuses
begin(). - DoValue
- A value read out of a Durable Object storage result, already converted from JavaScript.
- DoValue
Ref - A borrowed
DoValue, which is whatDecodeimplementations read.
Enums§
- DoArgument
Value - One SQLite value on the Rust side of the JavaScript boundary, in either direction: a parameter a query binds, or a value a result row holds.
- DoType
Info - The storage class of a single value, which is all these backends report.
Traits§
- DoExecutor
- An executor for Durable Object storage:
&DoConnectionor&mut DoConnection.
Type Aliases§
- DoBatch
Result - What one statement of a
DoConnection::fetch_batchdid, and the rows it returned.