sqlx_sqlite/connection/
execute.rs
1use crate::connection::{ConnectionHandle, ConnectionState};
2use crate::error::Error;
3use crate::logger::QueryLogger;
4use crate::statement::{StatementHandle, VirtualStatement};
5use crate::{SqliteArguments, SqliteQueryResult, SqliteRow};
6use sqlx_core::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 ExecuteIter<'_> {
57 pub fn finish(&mut self) -> Result<(), Error> {
58 for res in self {
59 let _ = res?;
60 }
61
62 Ok(())
63 }
64}
65
66impl Iterator for ExecuteIter<'_> {
67 type Item = Result<Either<SqliteQueryResult, SqliteRow>, Error>;
68
69 fn next(&mut self) -> Option<Self::Item> {
70 let statement = if self.goto_next {
71 let statement = match self.statement.prepare_next(self.handle) {
72 Ok(Some(statement)) => statement,
73 Ok(None) => return None,
74 Err(e) => return Some(Err(e)),
75 };
76
77 self.goto_next = false;
78
79 if let Err(e) = statement.handle.reset() {
81 return Some(Err(e.into()));
82 }
83
84 statement.handle.clear_bindings();
85
86 match bind(statement.handle, &self.args, self.args_used) {
87 Ok(args_used) => self.args_used += args_used,
88 Err(e) => return Some(Err(e)),
89 }
90
91 statement
92 } else {
93 self.statement.current()?
94 };
95
96 match statement.handle.step() {
97 Ok(true) => {
98 self.logger.increment_rows_returned();
99
100 Some(Ok(Either::Right(SqliteRow::current(
101 statement.handle,
102 statement.columns,
103 statement.column_names,
104 ))))
105 }
106 Ok(false) => {
107 let last_insert_rowid = self.handle.last_insert_rowid();
108
109 let changes = statement.handle.changes();
110 self.logger.increase_rows_affected(changes);
111
112 let done = SqliteQueryResult {
113 changes,
114 last_insert_rowid,
115 };
116
117 self.goto_next = true;
118
119 Some(Ok(Either::Left(done)))
120 }
121 Err(e) => Some(Err(e.into())),
122 }
123 }
124}
125
126impl Drop for ExecuteIter<'_> {
127 fn drop(&mut self) {
128 self.statement.reset().ok();
129 }
130}