sqlite_ll/statement.rs
1use core::ffi::{CStr, c_int};
2use core::fmt;
3use core::ops::Range;
4use core::ptr;
5use core::slice;
6
7use sqlite3_sys as ffi;
8
9use crate::{Bindable, Error, Readable, Result, Type, Writable};
10
11/// A marker type representing a NULL value.
12///
13/// This can be used with both [`Bindable`] and [`Writable`].
14///
15/// See [`Statement::bind`] and [`Statement::read`].
16#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
17pub struct Null;
18
19/// The state after stepping a statement.
20///
21/// See [`Statement::step`].
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23#[non_exhaustive]
24pub enum State {
25 /// There is a row available for reading.
26 Row,
27 /// The statement has been entirely evaluated.
28 Done,
29}
30
31/// A prepared statement.
32///
33/// Prepared statements are compiled using [`Connection::prepare`] or
34/// [`Connection::prepare_with`].
35///
36/// They can be re-used, but between each re-use they must be reset using
37/// [`Statement::reset`]. Defensive coding would suggest its appropriate to
38/// always call this before using a statement unless it was just created.
39///
40/// For durable prepared statements it is recommended that
41/// [`Connection::prepare_with`] is used with [`Prepare::PERSISTENT`] set.
42///
43/// [`Connection::prepare`]: crate::Connection::prepare
44/// [`Connection::prepare_with`]: crate::Connection::prepare_with
45/// [`Prepare::PERSISTENT`]: crate::Prepare::PERSISTENT
46///
47/// # Examples
48///
49/// ```
50/// use sqlite_ll::{Connection, State, Prepare};
51///
52/// let c = Connection::open_memory()?;
53/// c.execute("CREATE TABLE test (id INTEGER);")?;
54///
55/// let mut insert_stmt = c.prepare_with("INSERT INTO test (id) VALUES (?);", Prepare::PERSISTENT)?;
56/// let mut query_stmt = c.prepare_with("SELECT id FROM test;", Prepare::PERSISTENT)?;
57///
58/// drop(c);
59///
60/// /* .. */
61///
62/// insert_stmt.reset()?;
63/// insert_stmt.bind(1, 42)?;
64/// assert_eq!(insert_stmt.step()?, State::Done);
65///
66/// query_stmt.reset()?;
67///
68/// while let Some(mut row) = query_stmt.next()? {
69/// let id: i64 = row.read(0)?;
70/// assert_eq!(id, 42);
71/// }
72/// # Ok::<_, sqlite_ll::Error>(())
73/// ```
74#[repr(transparent)]
75pub struct Statement {
76 raw: ptr::NonNull<ffi::sqlite3_stmt>,
77}
78
79impl fmt::Debug for Statement {
80 #[inline]
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 f.debug_struct("Statement").finish_non_exhaustive()
83 }
84}
85
86/// A prepared statement is `Send`.
87unsafe impl Send for Statement {}
88
89impl Statement {
90 /// Construct a statement from a raw pointer.
91 #[inline]
92 pub(crate) fn from_raw(raw: ptr::NonNull<ffi::sqlite3_stmt>) -> Statement {
93 Statement { raw }
94 }
95
96 /// Return the raw pointer.
97 #[inline]
98 pub(super) fn as_ptr(&self) -> *mut ffi::sqlite3_stmt {
99 self.raw.as_ptr()
100 }
101
102 /// Return the raw mutable pointer.
103 #[inline]
104 pub(super) fn as_ptr_mut(&mut self) -> *mut ffi::sqlite3_stmt {
105 self.raw.as_ptr()
106 }
107
108 /// Get the next row from the statement.
109 ///
110 /// Returns `None` when there are no more rows.
111 ///
112 /// This is a higher level API than `step` and is less prone to misuse. Note
113 /// however that misuse never leads to corrupted data or undefined behavior,
114 /// only surprising behavior such as NULL values being auto-converted (see
115 /// [`Statement::step`]).
116 ///
117 /// # Examples
118 ///
119 /// ```
120 /// use sqlite_ll::Connection;
121 ///
122 /// let c = Connection::open_memory()?;
123 ///
124 /// c.execute(
125 /// "
126 /// CREATE TABLE users (name TEXT, age INTEGER);
127 /// INSERT INTO users VALUES ('Alice', 72);
128 /// INSERT INTO users VALUES ('Bob', 40);
129 /// ",
130 /// )?;
131 ///
132 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
133 ///
134 /// let mut results = Vec::new();
135 ///
136 /// for age in [30, 50] {
137 /// stmt.reset()?;
138 /// stmt.bind(1, age)?;
139 ///
140 /// while let Some(row) = stmt.next()? {
141 /// results.push((row.read::<String>(0)?, row.read::<i64>(1)?));
142 /// }
143 /// }
144 ///
145 /// let expected = [
146 /// (String::from("Alice"), 72),
147 /// (String::from("Bob"), 40),
148 /// (String::from("Alice"), 72),
149 /// ];
150 ///
151 /// assert_eq!(results, expected);
152 /// # Ok::<_, sqlite_ll::Error>(())
153 /// ```
154 pub fn next(&mut self) -> Result<Option<Row<'_>>> {
155 match self.step()? {
156 State::Row => Ok(Some(Row { stmt: self })),
157 State::Done => Ok(None),
158 }
159 }
160
161 /// Step the statement.
162 ///
163 /// This is necessary in order to produce rows from a statement. It must be
164 /// called once before the first row is returned. Trying to read data from a
165 /// statement which has not been stepped will always result in a NULL value
166 /// being read which is subject to auto-conversion.
167 ///
168 /// ```
169 /// use sqlite_ll::{Connection, State, Code};
170 ///
171 /// let c = Connection::open_memory()?;
172 /// c.execute("CREATE TABLE users (id INTEGER, name TEXT);")?;
173 /// c.execute("INSERT INTO users (id, name) VALUES (0, 'Alice'), (1, 'Bob');")?;
174 ///
175 /// let mut stmt = c.prepare("SELECT name FROM users;")?;
176 /// assert_eq!(stmt.read::<i64>(0)?, 0);
177 /// assert_eq!(stmt.read::<String>(0)?, "");
178 /// # Ok::<_, sqlite_ll::Error>(())
179 /// ```
180 ///
181 /// When the statement returns [`State::Done`] no more rows are available.
182 ///
183 /// # Examples
184 ///
185 /// ```
186 /// use sqlite_ll::{Connection, State};
187 ///
188 /// let c = Connection::open_memory()?;
189 ///
190 /// c.execute(
191 /// "
192 /// CREATE TABLE users (name TEXT, age INTEGER);
193 /// INSERT INTO users VALUES ('Alice', 72);
194 /// INSERT INTO users VALUES ('Bob', 40);
195 /// ",
196 /// )?;
197 ///
198 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
199 ///
200 /// let mut results = Vec::new();
201 ///
202 /// for age in [30, 50] {
203 /// stmt.reset()?;
204 /// stmt.bind(1, age)?;
205 ///
206 /// while let State::Row = stmt.step()? {
207 /// results.push((stmt.read::<String>(0)?, stmt.read::<i64>(1)?));
208 /// }
209 /// }
210 ///
211 /// let expected = [
212 /// (String::from("Alice"), 72),
213 /// (String::from("Bob"), 40),
214 /// (String::from("Alice"), 72),
215 /// ];
216 ///
217 /// assert_eq!(results, expected);
218 /// # Ok::<_, sqlite_ll::Error>(())
219 /// ```
220 pub fn step(&mut self) -> Result<State> {
221 // SAFETY: We own the raw handle to this statement.
222 unsafe {
223 match ffi::sqlite3_step(self.raw.as_ptr()) {
224 ffi::SQLITE_ROW => Ok(State::Row),
225 ffi::SQLITE_DONE => Ok(State::Done),
226 code => Err(Error::new(code)),
227 }
228 }
229 }
230
231 /// Reset the statement allowing it to be re-used.
232 ///
233 /// Resetting a statement unsets all bindings set by [`Statement::bind`].
234 ///
235 /// # Examples
236 ///
237 /// ```
238 /// use sqlite_ll::{Connection, State};
239 ///
240 /// let c = Connection::open_memory()?;
241 ///
242 /// c.execute(
243 /// "
244 /// CREATE TABLE users (name TEXT, age INTEGER);
245 /// INSERT INTO users VALUES ('Alice', 72);
246 /// INSERT INTO users VALUES ('Bob', 40);
247 /// ",
248 /// )?;
249 ///
250 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
251 ///
252 /// let mut results = Vec::new();
253 ///
254 /// for age in [30, 50] {
255 /// stmt.reset()?;
256 /// stmt.bind(1, age)?;
257 ///
258 /// while let State::Row = stmt.step()? {
259 /// results.push((stmt.read::<String>(0)?, stmt.read::<i64>(1)?));
260 /// }
261 /// }
262 ///
263 /// let expected = [
264 /// (String::from("Alice"), 72),
265 /// (String::from("Bob"), 40),
266 /// (String::from("Alice"), 72),
267 /// ];
268 ///
269 /// assert_eq!(results, expected);
270 /// # Ok::<_, sqlite_ll::Error>(())
271 /// ```
272 #[inline]
273 pub fn reset(&mut self) -> Result<()> {
274 unsafe { ffi::sqlite3_reset(self.raw.as_ptr()) };
275 Ok(())
276 }
277
278 /// Bind a value to a parameter by index.
279 ///
280 /// # Errors
281 ///
282 /// The first parameter has index 1, attempting to bind to 0 will result in an error.
283 ///
284 /// ```
285 /// use sqlite_ll::{Connection, Null, Code};
286 ///
287 /// let c = Connection::open_memory()?;
288 /// c.execute("CREATE TABLE users (name STRING)");
289 /// let mut stmt = c.prepare("SELECT * FROM users WHERE name = ?")?;
290 /// let e = stmt.bind(0, "Bob").unwrap_err();
291 /// assert_eq!(e.code(), Code::RANGE);
292 /// # Ok::<_, sqlite_ll::Error>(())
293 /// ```
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// use sqlite_ll::{Connection, Null, Code, State};
299 ///
300 /// let c = Connection::open_memory()?;
301 /// c.execute("CREATE TABLE users (name STRING)");
302 /// let mut stmt = c.prepare("SELECT * FROM users WHERE name = ?")?;
303 /// stmt.bind(1, "Bob")?;
304 ///
305 /// assert_eq!(stmt.step()?, State::Done);
306 /// # Ok::<_, sqlite_ll::Error>(())
307 /// ```
308 #[inline]
309 pub fn bind(&mut self, index: c_int, value: impl Bindable) -> Result<()> {
310 value.bind(self, index)
311 }
312
313 /// Bind a value to a parameter by name.
314 ///
315 /// # Examples
316 ///
317 /// ```
318 /// # let c = sqlite_ll::Connection::open(":memory:")?;
319 /// # c.execute("CREATE TABLE users (name STRING)");
320 /// let mut statement = c.prepare("SELECT * FROM users WHERE name = :name")?;
321 /// statement.bind_by_name(c":name", "Bob")?;
322 /// # Ok::<_, sqlite_ll::Error>(())
323 /// ```
324 pub fn bind_by_name(&mut self, name: impl AsRef<CStr>, value: impl Bindable) -> Result<()> {
325 if let Some(index) = self.parameter_index(name) {
326 self.bind(index, value)?;
327 Ok(())
328 } else {
329 Err(Error::new(ffi::SQLITE_MISMATCH))
330 }
331 }
332
333 /// Return the number of columns.
334 #[inline]
335 pub fn column_count(&self) -> c_int {
336 unsafe { ffi::sqlite3_column_count(self.raw.as_ptr()) }
337 }
338
339 /// Return the name of a column.
340 ///
341 /// If an invalid index is specified, `None` is returned.
342 ///
343 /// ```
344 /// use sqlite_ll::Connection;
345 ///
346 /// let c = Connection::open_memory()?;
347 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER);")?;
348 /// let stmt = c.prepare("SELECT * FROM users;")?;
349 ///
350 /// assert_eq!(stmt.column_name(0), Some("name"));
351 /// assert_eq!(stmt.column_name(1), Some("age"));
352 /// assert_eq!(stmt.column_name(2), None);
353 /// # Ok::<_, sqlite_ll::Error>(())
354 /// ```
355 ///
356 /// # Examples
357 ///
358 /// ```
359 /// use sqlite_ll::Connection;
360 ///
361 /// let c = Connection::open_memory()?;
362 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER);")?;
363 /// let stmt = c.prepare("SELECT * FROM users;")?;
364 ///
365 /// let cols = stmt.columns().collect::<Vec<_>>();
366 /// assert_eq!(cols, vec![0, 1]);
367 /// assert!(cols.iter().flat_map(|i| stmt.column_name(*i)).eq(["name", "age"]));
368 ///
369 /// let cols = stmt.columns().rev().collect::<Vec<_>>();
370 /// assert_eq!(cols, vec![1, 0]);
371 /// assert!(cols.iter().flat_map(|i| stmt.column_name(*i)).eq(["age", "name"]));
372 /// # Ok::<_, sqlite_ll::Error>(())
373 /// ```
374 #[inline]
375 pub fn column_name(&self, index: c_int) -> Option<&str> {
376 unsafe {
377 let ptr = ffi::sqlite3_column_name(self.raw.as_ptr(), index);
378
379 if ptr.is_null() {
380 return None;
381 }
382
383 // NB: Look for the null terminator. sqlite guarantees that it's in
384 // here somewhere. Unfortunately we have to go byte-by-byte since we
385 // don't know the extend of the string being returned.
386 for len in 0.. {
387 if ptr.add(len).read() == 0 {
388 let bytes = slice::from_raw_parts(ptr.cast(), len);
389 let s = str::from_utf8_unchecked(bytes);
390 return Some(s);
391 }
392 }
393
394 None
395 }
396 }
397
398 /// Return an iterator of column indexes.
399 ///
400 /// Column names are visible even when a prepared statement has not been
401 /// advanced using [`Statement::step`].
402 ///
403 /// # Examples
404 ///
405 /// ```
406 /// use sqlite_ll::Connection;
407 ///
408 /// let c = Connection::open_memory()?;
409 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER);")?;
410 /// let stmt = c.prepare("SELECT * FROM users;")?;
411 ///
412 /// let cols = stmt.columns().collect::<Vec<_>>();
413 /// assert_eq!(cols, vec![0, 1]);
414 ///
415 /// let cols = stmt.columns().rev().collect::<Vec<_>>();
416 /// assert_eq!(cols, vec![1, 0]);
417 ///
418 /// let col = stmt.columns().nth(1);
419 /// assert_eq!(col, Some(1));
420 ///
421 /// let col = stmt.columns().rev().nth(1);
422 /// assert_eq!(col, Some(0));
423 /// # Ok::<_, sqlite_ll::Error>(())
424 /// ```
425 #[inline]
426 pub fn columns(&self) -> Columns {
427 Columns {
428 range: 0..self.column_count().max(0),
429 }
430 }
431
432 /// Return an iterator of column names.
433 ///
434 /// Column names are visible even when a prepared statement has not been
435 /// advanced using [`Statement::step`].
436 ///
437 /// # Examples
438 ///
439 /// ```
440 /// use sqlite_ll::Connection;
441 ///
442 /// let c = Connection::open_memory()?;
443 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER, occupation TEXT);")?;
444 /// let stmt = c.prepare("SELECT * FROM users;")?;
445 ///
446 /// let column_names = stmt.column_names().collect::<Vec<_>>();
447 /// assert_eq!(column_names, vec!["name", "age", "occupation"]);
448 ///
449 /// let column_names = stmt.column_names().rev().collect::<Vec<_>>();
450 /// assert_eq!(column_names, vec!["occupation", "age", "name"]);
451 ///
452 /// let name = stmt.column_names().nth(1);
453 /// assert_eq!(name, Some("age"));
454 ///
455 /// let name = stmt.column_names().nth(2);
456 /// assert_eq!(name, Some("occupation"));
457 ///
458 /// let name = stmt.column_names().rev().nth(2);
459 /// assert_eq!(name, Some("name"));
460 /// # Ok::<_, sqlite_ll::Error>(())
461 /// ```
462 #[inline]
463 pub fn column_names(&self) -> ColumnNames<'_> {
464 ColumnNames {
465 stmt: self,
466 range: 0..self.column_count().max(0),
467 }
468 }
469
470 /// Return the type of a column.
471 ///
472 /// The first column has index 0. The type becomes available after taking a
473 /// step.
474 ///
475 /// # Examples
476 ///
477 /// ```
478 /// use sqlite_ll::{Connection, Type, State};
479 ///
480 /// let mut c = Connection::open_memory()?;
481 ///
482 /// c.execute(r##"
483 /// CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age REAL, photo BLOB);
484 /// "##)?;
485 ///
486 /// c.execute(r##"
487 /// INSERT INTO users (id, name, age, photo) VALUES (1, 'Bob', 30.5, X'01020304');
488 /// "##)?;
489 ///
490 /// let mut stmt = c.prepare("SELECT * FROM users")?;
491 ///
492 /// assert_eq!(stmt.column_type(0), Type::NULL);
493 /// assert_eq!(stmt.column_type(1), Type::NULL);
494 /// assert_eq!(stmt.column_type(2), Type::NULL);
495 /// assert_eq!(stmt.column_type(3), Type::NULL);
496 ///
497 /// assert_eq!(stmt.step()?, State::Row);
498 ///
499 /// assert_eq!(stmt.column_type(0), Type::INTEGER);
500 /// assert_eq!(stmt.column_type(1), Type::TEXT);
501 /// assert_eq!(stmt.column_type(2), Type::FLOAT);
502 /// assert_eq!(stmt.column_type(3), Type::BLOB);
503 /// // Since the fifth column does not exist it is always `Null`.
504 /// assert_eq!(stmt.column_type(4), Type::NULL);
505 /// # Ok::<_, sqlite_ll::Error>(())
506 /// ```
507 #[inline]
508 pub fn column_type(&self, index: c_int) -> Type {
509 unsafe { Type::from_raw(ffi::sqlite3_column_type(self.raw.as_ptr(), index)) }
510 }
511
512 /// Return the index for a named parameter if exists.
513 ///
514 /// Note that this takes a c-string as the parameter name since that is what
515 /// the underlying API expects. To accomodate this, you can make use of the
516 /// `c"string"` syntax.
517 ///
518 /// # Examples
519 ///
520 /// ```
521 /// # let c = sqlite_ll::Connection::open(":memory:")?;
522 /// c.execute("CREATE TABLE users (name STRING)");
523 /// let stmt = c.prepare("SELECT * FROM users WHERE name = :name")?;
524 /// assert_eq!(stmt.parameter_index(c":name"), Some(1));
525 /// assert_eq!(stmt.parameter_index(c":asdf"), None);
526 /// # Ok::<_, sqlite_ll::Error>(())
527 /// ```
528 #[inline]
529 pub fn parameter_index(&self, parameter: impl AsRef<CStr>) -> Option<c_int> {
530 let index = unsafe {
531 ffi::sqlite3_bind_parameter_index(self.raw.as_ptr(), parameter.as_ref().as_ptr())
532 };
533
534 match index {
535 0 => None,
536 _ => Some(index),
537 }
538 }
539
540 /// Read a value from a column into a [`Readable`].
541 ///
542 /// The first column has index 0. The same column can be read multiple
543 /// times.
544 /// # Examples
545 ///
546 /// ```
547 /// use sqlite_ll::{Connection, State};
548 ///
549 /// let c = Connection::open_memory()?;
550 ///
551 /// c.execute(
552 /// "
553 /// CREATE TABLE users (name TEXT, age INTEGER);
554 /// INSERT INTO users VALUES ('Alice', 72);
555 /// INSERT INTO users VALUES ('Bob', 40);
556 /// ",
557 /// )?;
558 ///
559 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
560 ///
561 /// let mut results = Vec::new();
562 ///
563 /// for age in [30, 50] {
564 /// stmt.reset()?;
565 /// stmt.bind(1, age)?;
566 ///
567 /// while let State::Row = stmt.step()? {
568 /// results.push((stmt.read::<String>(0)?, stmt.read::<i64>(1)?));
569 /// }
570 /// }
571 ///
572 /// let expected = [
573 /// (String::from("Alice"), 72),
574 /// (String::from("Bob"), 40),
575 /// (String::from("Alice"), 72),
576 /// ];
577 ///
578 /// assert_eq!(results, expected);
579 /// # Ok::<_, sqlite_ll::Error>(())
580 /// ```
581 #[inline]
582 pub fn read<T>(&self, index: c_int) -> Result<T>
583 where
584 T: Readable,
585 {
586 Readable::read(self, index)
587 }
588
589 /// Read a value from a column into the provided [`Writable`].
590 ///
591 /// The first column has index 0. The same column can be read multiple
592 /// times.
593 ///
594 /// This can be much more efficient than calling `read` since you can
595 /// provide your own buffers.
596 ///
597 /// # Examples
598 ///
599 /// ```
600 /// use sqlite_ll::{Connection, State};
601 ///
602 /// let c = Connection::open_memory()?;
603 ///
604 /// c.execute(
605 /// "
606 /// CREATE TABLE users (name TEXT, age INTEGER);
607 /// INSERT INTO users VALUES ('Alice', 72);
608 /// INSERT INTO users VALUES ('Bob', 40);
609 /// ",
610 /// )?;
611 ///
612 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
613 ///
614 /// let mut results = Vec::new();
615 /// let mut name_buffer = String::new();
616 ///
617 /// for age in [30, 50] {
618 /// stmt.reset()?;
619 /// stmt.bind(1, age)?;
620 ///
621 /// while let State::Row = stmt.step()? {
622 /// name_buffer.clear();
623 /// stmt.read_into(0, &mut name_buffer)?;
624 ///
625 /// if name_buffer == "Bob" {
626 /// results.push(stmt.read::<i64>(1)?);
627 /// }
628 /// }
629 /// }
630 ///
631 /// let expected = [40];
632 ///
633 /// assert_eq!(results, expected);
634 /// # Ok::<_, sqlite_ll::Error>(())
635 /// ```
636 #[inline]
637 pub fn read_into(&self, index: c_int, out: &mut (impl ?Sized + Writable)) -> Result<()> {
638 out.write(self, index)?;
639 Ok(())
640 }
641}
642
643impl Drop for Statement {
644 #[inline]
645 fn drop(&mut self) {
646 unsafe { ffi::sqlite3_finalize(self.raw.as_ptr()) };
647 }
648}
649
650/// An iterator over the column names of a statement.
651///
652/// See [`Statement::column_names`].
653pub struct ColumnNames<'a> {
654 stmt: &'a Statement,
655 range: Range<c_int>,
656}
657
658impl<'a> Iterator for ColumnNames<'a> {
659 type Item = &'a str;
660
661 #[inline]
662 fn next(&mut self) -> Option<Self::Item> {
663 self.stmt.column_name(self.range.next()?)
664 }
665
666 #[inline]
667 fn nth(&mut self, n: usize) -> Option<Self::Item> {
668 self.stmt.column_name(self.range.nth(n)?)
669 }
670
671 #[inline]
672 fn size_hint(&self) -> (usize, Option<usize>) {
673 self.range.size_hint()
674 }
675}
676
677impl<'a> DoubleEndedIterator for ColumnNames<'a> {
678 #[inline]
679 fn next_back(&mut self) -> Option<Self::Item> {
680 self.stmt.column_name(self.range.next_back()?)
681 }
682
683 #[inline]
684 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
685 self.stmt.column_name(self.range.nth_back(n)?)
686 }
687}
688
689impl ExactSizeIterator for ColumnNames<'_> {
690 #[inline]
691 fn len(&self) -> usize {
692 self.range.len()
693 }
694}
695
696/// An iterator over the column names of a statement.
697///
698/// See [`Statement::columns`].
699pub struct Columns {
700 range: Range<c_int>,
701}
702
703impl Iterator for Columns {
704 type Item = c_int;
705
706 #[inline]
707 fn next(&mut self) -> Option<Self::Item> {
708 self.range.next()
709 }
710
711 #[inline]
712 fn nth(&mut self, n: usize) -> Option<Self::Item> {
713 self.range.nth(n)
714 }
715
716 #[inline]
717 fn size_hint(&self) -> (usize, Option<usize>) {
718 self.range.size_hint()
719 }
720}
721
722impl DoubleEndedIterator for Columns {
723 #[inline]
724 fn next_back(&mut self) -> Option<Self::Item> {
725 self.range.next_back()
726 }
727
728 #[inline]
729 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
730 self.range.nth_back(n)
731 }
732}
733
734/// A row produced by a statement.
735///
736/// See [`Statement::next`].
737pub struct Row<'a> {
738 stmt: &'a mut Statement,
739}
740
741impl<'a> Row<'a> {
742 /// Read a value from a column into a [`Readable`].
743 ///
744 /// The first column has index 0. The same column can be read multiple
745 /// times.
746 ///
747 /// # Examples
748 ///
749 /// ```
750 /// use sqlite_ll::Connection;
751 ///
752 /// let c = Connection::open_memory()?;
753 ///
754 /// c.execute(
755 /// "
756 /// CREATE TABLE users (name TEXT, age INTEGER);
757 /// INSERT INTO users VALUES ('Alice', 72);
758 /// INSERT INTO users VALUES ('Bob', 40);
759 /// ",
760 /// )?;
761 ///
762 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
763 ///
764 /// let mut results = Vec::new();
765 ///
766 /// for age in [30, 50] {
767 /// stmt.reset()?;
768 /// stmt.bind(1, age)?;
769 ///
770 /// while let Some(row) = stmt.next()? {
771 /// results.push((row.read::<String>(0)?, row.read::<i64>(1)?));
772 /// }
773 /// }
774 ///
775 /// let expected = [
776 /// (String::from("Alice"), 72),
777 /// (String::from("Bob"), 40),
778 /// (String::from("Alice"), 72),
779 /// ];
780 ///
781 /// assert_eq!(results, expected);
782 /// # Ok::<_, sqlite_ll::Error>(())
783 /// ```
784 #[inline]
785 pub fn read<T>(&self, index: c_int) -> Result<T>
786 where
787 T: Readable,
788 {
789 Readable::read(self.stmt, index)
790 }
791
792 /// Read a value from a column into the provided [`Writable`].
793 ///
794 /// The first column has index 0. The same column can be read multiple
795 /// times.
796 ///
797 /// This can be much more efficient than calling `read` since you can
798 /// provide your own buffers.
799 ///
800 /// # Examples
801 ///
802 /// ```
803 /// use sqlite_ll::{Connection, State};
804 ///
805 /// let c = Connection::open_memory()?;
806 ///
807 /// c.execute(
808 /// "
809 /// CREATE TABLE users (name TEXT, age INTEGER);
810 /// INSERT INTO users VALUES ('Alice', 72);
811 /// INSERT INTO users VALUES ('Bob', 40);
812 /// ",
813 /// )?;
814 ///
815 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
816 ///
817 /// let mut results = Vec::new();
818 /// let mut name_buffer = String::new();
819 ///
820 /// for age in [30, 50] {
821 /// stmt.reset()?;
822 /// stmt.bind(1, age)?;
823 ///
824 /// while let Some(row) = stmt.next()? {
825 /// name_buffer.clear();
826 /// row.read_into(0, &mut name_buffer)?;
827 ///
828 /// if name_buffer == "Bob" {
829 /// results.push(row.read::<i64>(1)?);
830 /// }
831 /// }
832 /// }
833 ///
834 /// let expected = [40];
835 ///
836 /// assert_eq!(results, expected);
837 /// # Ok::<_, sqlite_ll::Error>(())
838 /// ```
839 #[inline]
840 pub fn read_into(&self, index: c_int, out: &mut (impl ?Sized + Writable)) -> Result<()> {
841 out.write(self.stmt, index)?;
842 Ok(())
843 }
844}