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::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::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::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::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::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::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::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<T>(&mut self, index: c_int, value: T) -> Result<()>
310 where
311 T: Bindable,
312 {
313 value.bind(self, index)
314 }
315
316 /// Bind a value to a parameter by name.
317 ///
318 /// # Examples
319 ///
320 /// ```
321 /// # let c = sqlite_ll::Connection::open(":memory:")?;
322 /// # c.execute("CREATE TABLE users (name STRING)");
323 /// let mut statement = c.prepare("SELECT * FROM users WHERE name = :name")?;
324 /// statement.bind_by_name(c":name", "Bob")?;
325 /// # Ok::<_, sqlite_ll::Error>(())
326 /// ```
327 pub fn bind_by_name(&mut self, name: impl AsRef<CStr>, value: impl Bindable) -> Result<()> {
328 if let Some(index) = self.parameter_index(name) {
329 self.bind(index, value)?;
330 Ok(())
331 } else {
332 Err(Error::new(ffi::SQLITE_MISMATCH))
333 }
334 }
335
336 /// Return the number of columns.
337 #[inline]
338 pub fn column_count(&self) -> c_int {
339 unsafe { ffi::sqlite3_column_count(self.raw.as_ptr()) }
340 }
341
342 /// Return the name of a column.
343 ///
344 /// If an invalid index is specified, `None` is returned.
345 ///
346 /// ```
347 /// use sqlite_ll::Connection;
348 ///
349 /// let c = Connection::memory()?;
350 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER);")?;
351 /// let stmt = c.prepare("SELECT * FROM users;")?;
352 ///
353 /// assert_eq!(stmt.column_name(0), Some("name"));
354 /// assert_eq!(stmt.column_name(1), Some("age"));
355 /// assert_eq!(stmt.column_name(2), None);
356 /// # Ok::<_, sqlite_ll::Error>(())
357 /// ```
358 ///
359 /// # Examples
360 ///
361 /// ```
362 /// use sqlite_ll::Connection;
363 ///
364 /// let c = Connection::memory()?;
365 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER);")?;
366 /// let stmt = c.prepare("SELECT * FROM users;")?;
367 ///
368 /// let cols = stmt.columns().collect::<Vec<_>>();
369 /// assert_eq!(cols, vec![0, 1]);
370 /// assert!(cols.iter().flat_map(|i| stmt.column_name(*i)).eq(["name", "age"]));
371 ///
372 /// let cols = stmt.columns().rev().collect::<Vec<_>>();
373 /// assert_eq!(cols, vec![1, 0]);
374 /// assert!(cols.iter().flat_map(|i| stmt.column_name(*i)).eq(["age", "name"]));
375 /// # Ok::<_, sqlite_ll::Error>(())
376 /// ```
377 #[inline]
378 pub fn column_name(&self, index: c_int) -> Option<&str> {
379 unsafe {
380 let ptr = ffi::sqlite3_column_name(self.raw.as_ptr(), index);
381
382 if ptr.is_null() {
383 return None;
384 }
385
386 // NB: Look for the null terminator. sqlite guarantees that it's in
387 // here somewhere. Unfortunately we have to go byte-by-byte since we
388 // don't know the extend of the string being returned.
389 for len in 0.. {
390 if ptr.add(len).read() == 0 {
391 let bytes = slice::from_raw_parts(ptr.cast(), len);
392 let s = str::from_utf8_unchecked(bytes);
393 return Some(s);
394 }
395 }
396
397 None
398 }
399 }
400
401 /// Return an iterator of column indexes.
402 ///
403 /// Column names are visible even when a prepared statement has not been
404 /// advanced using [`Statement::step`].
405 ///
406 /// # Examples
407 ///
408 /// ```
409 /// use sqlite_ll::Connection;
410 ///
411 /// let c = Connection::memory()?;
412 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER);")?;
413 /// let stmt = c.prepare("SELECT * FROM users;")?;
414 ///
415 /// let cols = stmt.columns().collect::<Vec<_>>();
416 /// assert_eq!(cols, vec![0, 1]);
417 ///
418 /// let cols = stmt.columns().rev().collect::<Vec<_>>();
419 /// assert_eq!(cols, vec![1, 0]);
420 ///
421 /// let col = stmt.columns().nth(1);
422 /// assert_eq!(col, Some(1));
423 ///
424 /// let col = stmt.columns().rev().nth(1);
425 /// assert_eq!(col, Some(0));
426 /// # Ok::<_, sqlite_ll::Error>(())
427 /// ```
428 #[inline]
429 pub fn columns(&self) -> Columns {
430 Columns {
431 range: 0..self.column_count().max(0),
432 }
433 }
434
435 /// Return an iterator of column names.
436 ///
437 /// Column names are visible even when a prepared statement has not been
438 /// advanced using [`Statement::step`].
439 ///
440 /// # Examples
441 ///
442 /// ```
443 /// use sqlite_ll::Connection;
444 ///
445 /// let c = Connection::memory()?;
446 /// c.execute("CREATE TABLE users (name TEXT, age INTEGER, occupation TEXT);")?;
447 /// let stmt = c.prepare("SELECT * FROM users;")?;
448 ///
449 /// let column_names = stmt.column_names().collect::<Vec<_>>();
450 /// assert_eq!(column_names, vec!["name", "age", "occupation"]);
451 ///
452 /// let column_names = stmt.column_names().rev().collect::<Vec<_>>();
453 /// assert_eq!(column_names, vec!["occupation", "age", "name"]);
454 ///
455 /// let name = stmt.column_names().nth(1);
456 /// assert_eq!(name, Some("age"));
457 ///
458 /// let name = stmt.column_names().nth(2);
459 /// assert_eq!(name, Some("occupation"));
460 ///
461 /// let name = stmt.column_names().rev().nth(2);
462 /// assert_eq!(name, Some("name"));
463 /// # Ok::<_, sqlite_ll::Error>(())
464 /// ```
465 #[inline]
466 pub fn column_names(&self) -> ColumnNames<'_> {
467 ColumnNames {
468 stmt: self,
469 range: 0..self.column_count().max(0),
470 }
471 }
472
473 /// Return the type of a column.
474 ///
475 /// The first column has index 0. The type becomes available after taking a
476 /// step.
477 ///
478 /// # Examples
479 ///
480 /// ```
481 /// use sqlite_ll::{Connection, Type, State};
482 ///
483 /// let mut c = Connection::memory()?;
484 ///
485 /// c.execute(r##"
486 /// CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age REAL, photo BLOB);
487 /// "##)?;
488 ///
489 /// c.execute(r##"
490 /// INSERT INTO users (id, name, age, photo) VALUES (1, 'Bob', 30.5, X'01020304');
491 /// "##)?;
492 ///
493 /// let mut stmt = c.prepare("SELECT * FROM users")?;
494 ///
495 /// assert_eq!(stmt.column_type(0), Type::NULL);
496 /// assert_eq!(stmt.column_type(1), Type::NULL);
497 /// assert_eq!(stmt.column_type(2), Type::NULL);
498 /// assert_eq!(stmt.column_type(3), Type::NULL);
499 ///
500 /// assert_eq!(stmt.step()?, State::Row);
501 ///
502 /// assert_eq!(stmt.column_type(0), Type::INTEGER);
503 /// assert_eq!(stmt.column_type(1), Type::TEXT);
504 /// assert_eq!(stmt.column_type(2), Type::FLOAT);
505 /// assert_eq!(stmt.column_type(3), Type::BLOB);
506 /// // Since the fifth column does not exist it is always `Null`.
507 /// assert_eq!(stmt.column_type(4), Type::NULL);
508 /// # Ok::<_, sqlite_ll::Error>(())
509 /// ```
510 #[inline]
511 pub fn column_type(&self, index: c_int) -> Type {
512 unsafe { Type::from_raw(ffi::sqlite3_column_type(self.raw.as_ptr(), index)) }
513 }
514
515 /// Return the index for a named parameter if exists.
516 ///
517 /// Note that this takes a c-string as the parameter name since that is what
518 /// the underlying API expects. To accomodate this, you can make use of the
519 /// `c"string"` syntax.
520 ///
521 /// # Examples
522 ///
523 /// ```
524 /// # let c = sqlite_ll::Connection::open(":memory:")?;
525 /// c.execute("CREATE TABLE users (name STRING)");
526 /// let stmt = c.prepare("SELECT * FROM users WHERE name = :name")?;
527 /// assert_eq!(stmt.parameter_index(c":name"), Some(1));
528 /// assert_eq!(stmt.parameter_index(c":asdf"), None);
529 /// # Ok::<_, sqlite_ll::Error>(())
530 /// ```
531 #[inline]
532 pub fn parameter_index(&self, parameter: impl AsRef<CStr>) -> Option<c_int> {
533 let index = unsafe {
534 ffi::sqlite3_bind_parameter_index(self.raw.as_ptr(), parameter.as_ref().as_ptr())
535 };
536
537 match index {
538 0 => None,
539 _ => Some(index),
540 }
541 }
542
543 /// Read a value from a column into a [`Readable`].
544 ///
545 /// The first column has index 0. The same column can be read multiple
546 /// times.
547 /// # Examples
548 ///
549 /// ```
550 /// use sqlite_ll::{Connection, State};
551 ///
552 /// let c = Connection::memory()?;
553 ///
554 /// c.execute(
555 /// "
556 /// CREATE TABLE users (name TEXT, age INTEGER);
557 /// INSERT INTO users VALUES ('Alice', 72);
558 /// INSERT INTO users VALUES ('Bob', 40);
559 /// ",
560 /// )?;
561 ///
562 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
563 ///
564 /// let mut results = Vec::new();
565 ///
566 /// for age in [30, 50] {
567 /// stmt.reset()?;
568 /// stmt.bind(1, age)?;
569 ///
570 /// while let State::Row = stmt.step()? {
571 /// results.push((stmt.read::<String>(0)?, stmt.read::<i64>(1)?));
572 /// }
573 /// }
574 ///
575 /// let expected = [
576 /// (String::from("Alice"), 72),
577 /// (String::from("Bob"), 40),
578 /// (String::from("Alice"), 72),
579 /// ];
580 ///
581 /// assert_eq!(results, expected);
582 /// # Ok::<_, sqlite_ll::Error>(())
583 /// ```
584 #[inline]
585 pub fn read<T>(&self, index: c_int) -> Result<T>
586 where
587 T: Readable,
588 {
589 Readable::read(self, index)
590 }
591
592 /// Read a value from a column into the provided [`Writable`].
593 ///
594 /// The first column has index 0. The same column can be read multiple
595 /// times.
596 ///
597 /// This can be much more efficient than calling `read` since you can
598 /// provide your own buffers.
599 ///
600 /// # Examples
601 ///
602 /// ```
603 /// use sqlite_ll::{Connection, State};
604 ///
605 /// let c = Connection::memory()?;
606 ///
607 /// c.execute(
608 /// "
609 /// CREATE TABLE users (name TEXT, age INTEGER);
610 /// INSERT INTO users VALUES ('Alice', 72);
611 /// INSERT INTO users VALUES ('Bob', 40);
612 /// ",
613 /// )?;
614 ///
615 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
616 ///
617 /// let mut results = Vec::new();
618 /// let mut name_buffer = String::new();
619 ///
620 /// for age in [30, 50] {
621 /// stmt.reset()?;
622 /// stmt.bind(1, age)?;
623 ///
624 /// while let State::Row = stmt.step()? {
625 /// name_buffer.clear();
626 /// stmt.read_into(0, &mut name_buffer)?;
627 ///
628 /// if name_buffer == "Bob" {
629 /// results.push(stmt.read::<i64>(1)?);
630 /// }
631 /// }
632 /// }
633 ///
634 /// let expected = [40];
635 ///
636 /// assert_eq!(results, expected);
637 /// # Ok::<_, sqlite_ll::Error>(())
638 /// ```
639 #[inline]
640 pub fn read_into<T>(&self, index: c_int, out: &mut T) -> Result<()>
641 where
642 T: ?Sized + Writable,
643 {
644 out.write(self, index)?;
645 Ok(())
646 }
647}
648
649impl Drop for Statement {
650 #[inline]
651 fn drop(&mut self) {
652 unsafe { ffi::sqlite3_finalize(self.raw.as_ptr()) };
653 }
654}
655
656/// An iterator over the column names of a statement.
657///
658/// See [`Statement::column_names`].
659pub struct ColumnNames<'a> {
660 stmt: &'a Statement,
661 range: Range<c_int>,
662}
663
664impl<'a> Iterator for ColumnNames<'a> {
665 type Item = &'a str;
666
667 #[inline]
668 fn next(&mut self) -> Option<Self::Item> {
669 self.stmt.column_name(self.range.next()?)
670 }
671
672 #[inline]
673 fn nth(&mut self, n: usize) -> Option<Self::Item> {
674 self.stmt.column_name(self.range.nth(n)?)
675 }
676
677 #[inline]
678 fn size_hint(&self) -> (usize, Option<usize>) {
679 self.range.size_hint()
680 }
681}
682
683impl<'a> DoubleEndedIterator for ColumnNames<'a> {
684 #[inline]
685 fn next_back(&mut self) -> Option<Self::Item> {
686 self.stmt.column_name(self.range.next_back()?)
687 }
688
689 #[inline]
690 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
691 self.stmt.column_name(self.range.nth_back(n)?)
692 }
693}
694
695impl ExactSizeIterator for ColumnNames<'_> {
696 #[inline]
697 fn len(&self) -> usize {
698 self.range.len()
699 }
700}
701
702/// An iterator over the column names of a statement.
703///
704/// See [`Statement::columns`].
705pub struct Columns {
706 range: Range<c_int>,
707}
708
709impl Iterator for Columns {
710 type Item = c_int;
711
712 #[inline]
713 fn next(&mut self) -> Option<Self::Item> {
714 self.range.next()
715 }
716
717 #[inline]
718 fn nth(&mut self, n: usize) -> Option<Self::Item> {
719 self.range.nth(n)
720 }
721
722 #[inline]
723 fn size_hint(&self) -> (usize, Option<usize>) {
724 self.range.size_hint()
725 }
726}
727
728impl DoubleEndedIterator for Columns {
729 #[inline]
730 fn next_back(&mut self) -> Option<Self::Item> {
731 self.range.next_back()
732 }
733
734 #[inline]
735 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
736 self.range.nth_back(n)
737 }
738}
739
740/// A row produced by a statement.
741///
742/// See [`Statement::next`].
743pub struct Row<'a> {
744 stmt: &'a mut Statement,
745}
746
747impl<'a> Row<'a> {
748 /// Read a value from a column into a [`Readable`].
749 ///
750 /// The first column has index 0. The same column can be read multiple
751 /// times.
752 ///
753 /// # Examples
754 ///
755 /// ```
756 /// use sqlite_ll::Connection;
757 ///
758 /// let c = Connection::memory()?;
759 ///
760 /// c.execute(
761 /// "
762 /// CREATE TABLE users (name TEXT, age INTEGER);
763 /// INSERT INTO users VALUES ('Alice', 72);
764 /// INSERT INTO users VALUES ('Bob', 40);
765 /// ",
766 /// )?;
767 ///
768 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
769 ///
770 /// let mut results = Vec::new();
771 ///
772 /// for age in [30, 50] {
773 /// stmt.reset()?;
774 /// stmt.bind(1, age)?;
775 ///
776 /// while let Some(row) = stmt.next()? {
777 /// results.push((row.read::<String>(0)?, row.read::<i64>(1)?));
778 /// }
779 /// }
780 ///
781 /// let expected = [
782 /// (String::from("Alice"), 72),
783 /// (String::from("Bob"), 40),
784 /// (String::from("Alice"), 72),
785 /// ];
786 ///
787 /// assert_eq!(results, expected);
788 /// # Ok::<_, sqlite_ll::Error>(())
789 /// ```
790 #[inline]
791 pub fn read<T>(&self, index: c_int) -> Result<T>
792 where
793 T: Readable,
794 {
795 Readable::read(self.stmt, index)
796 }
797
798 /// Read a value from a column into the provided [`Writable`].
799 ///
800 /// The first column has index 0. The same column can be read multiple
801 /// times.
802 ///
803 /// This can be much more efficient than calling `read` since you can
804 /// provide your own buffers.
805 ///
806 /// # Examples
807 ///
808 /// ```
809 /// use sqlite_ll::{Connection, State};
810 ///
811 /// let c = Connection::memory()?;
812 ///
813 /// c.execute(
814 /// "
815 /// CREATE TABLE users (name TEXT, age INTEGER);
816 /// INSERT INTO users VALUES ('Alice', 72);
817 /// INSERT INTO users VALUES ('Bob', 40);
818 /// ",
819 /// )?;
820 ///
821 /// let mut stmt = c.prepare("SELECT * FROM users WHERE age > ?")?;
822 ///
823 /// let mut results = Vec::new();
824 /// let mut name_buffer = String::new();
825 ///
826 /// for age in [30, 50] {
827 /// stmt.reset()?;
828 /// stmt.bind(1, age)?;
829 ///
830 /// while let Some(row) = stmt.next()? {
831 /// name_buffer.clear();
832 /// row.read_into(0, &mut name_buffer)?;
833 ///
834 /// if name_buffer == "Bob" {
835 /// results.push(row.read::<i64>(1)?);
836 /// }
837 /// }
838 /// }
839 ///
840 /// let expected = [40];
841 ///
842 /// assert_eq!(results, expected);
843 /// # Ok::<_, sqlite_ll::Error>(())
844 /// ```
845 #[inline]
846 pub fn read_into<T>(&self, index: c_int, out: &mut T) -> Result<()>
847 where
848 T: ?Sized + Writable,
849 {
850 out.write(self.stmt, index)?;
851 Ok(())
852 }
853}