1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use async_trait;
use ;
use crateSqlDialect;
/// Identifies one statement queued into a [`DbBatch`].
///
/// Returned by [`DbBatch::add_statement`] and used to locate that statement's
/// [`DbStatementResult`] in the `Vec` returned by [`DbBatch::commit`]: the id
/// is the result's index, so `results[id.0]` is always this statement's
/// outcome. Holding the id means callers never have to track insertion order
/// by hand to find their own `RETURNING` rows (e.g. for emitting change
/// events after the batch commits).
;
/// The outcome of a single statement once its batch has committed.
///
/// One of these is produced per [`DbBatch::add_statement`] call, in add order.
/// `rows` carries the statement's `RETURNING` output (empty when it had no
/// `RETURNING` clause); `rows_affected` is the INSERT/UPDATE/DELETE row count,
/// which some callers need to decide whether an LWW write actually changed
/// anything.
/// An atomic, all-or-nothing unit of writes.
///
/// Statements are *collected* with [`add_statement`](DbBatch::add_statement)
/// and then run together by [`commit`](DbBatch::commit) inside a single
/// transaction. Either every statement commits or none does; on any error the
/// whole batch rolls back.
///
/// There is deliberately **no read method** on a batch. A queued statement may
/// not depend on the result of an earlier one in the same batch — all reads
/// must happen on [`Db`](super::Db) *before* the batch is assembled. This keeps
/// a batch expressible as a flat, declarative statement list.
///
/// That declarative shape is the portable lowest common denominator across
/// SQLite backends. Any backend where compute is *network-distant* from the
/// database can't safely expose an interactive `BEGIN`/`COMMIT`: a client could
/// open a write transaction and then crash or stall, stranding SQLite's single
/// write slot. So the whole category of HTTP-fronted edge SQLite exposes only a
/// batch/pipeline primitive that opens and closes the transaction database-side
/// in one round trip — Cloudflare D1's `batch()`, Turso/libSQL's remote client
/// (its stateless HTTP requests share no transaction context), and Bunny (also
/// libSQL-over-HTTP). The same flat list also maps cleanly onto backends that
/// *do* offer a real interactive transaction because compute is colocated with
/// the data — rusqlite `BEGIN/COMMIT`, Durable Object `transactionSync`. One
/// batch abstraction therefore runs identically everywhere.