From a73b36f8540dab3aeb31fcb5b734257c734e06de Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sun, 10 Mar 2024 19:51:31 +0100 Subject: [PATCH] Stop iteration upon exception --- Cargo.toml | 2 +- src/cursor.rs | 27 +++++++++++++++++++-------- tests/cursor.rs | 6 ++++-- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 28e1786b..81e3a9da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlite" -version = "0.33.0" +version = "0.34.0" edition = "2021" license = "Apache-2.0/MIT" authors = [ diff --git a/src/cursor.rs b/src/cursor.rs index 0af7bcee..3a083a72 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -11,12 +11,14 @@ use crate::value::Value; pub struct Cursor<'l, 'm> { column_count: usize, statement: &'m mut Statement<'l>, + poisoned: bool, } /// An iterator for a prepared statement with ownership. pub struct CursorWithOwnership<'l> { column_count: usize, statement: Statement<'l>, + poisoned: bool, } /// A row. @@ -66,6 +68,7 @@ macro_rules! implement( #[allow(unused_mut)] pub fn reset(mut self) -> Result { self.statement.reset()?; + self.poisoned = false; Ok(self) } @@ -95,15 +98,21 @@ macro_rules! implement( type Item = Result; fn next(&mut self) -> Option { - let column_mapping = self.statement.column_mapping(); - self.try_next() - .map(|values| { - values.map(|values| Row { - column_mapping, + if self.poisoned { + return None; + } + match self.try_next() { + Ok(value) => { + value.map(|values| Ok(Row { + column_mapping: self.statement.column_mapping(), values, - }) - }) - .transpose() + })) + } + Err(error) => { + self.poisoned = true; + Some(Err(error)) + } + } } } } @@ -203,6 +212,7 @@ pub fn new<'l, 'm>(statement: &'m mut Statement<'l>) -> Cursor<'l, 'm> { Cursor { column_count: statement.column_count(), statement, + poisoned: false, } } @@ -210,5 +220,6 @@ pub fn new_with_ownership(statement: Statement<'_>) -> CursorWithOwnership<'_> { CursorWithOwnership { column_count: statement.column_count(), statement, + poisoned: false, } } diff --git a/tests/cursor.rs b/tests/cursor.rs index 1bd61394..df72536d 100644 --- a/tests/cursor.rs +++ b/tests/cursor.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use sqlite::{Result, Type, Value}; +use sqlite::{Type, Value}; mod common; @@ -97,7 +97,9 @@ fn iter_count_with_exception() { ok!(connection .execute("CREATE TRIGGER bar BEFORE INSERT ON foo BEGIN SELECT RAISE(FAIL, 'buz'); END")); let mut statement = ok!(connection.prepare("INSERT INTO foo VALUES (0) RETURNING rowid;")); - assert!(statement.iter().collect::>>().is_err()); + let results = statement.iter().collect::>(); + assert_eq!(results.len(), 1); + assert!(matches!(results[0], Err(_))); } #[test]