sqlx_core_guts/sqlite/connection/
execute.rs1use crate::error::Error;
2use crate::logger::QueryLogger;
3use crate::sqlite::connection::{ConnectionHandle, ConnectionState};
4use crate::sqlite::statement::{StatementHandle, VirtualStatement};
5use crate::sqlite::{SqliteArguments, SqliteQueryResult, SqliteRow};
6use either::Either;
7
8pub struct ExecuteIter<'a> {
9 handle: &'a mut ConnectionHandle,
10 statement: &'a mut VirtualStatement,
11 logger: QueryLogger<'a>,
12 args: Option<SqliteArguments<'a>>,
13
14 args_used: usize,
17
18 goto_next: bool,
19}
20
21pub(crate) fn iter<'a>(
22 conn: &'a mut ConnectionState,
23 query: &'a str,
24 args: Option<SqliteArguments<'a>>,
25 persistent: bool,
26) -> Result<ExecuteIter<'a>, Error> {
27 let statement = conn.statements.get(query, persistent)?;
29
30 let logger = QueryLogger::new(query, conn.log_settings.clone());
31
32 Ok(ExecuteIter {
33 handle: &mut conn.handle,
34 statement,
35 logger,
36 args,
37 args_used: 0,
38 goto_next: true,
39 })
40}
41
42fn bind(
43 statement: &mut StatementHandle,
44 arguments: &Option<SqliteArguments<'_>>,
45 offset: usize,
46) -> Result<usize, Error> {
47 let mut n = 0;
48
49 if let Some(arguments) = arguments {
50 n = arguments.bind(statement, offset)?;
51 }
52
53 Ok(n)
54}
55
56impl Iterator for ExecuteIter<'_> {
57 type Item = Result<Either<SqliteQueryResult, SqliteRow>, Error>;
58
59 fn next(&mut self) -> Option<Self::Item> {
60 let statement = if self.goto_next {
61 let mut statement = match self.statement.prepare_next(self.handle) {
62 Ok(Some(statement)) => statement,
63 Ok(None) => return None,
64 Err(e) => return Some(Err(e.into())),
65 };
66
67 self.goto_next = false;
68
69 if let Err(e) = statement.handle.reset() {
71 return Some(Err(e.into()));
72 }
73
74 statement.handle.clear_bindings();
75
76 match bind(&mut statement.handle, &self.args, self.args_used) {
77 Ok(args_used) => self.args_used += args_used,
78 Err(e) => return Some(Err(e)),
79 }
80
81 statement
82 } else {
83 self.statement.current()?
84 };
85
86 match statement.handle.step() {
87 Ok(true) => {
88 self.logger.increment_rows_returned();
89
90 Some(Ok(Either::Right(SqliteRow::current(
91 &statement.handle,
92 &statement.columns,
93 &statement.column_names,
94 ))))
95 }
96 Ok(false) => {
97 let last_insert_rowid = self.handle.last_insert_rowid();
98
99 let changes = statement.handle.changes();
100 self.logger.increase_rows_affected(changes);
101
102 let done = SqliteQueryResult {
103 changes,
104 last_insert_rowid,
105 };
106
107 self.goto_next = true;
108
109 Some(Ok(Either::Left(done)))
110 }
111 Err(e) => Some(Err(e.into())),
112 }
113 }
114}
115
116impl Drop for ExecuteIter<'_> {
117 fn drop(&mut self) {
118 self.statement.reset().ok();
119 }
120}