Skip to main content

sqlx_cloudflare_core/
result.rs

1/// What a statement did.
2#[derive(Debug, Default, Clone, PartialEq, Eq)]
3pub struct QueryResult {
4    rows_affected: u64,
5    last_insert_rowid: Option<i64>,
6}
7
8impl QueryResult {
9    /// A result reporting `rows_affected` and, when the backend knows one,
10    /// `last_insert_rowid`.
11    #[must_use]
12    pub fn new(rows_affected: u64, last_insert_rowid: Option<i64>) -> Self {
13        Self {
14            rows_affected,
15            last_insert_rowid,
16        }
17    }
18
19    /// Rows the statement inserted, updated or deleted.
20    #[must_use]
21    pub fn rows_affected(&self) -> u64 {
22        self.rows_affected
23    }
24
25    /// The rowid of the last row inserted, when the backend reports one.
26    #[must_use]
27    pub fn last_insert_rowid(&self) -> Option<i64> {
28        self.last_insert_rowid
29    }
30}
31
32impl Extend<QueryResult> for QueryResult {
33    fn extend<T: IntoIterator<Item = QueryResult>>(&mut self, iter: T) {
34        for result in iter {
35            self.rows_affected += result.rows_affected;
36            // The last statement that reported a rowid, not the last
37            // statement: a trailing SELECT reporting none should not erase
38            // the INSERT before it.
39            self.last_insert_rowid = result.last_insert_rowid.or(self.last_insert_rowid);
40        }
41    }
42}
43
44/// What one statement of a batch did, and the rows it returned.
45///
46/// Generic over the driver's row type, which only the driver can name;
47/// each driver exposes it as its own alias.
48#[derive(Debug, Clone)]
49pub struct BatchResult<R> {
50    rows: Vec<R>,
51    result: QueryResult,
52}
53
54impl<R> BatchResult<R> {
55    /// A statement's `rows` and what it did.
56    #[must_use]
57    pub fn new(rows: Vec<R>, result: QueryResult) -> Self {
58        Self { rows, result }
59    }
60
61    /// The rows the statement returned: a `SELECT`'s, or an `INSERT ...
62    /// RETURNING`'s. Empty for a statement that returns none.
63    #[must_use]
64    pub fn rows(&self) -> &[R] {
65        &self.rows
66    }
67
68    /// The rows, giving up the result.
69    #[must_use]
70    pub fn into_rows(self) -> Vec<R> {
71        self.rows
72    }
73
74    /// What the statement did.
75    #[must_use]
76    pub fn result(&self) -> &QueryResult {
77        &self.result
78    }
79
80    /// The rows and what the statement did.
81    #[must_use]
82    pub fn into_parts(self) -> (Vec<R>, QueryResult) {
83        (self.rows, self.result)
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use super::QueryResult;
90
91    #[test]
92    fn extend_sums_changes_and_keeps_the_last_reported_rowid() {
93        let mut result = QueryResult::default();
94
95        result.extend([
96            QueryResult::new(2, Some(7)),
97            QueryResult::new(1, Some(9)),
98            QueryResult::new(0, None),
99        ]);
100
101        assert_eq!(result.rows_affected(), 3);
102        assert_eq!(result.last_insert_rowid(), Some(9));
103    }
104}