From a1e85c6354e9698a9fbd39b8414c6a9e249ab85d Mon Sep 17 00:00:00 2001 From: Kristijan Sedlak Date: Fri, 30 Sep 2022 20:12:58 +0200 Subject: [PATCH 1/2] Respect missing values in session's conflict resolver --- src/session.rs | 56 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/src/session.rs b/src/session.rs index ef54f98..8b55bff 100644 --- a/src/session.rs +++ b/src/session.rs @@ -11,7 +11,7 @@ use std::slice::{from_raw_parts, from_raw_parts_mut}; use fallible_streaming_iterator::FallibleStreamingIterator; -use crate::error::{check, error_from_sqlite_code}; +use crate::error::{check, error_from_sqlite_code, Error}; use crate::ffi; use crate::hooks::Action; use crate::types::ValueRef; @@ -429,7 +429,11 @@ impl ChangesetItem { col as i32, &mut p_value, ))?; - Ok(ValueRef::from_value(p_value)) + if p_value.is_null() { + Err(Error::InvalidColumnIndex(col)) + } else { + Ok(ValueRef::from_value(p_value)) + } } } @@ -455,7 +459,11 @@ impl ChangesetItem { unsafe { let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); check(ffi::sqlite3changeset_new(self.it, col as i32, &mut p_value))?; - Ok(ValueRef::from_value(p_value)) + if p_value.is_null() { + Err(Error::InvalidColumnIndex(col)) + } else { + Ok(ValueRef::from_value(p_value)) + } } } @@ -468,7 +476,11 @@ impl ChangesetItem { unsafe { let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); check(ffi::sqlite3changeset_old(self.it, col as i32, &mut p_value))?; - Ok(ValueRef::from_value(p_value)) + if p_value.is_null() { + Err(Error::InvalidColumnIndex(col)) + } else { + Ok(ValueRef::from_value(p_value)) + } } } @@ -778,7 +790,7 @@ mod test { use crate::hooks::Action; use crate::{Connection, Result}; - fn one_changeset() -> Result { + fn one_changeset_insert() -> Result { let db = Connection::open_in_memory()?; db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?; @@ -791,6 +803,23 @@ mod test { session.changeset() } + fn one_changeset_update() -> Result { + let db = Connection::open_in_memory()?; + db.execute_batch(" + CREATE TABLE foo( + t TEXT PRIMARY KEY NOT NULL, + i INTEGER NOT NULL DEFAULT 0 + ); + INSERT INTO foo (t) VALUES ('bar'); + ")?; + + let mut session = Session::new(&db)?; + session.attach(None)?; + db.execute("UPDATE foo SET i=100 WHERE t='bar';", [])?; + + session.changeset() + } + fn one_changeset_strm() -> Result> { let db = Connection::open_in_memory()?; db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?; @@ -808,7 +837,7 @@ mod test { #[test] fn test_changeset() -> Result<()> { - let changeset = one_changeset()?; + let changeset = one_changeset_insert()?; let mut iter = changeset.iter()?; let item = iter.next()?; assert!(item.is_some()); @@ -841,9 +870,22 @@ mod test { Ok(()) } + #[test] + fn test_changeset_values() -> Result<()> { + let changeset = one_changeset_update()?; + let mut iter = changeset.iter()?; + let item = iter.next()?.unwrap(); + + let new_value = item.new_value(0); // unchanged + assert_eq!(Err(crate::Error::InvalidColumnIndex(0)), new_value); + let new_value = item.new_value(1)?; // updated + assert_eq!(Ok(100), new_value.as_i64()); + Ok(()) + } + #[test] fn test_changeset_apply() -> Result<()> { - let changeset = one_changeset()?; + let changeset = one_changeset_insert()?; let db = Connection::open_in_memory()?; db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?; From 47867c0a973790135ecd94f72b658c8f1cac1079 Mon Sep 17 00:00:00 2001 From: Kristijan Sedlak Date: Fri, 30 Sep 2022 20:53:34 +0200 Subject: [PATCH 2/2] Fix fmt requirements --- src/session.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/session.rs b/src/session.rs index 8b55bff..0a94829 100644 --- a/src/session.rs +++ b/src/session.rs @@ -805,13 +805,10 @@ mod test { fn one_changeset_update() -> Result { let db = Connection::open_in_memory()?; - db.execute_batch(" - CREATE TABLE foo( - t TEXT PRIMARY KEY NOT NULL, - i INTEGER NOT NULL DEFAULT 0 - ); - INSERT INTO foo (t) VALUES ('bar'); - ")?; + db.execute_batch( + "CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL, i INTEGER NOT NULL DEFAULT 0);", + )?; + db.execute_batch("INSERT INTO foo (t) VALUES ('bar');")?; let mut session = Session::new(&db)?; session.attach(None)?;